Skip to content

Commit ade5688

Browse files
shadowdevcodeclaude
andcommitted
chore(agents): enforce Phase 1 engineering rules upstream
Shift-left 7 rules from issue-009 postmortem into agent and command files: auth caller cross-verification, parent/child write sequence check, Gate 0 smoke test before deploy-check, empty ENV var detection, Sentry provisioning checklist in execute-plan, file size budget at generation time, and env var grep step post-implementation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4e0afbf commit ade5688

6 files changed

Lines changed: 172 additions & 5 deletions

File tree

agents/backend-architect-agent.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,29 @@ Before finalizing the architecture, answer all of the following. Any gap must be
220220
9. **Telemetry Latency Isolation**: For every API route with a latency SLA (P95 target), confirm that PostHog/telemetry calls are fire-and-forget (not awaited). Awaited telemetry in hot paths violates latency contracts and creates false fallback triggers in experiment flows.
221221
→ Exception: admin/cron routes where latency SLA doesn't apply.
222222

223+
10. **Dashboard / Report Rehydration Path**: For every dashboard, report, or results page that is linked from navigation, email CTA, push notification, or any external URL:
224+
→ Specify the exact authenticated read path for first-load rehydration: which API route is called, what query it runs, and what state it returns.
225+
→ The mutation response path (result available immediately after POST) is not sufficient — the page must hydrate from the DB on any entry point.
226+
→ Client-memory-only post-mutation flows are blocked for any page reachable from an email link or deep URL.
227+
228+
11. **Parent/Child Write Atomicity**: For every user action that writes a parent record + one or more child records in sequence:
229+
→ Specify the atomicity strategy explicitly: if the child write fails, define whether the parent is rolled back or transitioned to a `failed` state, and confirm error telemetry fires.
230+
→ Partial success (parent = `processed` / `success`, children = missing) is never an acceptable terminal state.
231+
→ "Log and continue" on child write failure is a blocking omission in the architecture spec.
232+
233+
12. **Fan-Out Worker HTTP Contract**: For every fan-out architecture (master cron → N worker routes):
234+
→ Specify the worker HTTP status contract explicitly: "Worker must return HTTP non-2xx (e.g., 502) on any failure that the master should count as failed."
235+
→ Master uses HTTP status only for success/failure accounting — never inspects JSON body.
236+
→ JSON error payloads with HTTP 200 are insufficient as a failure signal to the master.
237+
223238
# Added: 2026-03-19 — SMB Feature Bundling Engine
224239

225240
# Updated: 2026-03-21 — Ozi Reorder Experiment (items 4–7)
226241

227242
# Updated: 2026-03-28 — Nykaa Personalisation (items 8–9)
228243

244+
# Updated: 2026-04-03 — MoneyMirror (items 10–12)
245+
229246
---
230247

231248
## Anti-Sycophancy Mandate

agents/backend-engineer-agent.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,24 @@ Optimize for MVP speed.
154154
Experiment Integrity & Telemetry: Ensure cryptographic salts for A/B testing are server-only (do not use NEXT_PUBLIC). Telemetry calls (e.g., PostHog `captureServerEvent`) in user-facing API routes must be fire-and-forget (`.catch(() => {})`) instead of `await`ed to prevent external latency from corrupting SLAs and experiment data. Control group API responses must return a neutral label ("default"), never the real cohort string — the true cohort is captured server-side in PostHog only.
155155

156156
# Added: 2026-03-28 — Nykaa Personalisation (issue-008)
157+
158+
**Authenticated Route Caller Verification**: After adding authentication to any API route, search all client-side callers of that route path and verify each sends the required auth header. A `fetch()` call to an authenticated route without an `Authorization` header is a CRITICAL bug. A route auth fix without updating all callers is an incomplete fix — both the route and every caller must be updated in the same change.
159+
160+
# Added: 2026-04-03 — MoneyMirror (issue-009)
161+
162+
**File Size Budget at Generation Time**: Before writing any API route or page component expected to contain multi-phase logic, identify extraction points upfront. Route handlers must stay under 200 lines; page components must stay under 250 lines. If a file would exceed these limits, extract helpers or sub-components before writing past the limit — never write a large file and refactor later.
163+
164+
# Added: 2026-04-03 — MoneyMirror (issue-009)
165+
166+
**Infrastructure Provisioning is a hard deliverable** — not a README suggestion. Before execute-plan can be marked DONE, the Backend Engineer must confirm all of the following are complete:
167+
168+
1. **Database project exists** — Neon/Supabase project created and `DATABASE_URL` is a real connection string in `.env.local` (not a placeholder).
169+
2. **Schema applied**`schema.sql` has been run against the live DB. Verify by querying `information_schema.tables` — every expected table must exist.
170+
3. **Auth provider provisioned** — If the app uses Neon Auth, `NEON_AUTH_BASE_URL` must be obtained from the Neon console Auth section and filled in `.env.local`. OTP login must work locally before execute-plan closes.
171+
4. **All non-optional env vars filled** — Every variable in `.env.local.example` that is not explicitly marked `# Optional` must have a real value in `.env.local`. Empty strings (`VAR=`) are a blocking violation.
172+
5. **Sentry project created** — Create a Sentry project (free tier), run `npx @sentry/wizard@latest -i nextjs`, and fill `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` in `.env.local`. This is a backend setup task, not a deploy-check task.
173+
6. **`npm run dev` boots clean** — The app starts without errors and the core user flow works end-to-end. Auth, DB reads/writes, and the primary feature must all function before the task is closed.
174+
175+
Infra gaps discovered at `/deploy-check` are Backend Engineer failures. Ship infra, not just code.
176+
177+
# Added: 2026-04-03 — Shift-left infra validation (issue-009 postmortem pattern)

agents/code-review-agent.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,26 @@ If found: block approval and require removal of the client-side re-fire (server-
114114

115115
# Added: 2026-03-21 — Ozi Reorder Experiment
116116

117+
**Authenticated Route → Caller Cross-Verification** (required for every review):
118+
119+
For every API route confirmed to require authentication:
120+
121+
- Search all `fetch()`, `axios`, and `useSWR` calls in client components (`"use client"` files) targeting that route path.
122+
- If any caller omits the `Authorization` header (or equivalent auth mechanism), flag as **CRITICAL**.
123+
- A route auth fix without updating all callers is an incomplete fix — both sides must be verified in the same review pass.
124+
125+
# Added: 2026-04-03 — MoneyMirror (issue-009)
126+
127+
**Parent/Child Write Sequence** (required for every review):
128+
129+
For every API route that writes a parent record followed by child records:
130+
131+
- Verify the route cannot enter a success state (`processed`, `completed`, `201`) before child writes succeed.
132+
- If parent status is set to a success terminal state before child insert completes, flag as **CRITICAL**.
133+
- Verify that a child write failure either rolls back the parent or transitions it to a `failed` state — never silently logs and continues.
134+
135+
# Added: 2026-04-03 — MoneyMirror (issue-009)
136+
117137
---
118138

119139
## 5 Performance Risks

agents/qa-agent.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,26 @@ Verify:
116116

117117
# Added: 2026-03-21 — Ozi Reorder Experiment
118118

119+
**Env Var Key Name Cross-Check** (standalone QA dimension — required for all projects):
120+
121+
Perform a grep-based audit to verify `.env.local.example` exactly matches the source code:
122+
123+
```bash
124+
grep -r 'process\.env\.' src/ | grep -oP 'process\.env\.\K[A-Z_]+' | sort -u
125+
```
126+
127+
Compare the output against every key listed in `.env.local.example`.
128+
129+
Verify:
130+
131+
1. Every key used in source code appears in `.env.local.example`.
132+
2. Every key name matches exactly — no `NEXT_PUBLIC_` prefix added or removed relative to source usage.
133+
3. If any key in source is absent from the example file, or any name diverges, this is a **blocking QA finding** — env var mismatches cause silent production failures that are nearly impossible to debug from error logs alone.
134+
135+
Note: Pay special attention to server-side telemetry keys (PostHog, Sentry). A `NEXT_PUBLIC_` prefix on a server-only key leaks it to the browser bundle; a missing prefix means server-side clients read `undefined`.
136+
137+
# Added: 2026-04-03 — MoneyMirror (issue-009)
138+
119139
---
120140

121141
## 4 Performance Testing

commands/deploy-check.md

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,29 @@ Follow this sequence.
4444

4545
---
4646

47+
## 0 Local Smoke Test (PM runs manually before triggering /deploy-check)
48+
49+
**This gate must pass before running the command.** If any checkbox fails, fix the infra/env issue first — do not run `/deploy-check` against a broken local environment.
50+
51+
```
52+
□ `npm run dev` starts without errors (port 3000 accessible)
53+
□ /login loads and OTP is sent successfully (Neon Auth is provisioned + NEON_AUTH_BASE_URL filled)
54+
□ Onboarding completes (DB write to profiles table succeeds)
55+
□ Core feature works end-to-end (e.g., PDF upload parses, dashboard loads with data)
56+
□ No 500 errors in browser console or terminal
57+
□ All non-optional env vars have real values in .env.local (not empty strings)
58+
```
59+
60+
If any checkbox fails → diagnose and fix before proceeding. Common causes:
61+
62+
- `NEON_AUTH_BASE_URL` empty → provision Neon Auth on the project, copy the URL
63+
- Missing API keys → get them from the relevant service dashboard
64+
- Schema not applied → run `schema.sql` in Neon/Supabase SQL editor
65+
66+
# Added: 2026-04-03 — Shift-left infra validation; catch env/auth gaps before PR creation
67+
68+
---
69+
4770
## 1 Build Verification
4871

4972
Ensure all components build successfully.
@@ -71,12 +94,18 @@ Ensure secrets are not exposed.
7194
**ENV Completeness Check (blocking)**:
7295

7396
1. Scan `apps/<project-name>/src/` for all `process.env.*` references using grep.
74-
2. Compare the full list against `.env.local.example`.
75-
3. Report any variable present in code but missing from `.env.local.example` as a **BLOCKING violation**.
76-
4. If any missing vars are found: stop here and require them to be added to `.env.local.example` before continuing.
97+
2. Compare the full list against `.env.local.example` — report any variable present in code but missing from `.env.local.example` as a **BLOCKING violation**.
98+
3. Read `.env.local` directly and check each variable's value. Classify each as:
99+
- ✅ FILLED — has a real value
100+
- ⚠️ EMPTY — present in file but value is blank (`VAR=` or `VAR=""`)
101+
- ❌ MISSING — not in file at all
102+
4. Report EMPTY variables as a **BLOCKING violation** — a variable that exists in the file with no value is just as broken as one that's missing.
103+
5. Exception: variables explicitly marked `# Optional` in `.env.local.example` may be empty without blocking.
77104

78105
# Added: 2026-04-02 — ENV completeness must be a gate, not a checklist item
79106

107+
# Updated: 2026-04-03 — Distinguish EMPTY vs MISSING; empty values are a blocking violation
108+
80109
---
81110

82111
## 3 Infrastructure Readiness
@@ -278,9 +307,11 @@ Return output using this structure.
278307
279308
---
280309
310+
Local Smoke Test (Gate 0 — PM confirmed)
311+
281312
Build Status
282313
283-
Environment Configuration
314+
Environment Configuration (FILLED / EMPTY / MISSING per var)
284315
285316
Infrastructure Readiness
286317

commands/execute-plan.md

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ implement service logic
103103
integrate database operations
104104
handle errors and validation
105105

106+
**Sentry setup is a backend deliverable** — not a deploy-check task. During backend implementation:
107+
108+
1. `npm install @sentry/nextjs`
109+
2. `npx @sentry/wizard@latest -i nextjs` (creates `sentry.client.config.ts`, `sentry.server.config.ts`, updates `next.config.ts`)
110+
3. Add `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` to `.env.local.example`
111+
4. Wrap at least one API error handler with `Sentry.captureException(e)`
112+
113+
# Added: 2026-04-03 — Move Sentry setup to execute-plan; deploy-check is verification not first setup
114+
106115
---
107116

108117
## 3 Database Setup
@@ -129,6 +138,26 @@ core user journey works
129138
data flows correctly through system
130139
UI interactions behave correctly
131140

141+
**Read path / write path checkpoint** (required for every page in the plan):
142+
143+
For every page that displays data, verify BOTH paths are implemented before marking it complete:
144+
145+
- **Write path**: mutation fires (POST/upload) → result displayed in same request cycle
146+
- **Read path**: page loads fresh (refresh, direct URL, email deep link) → same result hydrated from DB via authenticated GET endpoint
147+
148+
If only the write path is implemented, the page is incomplete. Any page linked from an email CTA, push notification, or external URL that has no implemented read endpoint is a blocking gap.
149+
150+
**Third-party library API verification** (required for every new npm integration):
151+
152+
After wiring any npm package for the first time:
153+
154+
1. Check the installed version in `package.json`.
155+
2. Verify the generated call pattern against the package's TypeScript types or exported index — not against training knowledge.
156+
3. Run `npm test` to confirm the integration behaves as expected.
157+
4. Training knowledge of library APIs is not sufficient for version-sensitive properties (e.g., `result.total` vs `result.pages?.length`).
158+
159+
# Added: 2026-04-03 — MoneyMirror (issue-009)
160+
132161
---
133162

134163
# Output Format
@@ -151,6 +180,22 @@ Known Issues
151180

152181
---
153182

183+
## 5b File Size Budget Requirement
184+
185+
The 300-line pre-commit limit must be applied **during code generation**, not discovered at commit time.
186+
187+
**Rules**:
188+
189+
- API route handlers: must stay under **200 lines**. If a route handles more than 2 logical phases (e.g., validate → AI call → DB write → telemetry), extract each phase into a named helper function in a separate file before writing the route past 150 lines.
190+
- Page components: must stay under **250 lines**. If a page includes multiple UI states (loading, upload, result), extract each state into a named sub-component before writing the page past 200 lines.
191+
- **Never write a large file and refactor later.** Identify extraction points upfront during task breakdown (Step 0). If a file is projected to exceed the limit, add an extraction task to the task list before writing any code.
192+
193+
Violations discovered at deploy-check (pre-commit hook rejection) are execute-plan failures, not deploy-check tasks.
194+
195+
# Added: 2026-04-03 — MoneyMirror (issue-009)
196+
197+
---
198+
154199
## 6 Telemetry Completeness Requirement
155200

156201
For every API route calling an external AI service, implement PostHog events in ALL branches:
@@ -309,11 +354,24 @@ Before marking execute-plan complete, verify:
309354
- Key design decisions
310355

311356
2. **`.env.local.example`** lists every `process.env.*` reference in the codebase — including any variables added during peer-review or fix cycles.
357+
- **Mandatory grep verification**: Run `grep -r 'process\.env\.' src/ | grep -oP 'process\.env\.\K[A-Z_]+' | sort -u` and compare against every key in `.env.local.example`. Any key in the grep output absent from `.env.local.example` is a blocking gap. Any key name that diverges (e.g., `NEXT_PUBLIC_` added or removed) is a deploy blocker. `.env.local.example` must be generated from source, never from memory.
358+
359+
# Added: 2026-04-03 — MoneyMirror (issue-009)
312360

313-
If either is missing, execute-plan is **not complete**. A deploy-check README failure that originates here is an execute-plan prompt failure — flag it in the postmortem.
361+
3. **Infrastructure provisioning is complete** (blocking — do not mark done until all pass):
362+
- [ ] Neon/Supabase project created and `DATABASE_URL` filled in `.env.local`
363+
- [ ] Database schema applied (`schema.sql` run in SQL editor; all tables verified)
364+
- [ ] Auth provider provisioned (e.g., Neon Auth `NEON_AUTH_BASE_URL` obtained and filled)
365+
- [ ] All non-optional env vars have real values in `.env.local` — no empty strings
366+
- [ ] Sentry project created; `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` filled in `.env.local`
367+
- [ ] `npm run dev` boots without errors and the core user flow works end-to-end locally
368+
369+
If any item above is incomplete, execute-plan is **not done** — it is blocked. Infra gaps discovered at deploy-check are execute-plan failures.
314370

315371
# Added: 2026-03-21 — Ozi Reorder Experiment
316372

373+
# Updated: 2026-04-03 — Add infra provisioning checklist + Sentry setup as execute-plan hard deliverables (shift-left from deploy-check)
374+
317375
---
318376

319377
# Rules

0 commit comments

Comments
 (0)