Phase 1 foundation for the Stargue Publishing Engine (plan v2, BMAD
panel-reviewed 2026-04-19 — 1 APPROVE, 6 REVISE, 0 REJECT; all principles >=3).
- Governance doctrine adopted from DQMS
(.clinerules/12-foundational-principles.md,
.claude/hooks/gate-plan-exit.sh, .claude/skills/bmad-plan/SKILL.md)
- Bun workspaces + Turbo; apps/{mcp-linkedin,scheduler,admin};
packages/{schema,sanitize,linkedin-client,observability}
- Drizzle schema (content, publications, approvals, metrics,
linkedin_tokens, audit, outlet_feature_flags) with idempotency_key
UNIQUE and kill-switch table per TEA/dev panel revisions
- LinkedIn API canon: Posts API /rest/posts (not legacy UGC); OAuth
auth-code without PKCE; secretbox (not sealed-box); Community
Management API as separate approval gate from MDP
- Frontmatter Zod schema (status, language, outlets[], sanitize,
scheduled, version)
- Pino observability with PII redaction
- Expand-then-contract migration runbook
- Plan + panel verdicts mirrored to docs/plans/
- Deferred gates logged (Dokploy PaaS verification, LinkedIn Dev
Portal app registration)
bun install + bun run typecheck both exit 0 across 11 workspaces.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
156 lines
11 KiB
Markdown
156 lines
11 KiB
Markdown
# 12 — Foundational Principles (Non-Negotiable)
|
||
|
||
**Status:** Active doctrine. Enforced by [`.claude/hooks/gate-plan-exit.sh`](../.claude/hooks/gate-plan-exit.sh) and the [`/bmad-plan` skill](../.claude/skills/bmad-plan/SKILL.md).
|
||
|
||
Every implementation plan and the execution of that plan MUST satisfy these principles. They apply to BMAD workflows, ad-hoc fixes, refactors, and tooling work alike.
|
||
|
||
---
|
||
|
||
## Two-Tier Model
|
||
|
||
Principles are split into two tiers to keep the rubric discriminating instead of ritualistic.
|
||
|
||
| Tier | When scored | Hook behaviour |
|
||
| ---- | ----------- | -------------- |
|
||
| **Tier-1 (Always)** | Every verdict, every plan | Hook **denies** `ExitPlanMode` if any verdict scores any tier-1 principle <3 or omits its rationale. |
|
||
| **Tier-2 (Conditional)** | Only when declared `applicable_tier2` for the plan | Hook **denies** `ExitPlanMode` if a declared tier-2 principle is unscored, scored <3, or has no rationale. |
|
||
|
||
The Analyst (Mary) declares `applicable_tier2` at the end of Phase 1 (plan draft). The list lives at the top of the verdicts file:
|
||
|
||
```json
|
||
{
|
||
"plan_file": "<path>",
|
||
"applicable_tier2": ["RBR", "A11y"],
|
||
"verdicts": [ … ]
|
||
}
|
||
```
|
||
|
||
Allowed tier-2 values: `RBR`, `A11y`, `Testability`. Any other value causes the hook to deny.
|
||
|
||
---
|
||
|
||
## Tier-1 Principles (always scored)
|
||
|
||
### SEBP — Software Engineering Best Practices
|
||
|
||
**Definition:** SOLID (single-responsibility, open-closed, Liskov, interface-segregation, dependency-inversion), DRY, separation of concerns, clear module boundaries.
|
||
|
||
**Score 1 (violation):** duplicated logic across files; god-objects; leaky abstractions; mixed concerns (e.g., a route handler that also formats PDFs and writes audit logs inline).
|
||
**Score 3 (adequate):** clean enough; no immediate smell; reviewer would not block.
|
||
**Score 5 (exemplary):** composition over inheritance; each unit has one reason to change; boundaries documented in code shape, not just comments.
|
||
|
||
**Acceptance signals:** named exports with single responsibility; no copy-pasted blocks ≥6 lines; route handlers delegate to `src/lib/*` modules.
|
||
|
||
### SSoT — Single Source of Truth
|
||
|
||
**Definition:** every concept (constant, type, schema, config, secret, user-facing string, status enum) has exactly one authoritative location.
|
||
|
||
**Score 1:** the same constant or enum is duplicated in two or more files; type drift between API and DB; magic numbers in components.
|
||
**Score 3:** core domain types/constants centralised; minor leakage acceptable when behind a TODO or feature-flag.
|
||
**Score 5:** generated artifacts (Prisma client, OpenAPI types) flow from a single schema; constants live in `src/lib/constants/*`; i18n strings in one bundle.
|
||
|
||
**Acceptance signals:** no `const RETRY_LIMIT = 3` defined in two files; Zod schemas re-used (not re-declared) on both client and server; status enums imported from one module.
|
||
|
||
### FPT — First Principle Thinking
|
||
|
||
**Definition:** reasoning grounded in this codebase, this stack version, and verified docs — not training-data assumptions or generic patterns.
|
||
|
||
**Score 1:** "Next.js v15 probably does X" without checking; copy-pastes a pattern that doesn't fit the project's existing shape; ignores Memory-Bank lessons.
|
||
**Score 3:** cites at least one file or doc; checks a non-obvious assumption.
|
||
**Score 5:** identifies the actual constraint, not the symptom; runs probes (small scripts, type-checks) to verify before committing to a design; references prior incidents in `memory-bank/systemPatterns.md`.
|
||
|
||
**Acceptance signals:** plan references concrete file paths; cites Tailwind v4 / Prisma 6 / NextAuth v5 docs (not v3 patterns); names the prior pattern being followed or deliberately diverged from.
|
||
|
||
### DiDSP — Defense in Depth Security Practices
|
||
|
||
**Definition:** multiple independent layers of defence: input validation, authentication, authorization, rate limiting, audit logging, least privilege, output encoding.
|
||
|
||
**Score 1:** unvalidated user input reaches the database; missing authz on a sensitive operation; secrets in `public/`; tokens logged; SQL/HTML built by string concatenation.
|
||
**Score 3:** Zod validation + authn + authz on all touched API routes; secrets via env; no obvious OWASP top-10 hole.
|
||
**Score 5:** layered controls (Cerbos policy + route guard + DB constraint); audit log on sensitive ops; rate limit on abuse-prone endpoints; structured error responses that don't leak internals.
|
||
|
||
**Acceptance signals:** every new `src/app/api/**/route.ts` calls a Zod parse; every `auth()` call is paired with a Cerbos check for authz; no `console.log` of tokens, PII, or secrets; sensitive assets out of `public/`.
|
||
|
||
### PbD — Privacy by Design
|
||
|
||
**Definition:** GDPR Article 25 — data minimisation, purpose limitation, retention limits, lawful basis, transparency, user rights (access, portability, erasure, rectification).
|
||
|
||
**Score 1:** collects PII without a documented purpose; retains indefinitely; no consent record for a new processing activity; identity documents accessible without authn; cross-tenant data leakage possible.
|
||
**Score 3:** new fields have a documented purpose; consent is recorded if required; deletion path exists; no obvious GDPR regression.
|
||
**Score 5:** data minimisation actively reduces surface area; retention timer wired to lifecycle; consent versioning supports SAR/portability/erasure flows; brand-agnostic (no tenant cross-leakage); DPIA reasoning in the plan if processing is high-risk.
|
||
|
||
**Acceptance signals:** new PII columns have a `retention` policy reference; consent records updated when processing scope changes; SAR/erasure paths tested; identity-document endpoints require authn + authz + audit; no PII in URLs, logs, or error messages.
|
||
|
||
### OF — Observability First
|
||
|
||
**Definition:** every meaningful boundary emits structured signals (logs, metrics, traces, audit) sufficient to diagnose failure without re-running the operation.
|
||
|
||
**Score 1:** silent failure paths; bare `try/catch` that swallows errors; no log on auth/OCR/PDF/contract events; debugging requires re-creating user state.
|
||
**Score 3:** errors logged with context; key state transitions emit a record; oncall can locate a failure within minutes.
|
||
**Score 5:** structured logs (JSON, correlation IDs); audit trail for regulated ops (consent changes, document state, contract status); user-facing errors carry a trace ID; dashboards/alerts referenced in the plan when introducing new failure modes.
|
||
|
||
**Acceptance signals:** new background jobs log start/finish/error with correlation ID; new state machines emit one event per transition; new third-party calls log latency and outcome; PII redacted from logs.
|
||
|
||
---
|
||
|
||
## Tier-2 Principles (conditional)
|
||
|
||
Declare in `applicable_tier2` when relevant. Score on the same 1–5 scale; ≥3 required when declared.
|
||
|
||
### RBR — Reversibility / Blast Radius
|
||
|
||
**When to declare:** the plan touches migrations, deletes, third-party calls (email, SMS, payment, signing), shared infrastructure, CI/CD, production data, or any irreversible state change.
|
||
|
||
**Score 1:** destructive operation with no rollback path; one-way migration with no shadow column; bulk delete without dry-run.
|
||
**Score 3:** rollback strategy named; non-prod rehearsal planned.
|
||
**Score 5:** expand-then-contract migration; feature flags gate rollout; bulk operations are batched and resumable; every irreversible step has a guard, an audit record, and a documented recovery procedure.
|
||
|
||
### A11y — Accessibility (WCAG 2.2 AA)
|
||
|
||
**When to declare:** the plan introduces or significantly changes user-facing UI, forms, navigation, or content presentation.
|
||
|
||
**Score 1:** keyboard-trap; missing labels; colour-only state; non-semantic markup; forms without error association.
|
||
**Score 3:** semantic HTML; visible focus; labels on inputs; passes axe-core baseline.
|
||
**Score 5:** keyboard parity with mouse; aria-live where dynamic; respects `prefers-reduced-motion`; meets contrast ratios on all themes; tested with a screen reader.
|
||
|
||
### Testability
|
||
|
||
**When to declare:** the plan introduces or significantly changes business logic, domain rules, or system boundaries that future tests must reach.
|
||
|
||
**Score 1:** logic embedded in framework callbacks (Server Components, route handlers) with no extraction; hidden globals; non-deterministic clocks/IDs.
|
||
**Score 3:** pure functions extracted into `src/lib/*`; clock/ID/randomness injectable; tests can call the unit without booting the framework.
|
||
**Score 5:** seams expose every branch; fakes/spies straightforward; integration boundaries (DB, external APIs) covered by either real-DB tests or contract tests; no mocks where the real thing fits.
|
||
|
||
---
|
||
|
||
## Cross-cutting expectations (apply to all principles)
|
||
|
||
- **Plan rationale must cite evidence.** "Score 4" alone is not a verdict; the rationale must reference a file, a behaviour, or a decision in the plan.
|
||
- **Tie-break:** when a principle conflicts with another (e.g., DiDSP suggests a layer that hurts SSoT), the plan must name the trade-off explicitly. The reviewer should score *resolution quality*, not pretend there is no tension.
|
||
- **No retrofitting scores.** Do not raise a score after-the-fact to satisfy the gate; revise the plan instead.
|
||
|
||
---
|
||
|
||
## Review-process integration
|
||
|
||
1. **Phase 1 (Draft)** — author writes the plan and selects `applicable_tier2`. The plan file should include a short *Applicability* line stating which tier-2 principles apply and why.
|
||
2. **Phase 2 (Panel)** — each of the 7 BMAD agents (analyst, architect, pm, sm, ux-designer, dev, tea) returns a verdict. Every verdict scores all tier-1 principles + every declared tier-2 principle.
|
||
3. **Phase 3 (Verdicts file)** — write `/tmp/bmad-panel-verdicts-<session_id>.json` with the schema in the skill.
|
||
4. **Phase 4 (Consolidate)** — address every score <3 in the plan; re-engage the dissenting agent if needed.
|
||
5. **Phase 5 (Exit)** — call `ExitPlanMode`; the hook validates and approves.
|
||
|
||
---
|
||
|
||
## Anti-patterns
|
||
|
||
- **Score-inflation:** raising scores to clear the gate without revising the plan. The next reviewer will catch it; trust will erode.
|
||
- **Tier-2 over-declaration:** declaring every tier-2 principle on every plan dilutes the signal. Only declare what genuinely applies.
|
||
- **Tier-2 under-declaration to bypass review:** if the plan touches migrations, declare RBR. If it touches UI, declare A11y. If it changes domain logic, declare Testability. The Analyst (Mary) is responsible; gaming this defeats the doctrine.
|
||
- **Treating principles as a checklist:** the rubric exists to surface real tensions and trade-offs. A plan that scores 5 on all six tier-1 principles without acknowledging any trade-off is suspect.
|
||
|
||
---
|
||
|
||
## Precedence
|
||
|
||
This file ranks below CLAUDE.md and the documentation-lifecycle / feature-tracking / agent-mode protocols, and above the language-and-framework standards. See `CLAUDE.md > Conflict Resolution Precedence` for the full ordering.
|