Skip to content

Commit 6b53ca5

Browse files
docs(plans): require absorbing deferrals into downstream plans
"Deferred to <plan>" in a closeout Follow-ups section was a pointer that didn't oblige anyone to do anything — the downstream plan could ship without ever absorbing the deferred work, and the deferral would rot in place. Caught when reviewing the workspace plan's .env.example follow-up. Tighten: * "Deferred to <plan>" is only valid when the downstream plan is still `status: planned` * The same closeout commit must edit that downstream plan to absorb the deferral — typically a new bullet under Approach and a new criterion under Validation * If the downstream plan is `in-progress` or `done`, use the Issue shape instead — never modify a plan that's actively being implemented or already frozen Applied immediately to plans/api-skeleton.md to demonstrate the protocol and actually close the workspace deferral: * Approach.Env validation gains a paragraph requiring .env.example to ship with one entry per EnvSchema field * Validation gains a checkbox confirming it exists, cross-linked back to the workspace plan that deferred it Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ee19a5c commit 6b53ca5

3 files changed

Lines changed: 5 additions & 2 deletions

File tree

.claude/CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Plans index: [plans/README.md](../plans/README.md). Workflow:
4040
- **Notes** section: non-actionable carry-forwards — decisions, surprises, gotchas, learnings. Things future-you would want to know.
4141
- **Follow-ups** section: actionable items that didn't ship with this plan. Each entry is one of:
4242
- `Issue [#N](link) — short description` — when actionable and not owned by an existing planned-or-in-progress plan, file the issue first (`gh-axi issue create`) and link it
43-
- `Deferred to [`<other-plan>`](<other-plan>.md) — short description` — when the work is owned by a downstream plan already
43+
- `Deferred to [`<other-plan>`](<other-plan>.md) — short description` — when an unstarted (`status: planned`) downstream plan should own the work. **The same closeout commit must also edit that downstream plan to absorb the deferral** — typically a new bullet under Approach and a new criterion under Validation. If the downstream plan is already `in-progress` or `done`, use the Issue shape instead; never modify a plan that's actively being implemented or already frozen.
4444
- `Tracked as: <free-form pointer>` — for anything else (waiting on community input, vendor response, etc.)
4545
- `None.` — explicit when there's nothing, so a future reader can see the section was considered, not just absent
4646
- The plan is frozen after merge — historical record, no further edits

plans/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Documented in [`.claude/CLAUDE.md`](../.claude/CLAUDE.md#plans). Briefly:
1010

1111
1. Add a plan to start new work. `status: planned` and `depends:` set.
1212
2. Move to `in-progress` when starting, as the first commit on the branch (`chore(plans): mark <slug> in-progress`). Skippable for tiny plans.
13-
3. **Move to `done` as the last commit on the branch, before merge.** That one commit (message: `chore(plans): mark <slug> done (PR #<n>)`) flips frontmatter to `status: done` + `pr: <n>`, ticks each verified validation checkbox, fills in **Notes** (decisions and gotchas worth carrying forward), and fills in **Follow-ups** (actionable items not shipped). Unverifiable criteria stay `[ ]` with a Notes entry explaining where they'll close out — never rewrite a criterion to match what you ended up doing.
13+
3. **Move to `done` as the last commit on the branch, before merge.** That one commit (message: `chore(plans): mark <slug> done (PR #<n>)`) flips frontmatter to `status: done` + `pr: <n>`, ticks each verified validation checkbox, fills in **Notes** (decisions and gotchas worth carrying forward), and fills in **Follow-ups** (actionable items not shipped). Unverifiable criteria stay `[ ]` with a Notes entry explaining where they'll close out — never rewrite a criterion to match what you ended up doing. When a Follow-up takes the "Deferred to `<plan>`" shape, the same commit must also edit that downstream plan to absorb the deferral (Approach + Validation) — and the downstream plan must still be `planned`; otherwise file an issue.
1414
4. After merge: frozen. Historical record, no further edits.
1515
5. A plan implements specs that already exist. If specs need to change mid-plan, the spec change is its own PR before the plan continues.
1616

plans/api-skeleton.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ export const EnvSchema = z.object({
6262

6363
Validation runs at boot; bad config exits 1 with a clear error. No `process.env.X` reads outside `env.ts`.
6464

65+
Ship a `.env.example` file at the repo root that enumerates every `EnvSchema` field with placeholder values + an inline comment per field describing what it's for. This is what new contributors `cp .env.example .env` on first checkout. Keeps the `EnvSchema` and `.env.example` in lockstep is a per-PR review concern; if it drifts, that's a CI follow-up worth filing.
66+
6567
### Response envelope
6668

6769
`apps/api/src/lib/response.ts` exports:
@@ -113,6 +115,7 @@ In-memory `Map<personId+key, cachedResponse>` with a 24h TTL. Mutating endpoints
113115
- [ ] Per-IP rate limit kicks in: 61 anonymous reads from the same IP within a minute → 429 with `Retry-After`
114116
- [ ] Repeat POST with the same `Idempotency-Key` returns the cached response (verified by a stub route)
115117
- [ ] `/api/_openapi.json` returns a valid OpenAPI 3.1 document; `/api/_docs` renders Swagger UI
118+
- [ ] `.env.example` exists at the repo root with one entry per `EnvSchema` field (deferred from [`workspace`](workspace.md))
116119
- [ ] CI passes type-check + tests
117120

118121
## Risks / unknowns

0 commit comments

Comments
 (0)