You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>
Copy file name to clipboardExpand all lines: agents/backend-architect-agent.md
+17Lines changed: 17 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -220,12 +220,29 @@ Before finalizing the architecture, answer all of the following. Any gap must be
220
220
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.
221
221
→ Exception: admin/cron routes where latency SLA doesn't apply.
222
222
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.
Copy file name to clipboardExpand all lines: agents/backend-engineer-agent.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -154,3 +154,24 @@ Optimize for MVP speed.
154
154
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.
**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)
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`.
Copy file name to clipboardExpand all lines: commands/deploy-check.md
+35-4Lines changed: 35 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,29 @@ Follow this sequence.
44
44
45
45
---
46
46
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
+
47
70
## 1 Build Verification
48
71
49
72
Ensure all components build successfully.
@@ -71,12 +94,18 @@ Ensure secrets are not exposed.
71
94
**ENV Completeness Check (blocking)**:
72
95
73
96
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.
77
104
78
105
# Added: 2026-04-02 — ENV completeness must be a gate, not a checklist item
79
106
107
+
# Updated: 2026-04-03 — Distinguish EMPTY vs MISSING; empty values are a blocking violation
108
+
80
109
---
81
110
82
111
## 3 Infrastructure Readiness
@@ -278,9 +307,11 @@ Return output using this structure.
278
307
279
308
---
280
309
310
+
Local Smoke Test (Gate 0 — PM confirmed)
311
+
281
312
Build Status
282
313
283
-
Environment Configuration
314
+
Environment Configuration (FILLED / EMPTY / MISSING per var)
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
+
106
115
---
107
116
108
117
## 3 Database Setup
@@ -129,6 +138,26 @@ core user journey works
129
138
data flows correctly through system
130
139
UI interactions behave correctly
131
140
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
+
132
161
---
133
162
134
163
# Output Format
@@ -151,6 +180,22 @@ Known Issues
151
180
152
181
---
153
182
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
+
154
199
## 6 Telemetry Completeness Requirement
155
200
156
201
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:
309
354
- Key design decisions
310
355
311
356
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)
312
360
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)
0 commit comments