|
| 1 | +# Planning |
| 2 | + |
| 3 | +Specs, plans, and change history for `modern-di-faststream`. The living truth |
| 4 | +about *what the system does now* lives in [`architecture/`](../architecture/) |
| 5 | +at the repo root; this directory records *how it got there*. |
| 6 | + |
| 7 | +## Quick path (start here) |
| 8 | + |
| 9 | +> The fast lane for making a change. The full reference is in |
| 10 | +> [Conventions](#conventions) below — read it only when this isn't enough. |
| 11 | +
|
| 12 | +**1. Choose a lane — first matching rule wins:** |
| 13 | + |
| 14 | +1. Any of: needs design judgment · new file/module · public-API change · |
| 15 | + cross-cutting or multi-file · non-trivial test design → **Full** |
| 16 | + (`design.md` + `plan.md`) |
| 17 | +2. Purely mechanical: typo · dep bump · linter/formatter/CI tweak · |
| 18 | + mechanical rename · single-line config → **Tiny** (no bundle, conventional |
| 19 | + commit) |
| 20 | +3. Small-but-real, none of the above: ≲30 LOC net · ≤2 files · no new file · |
| 21 | + no public-API change · one straightforward test → **Lightweight** |
| 22 | + (`change.md`) |
| 23 | + |
| 24 | +Ambiguous between two? Take the heavier. A `change.md` that outgrows its lane |
| 25 | +splits into `design.md` + `plan.md`. |
| 26 | + |
| 27 | +**2. Create the bundle** (Full / Lightweight only): |
| 28 | +`planning/changes/YYYY-MM-DD.NN-<slug>/`, where `.NN` is a zero-padded |
| 29 | +intra-day counter. Copy the matching template from |
| 30 | +[`_templates/`](_templates/). |
| 31 | + |
| 32 | +**3. Ship in the implementing PR:** hand-edit the affected |
| 33 | +`architecture/<capability>.md`, finalize the bundle's `summary:` to the |
| 34 | +realized result, and run `just check-planning` before pushing. |
| 35 | + |
| 36 | +## Conventions |
| 37 | + |
| 38 | +> This is the portable convention, sourced from the canonical repo |
| 39 | +> [`lesnik512/planning-convention`](https://github.com/lesnik512/planning-convention) |
| 40 | +> (applied version in [`.convention-version`](.convention-version)). To update |
| 41 | +> it, run that repo's `APPLY.md` flow. The generated change index (`just index`) |
| 42 | +> and the `## Other` pointers below are repo-local. |
| 43 | +
|
| 44 | +### Two axes, never mixed |
| 45 | + |
| 46 | +- **`architecture/` (repo root) — the present.** One file per capability, |
| 47 | + living prose, updated in the same PR that ships the change. The truth home. |
| 48 | +- **`planning/changes/` — the past-and-pending.** One folder per change, |
| 49 | + kept in place after ship. |
| 50 | + |
| 51 | +A change **promotes** its conclusions into the affected |
| 52 | +`architecture/<capability>.md` by hand **in the implementing PR, alongside the |
| 53 | +code** — the edit rides in the same diff and is reviewed with it, never applied |
| 54 | +as a separate post-merge step. That hand-edit is what keeps `architecture/` |
| 55 | +true; the bundle stays in `changes/` as the *why*. |
| 56 | + |
| 57 | +### Change bundles |
| 58 | + |
| 59 | +A change is a folder `changes/YYYY-MM-DD.NN-<slug>/`: |
| 60 | + |
| 61 | +- `YYYY-MM-DD` — proposal date; `.NN` — zero-padded intra-day counter |
| 62 | + (`.01`, `.02`, …) that breaks same-date ties so the timeline sorts stably. |
| 63 | +- `<slug>` — kebab-case description, not a story ID. |
| 64 | + |
| 65 | +`summary` is written when the change is created (the intent one-liner) and |
| 66 | +**finalized at ship** to state the realized result — set in the implementing |
| 67 | +PR, alongside the code and the `architecture/` promotion. No post-merge |
| 68 | +bookkeeping, no folder move. `date` and `slug` are never written — they are |
| 69 | +read from the bundle's directory name. |
| 70 | + |
| 71 | +### Three lanes |
| 72 | + |
| 73 | +| Lane | Artifacts | Use when | |
| 74 | +|------|-----------|----------| |
| 75 | +| **Full** | `design.md` + `plan.md` | design judgment; new file/module; public-API change; cross-cutting/multi-file; non-trivial test design | |
| 76 | +| **Lightweight** | `change.md` | small-but-real: ≲30 LOC net, ≤2 files, no new file, no public-API change, single straightforward test | |
| 77 | +| **Tiny** | none — conventional commit | typo, dep bump, linter/formatter/CI tweak, mechanical rename, single-line config | |
| 78 | + |
| 79 | +Heavier lane wins on ambiguity. A `change.md` that outgrows its lane splits |
| 80 | +into `design.md` + `plan.md`. |
| 81 | + |
| 82 | +### Artifacts at a glance |
| 83 | + |
| 84 | +- **`design.md`** — the spec: the *thinking* (why, design, trade-offs, scope). |
| 85 | +- **`plan.md`** — the plan: the *sequencing* (the executor's task checklist). |
| 86 | +- **`change.md`** — both, condensed, for the lightweight lane. |
| 87 | +- **`releases/<semver>.md`** — per-release user-facing notes. |
| 88 | +- **`audits/<date>-<slug>.md`** — findings from a code/docs/bug-hunt sweep; |
| 89 | + spawns fix changes. |
| 90 | +- **`retros/<date>-<slug>.md`** — what we learned after a body of work. |
| 91 | +- **`deferred.md`** — real-but-unscheduled items, each with a revisit trigger. |
| 92 | +- **`decisions/<YYYY-MM-DD>-<slug>.md`** — one file per design decision taken |
| 93 | + (especially options *rejected*), each with a revisit trigger; listed by |
| 94 | + `just index`. |
| 95 | + |
| 96 | +Templates live in [`_templates/`](_templates/). |
| 97 | + |
| 98 | +### Frontmatter |
| 99 | + |
| 100 | +`date` and `slug` are **derived from the directory / file name** — never |
| 101 | +repeated in frontmatter. So: |
| 102 | + |
| 103 | +- `design.md` / `change.md`: `summary` (single line) only. |
| 104 | +- `plan.md`: **no frontmatter** — its identity is the bundle directory. |
| 105 | +- `decisions/*.md`: `status` (accepted|superseded), `summary`, and optional |
| 106 | + `supersedes` / `superseded_by`. |
| 107 | +- Files in `architecture/` carry **no** frontmatter — living prose, dated by git. |
| 108 | + |
| 109 | +**`summary`** is one line: written at creation as the intent, then **finalized |
| 110 | +at ship** to state the realized result — what shipped and its effect. It is the |
| 111 | +only field the index renders. |
| 112 | + |
| 113 | +## Index |
| 114 | + |
| 115 | +The listing is **generated**, not maintained — run `just index` to print it: a |
| 116 | +flat, newest-first list of changes, then decisions newest-first. The frontmatter |
| 117 | +in each bundle / decision file is the single source of truth; there is no |
| 118 | +committed copy to drift. |
| 119 | + |
| 120 | +## Other |
| 121 | + |
| 122 | +- **[`architecture/`](../architecture/)** at the repo root — the living |
| 123 | + capability truth. This is the promotion target on every ship. |
| 124 | +- **[decisions/](decisions/)** — design decisions taken (and alternatives |
| 125 | + rejected), each with a revisit trigger, so reviews don't re-litigate them; |
| 126 | + indexed by `just index`. |
| 127 | +- **[specs/](specs/)** — pre-convention design docs retained for history (e.g. |
| 128 | + the FastStream 0.7 migration design). |
0 commit comments