diff --git a/planning/README.md b/planning/README.md index f29bcbc..096d1c6 100644 --- a/planning/README.md +++ b/planning/README.md @@ -30,8 +30,8 @@ intra-day counter. Copy the matching template from [`_templates/`](_templates/). **3. Ship in the implementing PR:** hand-edit the affected -`architecture/.md`, fill `outcome:` in -the bundle frontmatter, and run `just check-planning` before pushing. +`architecture/.md`, finalize the bundle's `summary:` to the +realized result, and run `just check-planning` before pushing. ## Conventions @@ -62,10 +62,11 @@ A change is a folder `changes/YYYY-MM-DD.NN-/`: (`.01`, `.02`, …) that breaks same-date ties so the timeline sorts stably. - `` — kebab-case description, not a story ID. -`summary` is written when the change is created (it is the change's -one-liner). The implementing PR fills `outcome` -**in the branch**, alongside the code and the `architecture/` -promotion — no post-merge bookkeeping, no folder move. +`summary` is written when the change is created (the intent one-liner) and +**finalized at ship** to state the realized result — set in the implementing +PR, alongside the code and the `architecture/` promotion. No post-merge +bookkeeping, no folder move. `date` and `slug` are never written — they are +read from the bundle's directory name. ### Three lanes @@ -96,16 +97,18 @@ Templates live in [`_templates/`](_templates/). ### Frontmatter -`design.md` / `change.md`: `date`, `slug`, `summary` (single line), `outcome`. -`plan.md`: `date`, `slug`, `spec`. `decisions/*.md`: `status` -(accepted|superseded), `date`, `slug`, `summary`, `supersedes`, `superseded_by`. -Files in `architecture/` carry **no** frontmatter — living prose, dated by git. +`date` and `slug` are **derived from the directory / file name** — never +repeated in frontmatter. So: -**`outcome`** is filled at ship time: one line, ~1–3 sentences (≤ ~300 chars), -stating the realized result — what shipped and its effect (deviations from the -plan included), written so a future reader grasps the consequence without -opening the diff. It is distinct from `summary`, which is the pre-ship intent -one-liner. +- `design.md` / `change.md`: `summary` (single line) only. +- `plan.md`: **no frontmatter** — its identity is the bundle directory. +- `decisions/*.md`: `status` (accepted|superseded), `summary`, and optional + `supersedes` / `superseded_by`. +- Files in `architecture/` carry **no** frontmatter — living prose, dated by git. + +**`summary`** is one line: written at creation as the intent, then **finalized +at ship** to state the realized result — what shipped and its effect. It is the +only field the index renders. ## Index diff --git a/planning/_templates/change.md b/planning/_templates/change.md index ab6bc1f..d4c8962 100644 --- a/planning/_templates/change.md +++ b/planning/_templates/change.md @@ -1,8 +1,5 @@ --- -date: YYYY-MM-DD -slug: my-change -summary: One line — shown in the generated index. Fill at ship time. -outcome: Realized result — filled at ship time (~1–3 sentences); see README "Frontmatter". +summary: One line — shown in the generated index. Written at creation; finalize at ship to state the realized result. --- # Change: One-line capitalized title diff --git a/planning/_templates/decision.md b/planning/_templates/decision.md index e3801b8..45ccaf0 100644 --- a/planning/_templates/decision.md +++ b/planning/_templates/decision.md @@ -1,7 +1,5 @@ --- status: accepted # accepted | superseded -date: YYYY-MM-DD -slug: my-decision summary: One line — shown in `just index`. supersedes: null superseded_by: null diff --git a/planning/_templates/design.md b/planning/_templates/design.md index 861ebd2..d63e22d 100644 --- a/planning/_templates/design.md +++ b/planning/_templates/design.md @@ -1,8 +1,5 @@ --- -date: YYYY-MM-DD -slug: my-change -summary: One line — shown in the generated index. Fill at ship time. -outcome: Realized result — filled at ship time (~1–3 sentences); see README "Frontmatter". +summary: One line — shown in the generated index. Written at creation; finalize at ship to state the realized result. --- # Design: One-line capitalized title diff --git a/planning/_templates/plan.md b/planning/_templates/plan.md index 202ff6a..132d720 100644 --- a/planning/_templates/plan.md +++ b/planning/_templates/plan.md @@ -1,9 +1,3 @@ ---- -date: YYYY-MM-DD -slug: my-change -spec: design.md ---- - # — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use @@ -44,9 +38,7 @@ in the spec. ```bash git add path/to/file.py - git commit -m ": - - Co-Authored-By: Claude Opus 4.7 (1M context) " + git commit -m ": " ``` --- diff --git a/planning/changes/2026-06-05.01-bug-hunt-audit/design.md b/planning/changes/2026-06-05.01-bug-hunt-audit/design.md index cd403eb..9b397b1 100644 --- a/planning/changes/2026-06-05.01-bug-hunt-audit/design.md +++ b/planning/changes/2026-06-05.01-bug-hunt-audit/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-05 -slug: bug-hunt-audit summary: Four-dimension bug-hunt audit harness and report; 18 findings actioned in 2.15.0. -outcome: Four-dimension bug-hunt audit harness; report in audits/2026-06-05-bug-hunt-audit-report.md; 18 findings actioned in 2.15.0 (#188–#197). --- # Bug-Hunt Audit — Design diff --git a/planning/changes/2026-06-05.01-bug-hunt-audit/plan.md b/planning/changes/2026-06-05.01-bug-hunt-audit/plan.md index 4dbe2b4..48d6060 100644 --- a/planning/changes/2026-06-05.01-bug-hunt-audit/plan.md +++ b/planning/changes/2026-06-05.01-bug-hunt-audit/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-05 -slug: bug-hunt-audit -spec: design.md ---- - # Bug-Hunt Audit Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-05.02-singleton-rlock/design.md b/planning/changes/2026-06-05.02-singleton-rlock/design.md index e2b4a42..5705a5e 100644 --- a/planning/changes/2026-06-05.02-singleton-rlock/design.md +++ b/planning/changes/2026-06-05.02-singleton-rlock/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-05 -slug: singleton-rlock summary: RLock-guarded singleton creation to eliminate re-entrant deadlock; shipped in 2.15.0. -outcome: RLock guards singleton creation; shipped in 2.15.0. --- # Singleton Re-Entrant Lock Fix — Design diff --git a/planning/changes/2026-06-05.02-singleton-rlock/plan.md b/planning/changes/2026-06-05.02-singleton-rlock/plan.md index 466541d..b0d80f7 100644 --- a/planning/changes/2026-06-05.02-singleton-rlock/plan.md +++ b/planning/changes/2026-06-05.02-singleton-rlock/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-05 -slug: singleton-rlock -spec: design.md ---- - # Singleton RLock Fix Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-05.03-validate-rework/design.md b/planning/changes/2026-06-05.03-validate-rework/design.md index b9bbdad..113a11a 100644 --- a/planning/changes/2026-06-05.03-validate-rework/design.md +++ b/planning/changes/2026-06-05.03-validate-rework/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-05 -slug: validate-rework summary: Reworked validate() for transitive cycle/scope checks; shipped in 2.15.0. -outcome: validate() reworked for transitive cycle/scope checks; shipped in 2.15.0. --- # `Container.validate()` Rework — Design diff --git a/planning/changes/2026-06-05.03-validate-rework/plan.md b/planning/changes/2026-06-05.03-validate-rework/plan.md index b36e591..e8a49b9 100644 --- a/planning/changes/2026-06-05.03-validate-rework/plan.md +++ b/planning/changes/2026-06-05.03-validate-rework/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-05 -slug: validate-rework -spec: design.md ---- - # `Container.validate()` Rework Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/design.md b/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/design.md index 4d008d9..16d4771 100644 --- a/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/design.md +++ b/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-07 -slug: mkdocs-github-pages-migration summary: Docs hosting moved to GitHub Pages at modern-di.modern-python.org. -outcome: Docs hosting moved to GitHub Pages at modern-di.modern-python.org. --- # Migrate docs from Read the Docs to GitHub Pages diff --git a/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/plan.md b/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/plan.md index f8d23d9..6dd03f6 100644 --- a/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/plan.md +++ b/planning/changes/2026-06-07.01-mkdocs-github-pages-migration/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-07 -slug: mkdocs-github-pages-migration -spec: design.md ---- - # MkDocs to GitHub Pages Migration Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-08.01-scheduled-dep-check/design.md b/planning/changes/2026-06-08.01-scheduled-dep-check/design.md index 2f9ccf8..da4924e 100644 --- a/planning/changes/2026-06-08.01-scheduled-dep-check/design.md +++ b/planning/changes/2026-06-08.01-scheduled-dep-check/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-08 -slug: scheduled-dep-check summary: Weekly scheduled dependency-check GitHub Actions workflow. -outcome: Weekly scheduled dependency-check workflow (.github/workflows/scheduled.yml). --- # Scheduled dependency-breakage check diff --git a/planning/changes/2026-06-08.01-scheduled-dep-check/plan.md b/planning/changes/2026-06-08.01-scheduled-dep-check/plan.md index f2dcfe4..1a2609f 100644 --- a/planning/changes/2026-06-08.01-scheduled-dep-check/plan.md +++ b/planning/changes/2026-06-08.01-scheduled-dep-check/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-08 -slug: scheduled-dep-check -spec: design.md ---- - # Scheduled Dependency-Breakage Check Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-09.01-docs-improvements/design.md b/planning/changes/2026-06-09.01-docs-improvements/design.md index c9a0e79..c343ad0 100644 --- a/planning/changes/2026-06-09.01-docs-improvements/design.md +++ b/planning/changes/2026-06-09.01-docs-improvements/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-09 -slug: docs-improvements summary: Docs-site improvements: recipes section, concept pages, refreshed Quick Start. -outcome: Docs-site improvements shipped. --- # Spec: Docs improvements — recipes + concept pages diff --git a/planning/changes/2026-06-09.02-migration-guide-from-that-depends/design.md b/planning/changes/2026-06-09.02-migration-guide-from-that-depends/design.md index 1de90e3..d5a3eb1 100644 --- a/planning/changes/2026-06-09.02-migration-guide-from-that-depends/design.md +++ b/planning/changes/2026-06-09.02-migration-guide-from-that-depends/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-09 -slug: migration-guide-from-that-depends summary: Migration guide from that-depends covering all provider types and conceptual shifts. -outcome: docs/migration/from-that-depends.md published. --- # Spec: Rewrite `from-that-depends.md` migration guide diff --git a/planning/changes/2026-06-12.01-code-docs-audit/design.md b/planning/changes/2026-06-12.01-code-docs-audit/design.md index e669d83..d13a7cc 100644 --- a/planning/changes/2026-06-12.01-code-docs-audit/design.md +++ b/planning/changes/2026-06-12.01-code-docs-audit/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-12 -slug: code-docs-audit summary: Full code+docs audit harness; produced the 57-finding report. -outcome: Full code+docs audit harness; produced the 57-finding report in audits/2026-06-12-code-docs-audit-report.md. --- # Code & Docs Audit — Design diff --git a/planning/changes/2026-06-12.01-code-docs-audit/plan.md b/planning/changes/2026-06-12.01-code-docs-audit/plan.md index 724f9da..d2fa0d0 100644 --- a/planning/changes/2026-06-12.01-code-docs-audit/plan.md +++ b/planning/changes/2026-06-12.01-code-docs-audit/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-12 -slug: code-docs-audit -spec: design.md ---- - # Code & Docs Audit Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-12.02-audit-fixes/change.md b/planning/changes/2026-06-12.02-audit-fixes/change.md index a8511d3..2b3ce6e 100644 --- a/planning/changes/2026-06-12.02-audit-fixes/change.md +++ b/planning/changes/2026-06-12.02-audit-fixes/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-12 -slug: audit-fixes summary: First batch of code+docs audit fixes. Plan-only; spec = the audit report. -spec: ../../../audits/2026-06-12-code-docs-audit-report.md -outcome: Fixed bugs B-1..B-11/X-1, dead code Q-2..Q-4, pinning tests Q-10..Q-15, and doc drift D-3/D-6..D-14 from the 2026-06-12 code+docs audit; shipped in PR #202. --- # Audit Fixes Implementation Plan diff --git a/planning/changes/2026-06-13.01-audit-fixes-round2/change.md b/planning/changes/2026-06-13.01-audit-fixes-round2/change.md index bcc2422..c75e207 100644 --- a/planning/changes/2026-06-13.01-audit-fixes-round2/change.md +++ b/planning/changes/2026-06-13.01-audit-fixes-round2/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-13 -slug: audit-fixes-round2 summary: Round-2 fixes for the 21 deferred code+docs audit findings. Plan-only; spec = the audit report. -spec: ../../../audits/2026-06-12-code-docs-audit-report.md -outcome: Fixed 21 deferred code+docs audit findings (Q-1/Q-5/Q-9/X-2..X-5, Q-6..Q-8/X-6, D-2/D-4/D-5/G-1..G-11) including None-injection and coverage-gate move; shipped in PR #203. --- # Audit Fixes — Round 2 Implementation Plan diff --git a/planning/changes/2026-06-13.01-docs-ux-audit/design.md b/planning/changes/2026-06-13.01-docs-ux-audit/design.md index c8a23e4..e729c0f 100644 --- a/planning/changes/2026-06-13.01-docs-ux-audit/design.md +++ b/planning/changes/2026-06-13.01-docs-ux-audit/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-13 -slug: docs-ux-audit summary: Reader-experience audit producing a 70-finding report (16 Medium, 54 Low). -outcome: Produced the 70-finding reader-experience report (0 High, 16 Medium, 54 Low) in audits/2026-06-13-docs-ux-audit-report.md. All 16 Mediums fixed in PR #212; 54 Lows catalogued for later. --- # Design: Docs UX & Consistency Audit diff --git a/planning/changes/2026-06-13.01-docs-ux-audit/plan.md b/planning/changes/2026-06-13.01-docs-ux-audit/plan.md index 2be7edd..2a5e065 100644 --- a/planning/changes/2026-06-13.01-docs-ux-audit/plan.md +++ b/planning/changes/2026-06-13.01-docs-ux-audit/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-13 -slug: docs-ux-audit -spec: design.md ---- - # Plan: Docs UX & Consistency Audit Execution is a single multi-agent workflow (`Workflow` tool). This plan records diff --git a/planning/changes/2026-06-13.02-alias-scope-transparency/change.md b/planning/changes/2026-06-13.02-alias-scope-transparency/change.md index adf5f9d..0c1fcca 100644 --- a/planning/changes/2026-06-13.02-alias-scope-transparency/change.md +++ b/planning/changes/2026-06-13.02-alias-scope-transparency/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-13 -slug: alias-scope-transparency summary: Deprecate decorative `Alias(scope=...)`; `validate()` checks scope transitively via `effective_scope` (X-4). Plan-only; spec = the code-docs audit report. -spec: ../../../audits/2026-06-12-code-docs-audit-report.md -outcome: validate() now checks scope transitively via effective_scope through aliases (X-4); decorative Alias(scope=) deprecated; enforces_dependency_scope stopgap retired; shipped as 2.17.0 in PR #207. --- # Alias Scope Transparency (X-4) Implementation Plan diff --git a/planning/changes/2026-06-13.02-docs-ux-fixes/design.md b/planning/changes/2026-06-13.02-docs-ux-fixes/design.md index c688637..af032e5 100644 --- a/planning/changes/2026-06-13.02-docs-ux-fixes/design.md +++ b/planning/changes/2026-06-13.02-docs-ux-fixes/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-13 -slug: docs-ux-fixes summary: Fixed all 16 Medium findings from the docs UX audit (runnable examples, accuracy, nav). -outcome: All 16 Medium findings fixed and merged in PR #212 (#11b7b70). mkdocs --strict green; runnable snippets verified; O-5/O-6 confirmed against sibling repos. Architecture pages (scopes.md, providers.md) hand-edited as part of the fixes. --- # Design: Docs UX fixes (all 16 Medium audit findings) diff --git a/planning/changes/2026-06-13.02-docs-ux-fixes/plan.md b/planning/changes/2026-06-13.02-docs-ux-fixes/plan.md index 1999fc1..620b8d4 100644 --- a/planning/changes/2026-06-13.02-docs-ux-fixes/plan.md +++ b/planning/changes/2026-06-13.02-docs-ux-fixes/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-13 -slug: docs-ux-fixes -spec: design.md ---- - # Docs UX Fixes Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. diff --git a/planning/changes/2026-06-13.03-portable-planning-convention/design.md b/planning/changes/2026-06-13.03-portable-planning-convention/design.md index 884e4c7..5524a1d 100644 --- a/planning/changes/2026-06-13.03-portable-planning-convention/design.md +++ b/planning/changes/2026-06-13.03-portable-planning-convention/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-13 -slug: portable-planning-convention summary: Adopted the two-axis planning convention (architecture/ truth + changes/ bundles) from faststream-outbox. -outcome: Adopted the two-axis convention — architecture/ truth home (README + 6 capability docs) + planning/changes/{active,archive}/ bundles; migrated 11 historical spec/plan pairs into archive bundles; added portable README, _templates/, CLAUDE.md Workflow. Also aligned CLAUDE.md Architecture with the code. --- # Design: Adopt the portable planning convention diff --git a/planning/changes/2026-06-14.01-docs-ux-lows/change.md b/planning/changes/2026-06-14.01-docs-ux-lows/change.md index fefd7bf..a71e353 100644 --- a/planning/changes/2026-06-14.01-docs-ux-lows/change.md +++ b/planning/changes/2026-06-14.01-docs-ux-lows/change.md @@ -1,8 +1,5 @@ --- -date: 2026-06-14 -slug: docs-ux-lows summary: Fixed all 53 Low findings from the docs UX audit (cross-links, imports, terminology, docstrings). -outcome: All 53 Low findings fixed and merged in PR #213 (b81c23f). mkdocs --strict green, lint clean, 199 tests / 100% coverage. D-10 was already resolved by X-3 (#212); R-2/D-24 already satisfied there. Executed via parallel file-scoped subagents + central verification. --- # Change: Docs UX audit — fix the 53 Low findings diff --git a/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/design.md b/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/design.md index 94affdf..76dbabb 100644 --- a/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/design.md +++ b/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/design.md @@ -1,11 +1,5 @@ --- -date: 2026-06-14 -slug: set-context-cross-scope-staleness summary: Resolve ContextProvider params live so late set_context always propagates across scopes. -outcome: Shipped. ContextProvider values now resolve live on every resolve; - invalidate_compiled_kwargs deleted (net simplification). Late set_context - propagates across scopes for non-cached factories; cached-singleton limitation - documented. 205 tests, 100% coverage. --- # Design: Resolve context values live so late `set_context` always propagates diff --git a/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/plan.md b/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/plan.md index 3e9f749..9b7e607 100644 --- a/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/plan.md +++ b/planning/changes/2026-06-14.02-set-context-cross-scope-staleness/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-14 -slug: set-context-cross-scope-staleness -spec: design.md ---- - # set-context-cross-scope-staleness — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/changes/2026-06-14.03-audit-doc-rulings-batch1/change.md b/planning/changes/2026-06-14.03-audit-doc-rulings-batch1/change.md index 0ac59d6..c687a63 100644 --- a/planning/changes/2026-06-14.03-audit-doc-rulings-batch1/change.md +++ b/planning/changes/2026-06-14.03-audit-doc-rulings-batch1/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-14 -slug: audit-doc-rulings-batch1 summary: Action batch-1 rulings from the 2026-06-14 deep audit (B-4 pin, B-5/S-1/S-2 doc notes, A-1 comment + nogil caveat; A-2 closed). Doc/test/comment-only. Plan-only; spec = the audit report. -spec: ../../../audits/2026-06-14-deep-audit-report.md -outcome: Actioned batch-1 doc/test/comment rulings from 2026-06-14 deep audit (B-4 pin, B-5/S-1/S-2 doc notes, A-1 comment + nogil caveat; A-2 closed with no action); shipped in PR #217. --- # audit-doc-rulings-batch1 — implementation plan diff --git a/planning/changes/2026-06-14.04-audit-fixes-batch2/change.md b/planning/changes/2026-06-14.04-audit-fixes-batch2/change.md index 0342899..02b145e 100644 --- a/planning/changes/2026-06-14.04-audit-fixes-batch2/change.md +++ b/planning/changes/2026-06-14.04-audit-fixes-batch2/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-14 -slug: audit-fixes-batch2 summary: B-3 (gapped custom-enum child-scope derivation) + P-1 (drop the per-resolve throwaway `CacheItem` alloc via a `get` fast path, keeping atomic `setdefault` on creation). Plan-only; spec = the audit report. -spec: ../../../audits/2026-06-14-deep-audit-report.md -outcome: Fixed B-3 (gapped custom-enum child-scope derivation) and P-1 (eliminate per-resolve throwaway CacheItem alloc via get fast path) from 2026-06-14 deep audit; shipped in PR #218. --- # audit-fixes-batch2 — implementation plan diff --git a/planning/changes/2026-06-14.05-audit-fixes-batch3/change.md b/planning/changes/2026-06-14.05-audit-fixes-batch3/change.md index 036128b..b1dbbc9 100644 --- a/planning/changes/2026-06-14.05-audit-fixes-batch3/change.md +++ b/planning/changes/2026-06-14.05-audit-fixes-batch3/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-14 -slug: audit-fixes-batch3 summary: R-1 (`AbstractProvider.display_name` dedupes the bound-type-or-repr idiom across ~5 sites) + R-2 minimal (public `fetch_context_value`, drop the `SLF001` reach-in). Plan-only; spec = the audit report. -spec: ../../../audits/2026-06-14-deep-audit-report.md -outcome: Added AbstractProvider.display_name deduping R-1 (~5 sites) and public fetch_context_value dropping the SLF001 reach-in (R-2) from 2026-06-14 deep audit; shipped in PR #219. --- # audit-fixes-batch3 — implementation plan diff --git a/planning/changes/2026-06-14.06-audit-fixes-batch4-5/change.md b/planning/changes/2026-06-14.06-audit-fixes-batch4-5/change.md index 3c5db22..ef583b4 100644 --- a/planning/changes/2026-06-14.06-audit-fixes-batch4-5/change.md +++ b/planning/changes/2026-06-14.06-audit-fixes-batch4-5/change.md @@ -1,9 +1,5 @@ --- -date: 2026-06-14 -slug: audit-fixes-batch4-5 summary: Final audit cleanup: test hardening (P-6 compile-once pin, R-3 behavioral singleton assert, X-2 structured suggestion/path asserts) + DX/docs (X-3 exception docstrings, X-4 `exceptions` export, X-5 `ResolutionStep` docs). Closes every actionable finding. Plan-only; spec = audit report. -spec: ../../../audits/2026-06-14-deep-audit-report.md -outcome: Closed every actionable 2026-06-14 audit finding (P-6/R-3/X-2 test hardening; X-3/X-4/X-5 DX/docs); only won't-fix R-4/R-5/R-6 and the A-1 nogil follow-up remain. --- # audit-fixes-batch4-5 — implementation plan diff --git a/planning/changes/2026-06-23.01-wiring-plan-extraction/design.md b/planning/changes/2026-06-23.01-wiring-plan-extraction/design.md index 330ec8c..9c89fa5 100644 --- a/planning/changes/2026-06-23.01-wiring-plan-extraction/design.md +++ b/planning/changes/2026-06-23.01-wiring-plan-extraction/design.md @@ -1,18 +1,5 @@ --- -date: 2026-06-23 -slug: wiring-plan-extraction summary: Extract a WiringPlan deep module from Factory so the kwarg-binding decision lives in one place, testable without a Container. -outcome: | - Shipped. Factory's kwarg-wiring decision moved to a pure WiringPlan module - (modern_di/wiring.py): one matcher, one absent-value table (absent_disposition), - one error-construction site, testable with no Container. _compile_kwargs and - _find_dep_provider deleted; CacheItem holds one wiring_plan field. Behavior - preserved; the static-kwarg-provider validate() asymmetry kept intentionally. - The whole-branch review caught a CRITICAL regression — the plan memoized a - pre-built ArgumentResolutionError that resolve()'s prepend_step mutated, so - breadcrumbs compounded/leaked across repeated and nested failing resolves; fixed - by storing unwireable (name, SignatureItem) records and building the error fresh - per raise (regression tests added). 225 tests, 100% coverage. --- # Design: Extract the kwarg-wiring decision out of `Factory` into a `WiringPlan` diff --git a/planning/changes/2026-06-23.01-wiring-plan-extraction/plan.md b/planning/changes/2026-06-23.01-wiring-plan-extraction/plan.md index 32883aa..5051ae9 100644 --- a/planning/changes/2026-06-23.01-wiring-plan-extraction/plan.md +++ b/planning/changes/2026-06-23.01-wiring-plan-extraction/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-23 -slug: wiring-plan-extraction -spec: design.md ---- - # wiring-plan-extraction — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/changes/2026-06-23.02-inline-error-messages/design.md b/planning/changes/2026-06-23.02-inline-error-messages/design.md index ff127a6..1e8f1ff 100644 --- a/planning/changes/2026-06-23.02-inline-error-messages/design.md +++ b/planning/changes/2026-06-23.02-inline-error-messages/design.md @@ -1,15 +1,5 @@ --- -date: 2026-06-23 -slug: inline-error-messages summary: Inline the single-use error templates into their exception classes and delete the errors.py seam. -outcome: | - Shipped. 17 single-use message templates inlined as f-strings into their - exception classes; SUGGESTION_HEADER kept as a module constant in exceptions.py; - the 3 SUGGESTION_* line-formats inlined into providers_registry.py; errors.py - deleted. The review's import-cycle worry was verified moot (no constant crosses - both modules). A before/after str(e) dump across all 23 exception cases proved - every message byte-identical; ty caught a third errors importer in a benchmark, - also inlined. 225 tests, 100% coverage. --- # Design: Inline error messages into their exceptions and delete `errors.py` diff --git a/planning/changes/2026-06-23.02-inline-error-messages/plan.md b/planning/changes/2026-06-23.02-inline-error-messages/plan.md index 81b1a72..d6bf094 100644 --- a/planning/changes/2026-06-23.02-inline-error-messages/plan.md +++ b/planning/changes/2026-06-23.02-inline-error-messages/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-23 -slug: inline-error-messages -spec: design.md ---- - # inline-error-messages — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/changes/2026-06-23.03-suggester/design.md b/planning/changes/2026-06-23.03-suggester/design.md index f830753..bdf6713 100644 --- a/planning/changes/2026-06-23.03-suggester/design.md +++ b/planning/changes/2026-06-23.03-suggester/design.md @@ -1,15 +1,5 @@ --- -date: 2026-06-23 -slug: suggester summary: Extract the shared difflib fuzzy-match primitive into a directly-testable suggester module. -outcome: | - Shipped. The two difflib.get_close_matches sites (registry type suggestions, - factory kwarg "did you mean") now delegate to modern_di/suggester.close_matches; - the 0.6 cutoff lives once as its default; difflib is confined to suggester.py. - Adds tests/test_suggester.py (7 direct tests) — the fuzzy match is now unit- - testable without raising an error. Behavior identical (both sites already used - 0.6); review confirmed the list(candidates) materialization is behavior-neutral - (difflib's equal-ratio tie-break is deterministic). 232 tests, 100% coverage. --- # Design: A `suggester` module for the shared "did you mean" fuzzy match diff --git a/planning/changes/2026-06-23.03-suggester/plan.md b/planning/changes/2026-06-23.03-suggester/plan.md index 3835a39..abc545d 100644 --- a/planning/changes/2026-06-23.03-suggester/plan.md +++ b/planning/changes/2026-06-23.03-suggester/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-23 -slug: suggester -spec: design.md ---- - # suggester — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/changes/2026-06-25.01-agent-friendly-planning-convention/design.md b/planning/changes/2026-06-25.01-agent-friendly-planning-convention/design.md index 8a8b4ac..f642479 100644 --- a/planning/changes/2026-06-25.01-agent-friendly-planning-convention/design.md +++ b/planning/changes/2026-06-25.01-agent-friendly-planning-convention/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-25 -slug: agent-friendly-planning-convention summary: Make the planning convention agent-friendly — progressive-disclosure restructure (Quick-path on-ramp, deterministic lane decision, de-duplicated text) plus a `just check-planning` validator. -outcome: Shipped an agent-friendly planning convention — a `just check-planning` validator wired into `lint-ci`, a Quick-path on-ramp with a first-match lane decision, and CLAUDE.md de-duplicated to a pointer. Mid-flight the maintainer also dropped `pr` and `status`/supersession from change bundles, making a defined `outcome` the sole required lifecycle field. --- # Design: Make the planning convention agent-friendly diff --git a/planning/changes/2026-06-25.01-agent-friendly-planning-convention/plan.md b/planning/changes/2026-06-25.01-agent-friendly-planning-convention/plan.md index 0000f77..12d6b11 100644 --- a/planning/changes/2026-06-25.01-agent-friendly-planning-convention/plan.md +++ b/planning/changes/2026-06-25.01-agent-friendly-planning-convention/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-25 -slug: agent-friendly-planning-convention -spec: design.md ---- - # agent-friendly-planning-convention — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/changes/2026-06-25.02-architecture-promotion-reminder/change.md b/planning/changes/2026-06-25.02-architecture-promotion-reminder/change.md index c864070..de0565b 100644 --- a/planning/changes/2026-06-25.02-architecture-promotion-reminder/change.md +++ b/planning/changes/2026-06-25.02-architecture-promotion-reminder/change.md @@ -1,8 +1,5 @@ --- -date: 2026-06-25 -slug: architecture-promotion-reminder summary: Add an agent-facing note in CLAUDE.md reminding that a behavior change must promote to the matching architecture/.md in the same PR. -outcome: Added a one-line promotion imperative to CLAUDE.md's `## Architecture` intro, resolving evaluation Finding 3 with an agent-facing reminder rather than a CI gate. --- # Change: Agent-facing architecture/ promotion reminder diff --git a/planning/changes/2026-06-25.03-canonical-convention-repo/design.md b/planning/changes/2026-06-25.03-canonical-convention-repo/design.md index 352aa97..a0ebc80 100644 --- a/planning/changes/2026-06-25.03-canonical-convention-repo/design.md +++ b/planning/changes/2026-06-25.03-canonical-convention-repo/design.md @@ -1,8 +1,5 @@ --- -date: 2026-06-25 -slug: canonical-convention-repo summary: Extract the portable planning convention into a personal canonical repo (lesnik512/planning-convention) that agents apply/update into any repo via an APPLY.md instruction doc + a per-repo version marker. -outcome: "Extracted the portable planning convention into lesnik512/planning-convention (v1.0.0) with an APPLY.md agent-apply flow + planning/.convention-version marker; modern-di wired as consumer #1 with the README blockquote repointed to the canonical upstream." --- # Design: Canonical planning-convention repo applied by agents diff --git a/planning/changes/2026-06-25.03-canonical-convention-repo/plan.md b/planning/changes/2026-06-25.03-canonical-convention-repo/plan.md index d466a96..712151a 100644 --- a/planning/changes/2026-06-25.03-canonical-convention-repo/plan.md +++ b/planning/changes/2026-06-25.03-canonical-convention-repo/plan.md @@ -1,9 +1,3 @@ ---- -date: 2026-06-25 -slug: canonical-convention-repo -spec: design.md ---- - # canonical-convention-repo — implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use diff --git a/planning/decisions/2026-06-23-sync-async-close-separate.md b/planning/decisions/2026-06-23-sync-async-close-separate.md index 79483d0..d92a153 100644 --- a/planning/decisions/2026-06-23-sync-async-close-separate.md +++ b/planning/decisions/2026-06-23-sync-async-close-separate.md @@ -1,7 +1,5 @@ --- status: accepted -date: 2026-06-23 -slug: sync-async-close-separate summary: Keep sync/async close paths separate — the divergence is intrinsic, not duplication. supersedes: null superseded_by: null diff --git a/planning/index.py b/planning/index.py index ec6c2dc..8916661 100644 --- a/planning/index.py +++ b/planning/index.py @@ -7,6 +7,9 @@ reads their frontmatter, and prints a Markdown listing to stdout — changes then decisions, newest-first. Never writes a file: the listing is a query over the files, not a committed artifact. + +``date`` and ``slug`` are derived from the directory / file name, not +frontmatter — the name is the single source of truth for both. """ import pathlib @@ -17,12 +20,11 @@ CHANGES_DIR = pathlib.Path(__file__).parent / "changes" DECISIONS_DIR = pathlib.Path(__file__).parent / "decisions" VALID_DECISION_STATUS = {"accepted", "superseded"} -DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$") -BUNDLE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}\.\d{2}-(?P.+)$") +BUNDLE_RE = re.compile(r"^(?P\d{4}-\d{2}-\d{2})\.\d{2}-(?P.+)$") +DECISION_RE = re.compile(r"^(?P\d{4}-\d{2}-\d{2})-(?P.+)$") ALLOWED_BUNDLE_FILES = {"design.md", "plan.md", "change.md"} -SPEC_REQUIRED = ("date", "slug", "summary", "outcome") -PLAN_REQUIRED = ("date", "slug", "spec") -DECISION_REQUIRED = ("status", "date", "slug", "summary") +SPEC_REQUIRED = ("summary",) +DECISION_REQUIRED = ("status", "summary") def parse_frontmatter(text: str) -> dict[str, str]: @@ -44,8 +46,17 @@ def parse_frontmatter(text: str) -> dict[str, str]: return fields +def _named(fields: dict[str, str], name: str, pattern: re.Pattern[str]) -> dict[str, str]: + """Inject ``date``/``slug`` derived from a dir/file name into ``fields``.""" + match = pattern.match(name) + if match: + fields["date"] = match.group("date") + fields["slug"] = match.group("slug") + return fields + + def load_bundles() -> list[dict[str, str]]: - """Read every bundle's spec frontmatter under ``CHANGES_DIR``.""" + """Read each bundle's summary; derive date/slug from the directory name.""" bundles: list[dict[str, str]] = [] for bundle in sorted(CHANGES_DIR.iterdir()): if not bundle.is_dir(): @@ -55,7 +66,7 @@ def load_bundles() -> list[dict[str, str]]: spec = bundle / "change.md" if not spec.exists(): continue - fields = parse_frontmatter(spec.read_text(encoding="utf-8")) + fields = _named(parse_frontmatter(spec.read_text(encoding="utf-8")), bundle.name, BUNDLE_RE) fields["path"] = f"changes/{bundle.name}/{spec.name}" fields["name"] = bundle.name bundles.append(fields) @@ -63,14 +74,14 @@ def load_bundles() -> list[dict[str, str]]: def load_decisions() -> list[dict[str, str]]: - """Read frontmatter from every decision file under ``DECISIONS_DIR``.""" + """Read each decision's frontmatter; derive date/slug from the file name.""" decisions: list[dict[str, str]] = [] if not DECISIONS_DIR.is_dir(): return decisions for path in sorted(DECISIONS_DIR.glob("*.md")): if path.name == "README.md" or path.name.startswith("_"): continue - fields = parse_frontmatter(path.read_text(encoding="utf-8")) + fields = _named(parse_frontmatter(path.read_text(encoding="utf-8")), path.stem, DECISION_RE) fields["path"] = f"decisions/{path.name}" fields["name"] = path.stem decisions.append(fields) @@ -108,41 +119,16 @@ def _require(fields: dict[str, str], keys: tuple[str, ...], rel: str, violations violations.extend(f"{rel}: missing or empty frontmatter key '{key}'" for key in keys if not fields.get(key)) -def _check_common(fields: dict[str, str], dir_slug: str | None, rel: str, violations: list[str]) -> None: - """Validate date/slug fields shared by every artifact type.""" - date = fields.get("date", "") - if date and not DATE_RE.match(date): - violations.append(f"{rel}: date '{date}' is not YYYY-MM-DD") - slug = fields.get("slug", "") - if dir_slug and slug and slug != dir_slug: - violations.append(f"{rel}: slug '{slug}' does not match directory slug '{dir_slug}'") - - -def _check_spec_file(path: pathlib.Path, rel: str, dir_slug: str | None, violations: list[str]) -> None: - """Validate a design.md / change.md spec file.""" +def _check_spec_file(path: pathlib.Path, rel: str, violations: list[str]) -> None: + """Validate a design.md / change.md spec file (requires `summary`).""" fields = parse_frontmatter(path.read_text(encoding="utf-8")) _require(fields, SPEC_REQUIRED, rel, violations) - _check_common(fields, dir_slug, rel, violations) - - -def _check_plan_file( - path: pathlib.Path, bundle: pathlib.Path, rel: str, dir_slug: str | None, violations: list[str] -) -> None: - """Validate a plan.md file, including that its spec: link resolves.""" - fields = parse_frontmatter(path.read_text(encoding="utf-8")) - _require(fields, PLAN_REQUIRED, rel, violations) - _check_common(fields, dir_slug, rel, violations) - spec = fields.get("spec", "") - if spec and not (bundle / spec).resolve().exists(): - violations.append(f"{rel}: spec link '{spec}' does not resolve to a file") def _check_bundle(bundle: pathlib.Path, violations: list[str]) -> None: """Validate one change bundle directory.""" rel = f"changes/{bundle.name}" - match = BUNDLE_RE.match(bundle.name) - dir_slug = match.group("slug") if match else None - if match is None: + if BUNDLE_RE.match(bundle.name) is None: violations.append(f"{rel}: directory name is not 'YYYY-MM-DD.NN-slug'") violations.extend( f"{rel}/{child.name}: unexpected file in bundle (allowed: {', '.join(sorted(ALLOWED_BUNDLE_FILES))})" @@ -151,22 +137,21 @@ def _check_bundle(bundle: pathlib.Path, violations: list[str]) -> None: ) design = bundle / "design.md" change = bundle / "change.md" - plan = bundle / "plan.md" if not design.exists() and not change.exists(): violations.append(f"{rel}: bundle has neither design.md nor change.md") for spec_file in (design, change): if spec_file.exists(): - _check_spec_file(spec_file, f"{rel}/{spec_file.name}", dir_slug, violations) - if plan.exists(): - _check_plan_file(plan, bundle, f"{rel}/plan.md", dir_slug, violations) + _check_spec_file(spec_file, f"{rel}/{spec_file.name}", violations) + # plan.md carries no frontmatter — its identity comes from the bundle dir. def _check_decision(path: pathlib.Path, violations: list[str]) -> None: - """Validate one decision file.""" + """Validate one decision file (requires `status` + `summary`).""" rel = f"decisions/{path.name}" + if DECISION_RE.match(path.stem) is None: + violations.append(f"{rel}: file name is not 'YYYY-MM-DD-slug.md'") fields = parse_frontmatter(path.read_text(encoding="utf-8")) _require(fields, DECISION_REQUIRED, rel, violations) - _check_common(fields, None, rel, violations) status = fields.get("status", "") if status and status not in VALID_DECISION_STATUS: violations.append(f"{rel}: invalid status '{status}' (allowed: {', '.join(sorted(VALID_DECISION_STATUS))})")