Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ BaseBootstrapper (abc.ABC)

### Key design decisions

Recent design context, bugs, and convention rationale: see the bug-audit findings in `planning/audits/` and the post-work reflections in `planning/retros/` (the audit arcs themselves are bundled under `planning/changes/archive/`).
Recent design context, bugs, and convention rationale: see the bug-audit findings in `planning/audits/` and the post-work reflections in `planning/retros/` (the audit arcs themselves are bundled under `planning/changes/`).

- **Optional dependencies**: Each instrument checks for its optional package via `import_checker.py` (`importlib.util.find_spec`). Instruments are skipped silently if the package is absent. Optional packages are imported inside `if import_checker.is_X_installed:` blocks; static analyzers that don't model this guard will report spurious "possibly unbound" diagnostics — the project uses `ty` which handles the pattern correctly.
- **Instrument skip ordering**: `BaseBootstrapper.__init__` runs `instrument_type.is_configured(config)` first (silent skip if the user's config indicates the instrument shouldn't run — populates `bootstrapper.skipped_instruments: list[tuple[type, str]]`); then `check_dependencies()` (emits `InstrumentDependencyMissingWarning` only for configured-but-dep-missing — the genuine deployment surprise); then instantiates. One `logger.info` summary line at the end lists configured + skipped instruments via `BaseBootstrapper.build_summary()`; that method is also publicly callable for post-construction debugging. Uses stdlib `logging` so it composes cleanly with the user's logging setup and with pytest's `caplog`.
Expand All @@ -63,13 +63,13 @@ See `[project.optional-dependencies]` in `pyproject.toml` for the full extras ma

## Workflow

Per-feature: brainstorming → spec in `planning/changes/active/YYYY-MM-DD.NN-<slug>/design.md` → writing-plans → plan in `planning/changes/active/YYYY-MM-DD.NN-<slug>/plan.md` → executing-plans / subagent-driven-development → requesting-code-review → finishing-a-development-branch. Each change is a folder bundle; `<slug>` is a kebab-case description, not a story ID; `.NN` is a zero-padded intra-day counter that breaks same-date ties so the timeline sorts stably. On merge, the bundle moves to `planning/changes/archive/` with `status: shipped`, `pr:`, and `outcome:` filled, **and the change promotes its conclusions into the affected `architecture/<capability>.md`** — that hand-edit is what keeps `architecture/` true. See [`planning/README.md`](planning/README.md) for the conventions + index and [`planning/_templates/`](planning/_templates/) for copy-and-fill starting points.
Per-feature: brainstorming → spec in `planning/changes/YYYY-MM-DD.NN-<slug>/design.md` → writing-plans → plan in `planning/changes/YYYY-MM-DD.NN-<slug>/plan.md` → executing-plans / subagent-driven-development → requesting-code-review → finishing-a-development-branch. Each change is a folder bundle; `<slug>` is a kebab-case description, not a story ID; `.NN` is a zero-padded intra-day counter that breaks same-date ties so the timeline sorts stably. The implementing PR sets `status: shipped` and fills `pr` / `outcome` in the branch, alongside the code and promotes its conclusions into the affected `architecture/<capability>.md` — that hand-edit keeps `architecture/` true and is the only ship-time step; there is no folder move. The change listing is generated — run `just index`. See [`planning/README.md`](planning/README.md) for the conventions and [`planning/_templates/`](planning/_templates/) for copy-and-fill starting points.

**Spec** (`design.md`) captures the *thinking* — why, what the design is, trade-offs, scope. Written before code; rarely revised after merge. **Plan** (`plan.md`) captures the *sequencing* — the ordered checklist an executor walks; references the spec for the "why". **`architecture/`** captures the *invariants* of shipped systems — the living truth, promoted from a change on merge. A plan paragraph that would still read correctly with all task numbers and checkboxes removed is design content and belongs in the spec.
**Spec** (`design.md`) captures the *thinking* — why, what the design is, trade-offs, scope. Written before code; rarely revised after merge. **Plan** (`plan.md`) captures the *sequencing* — the ordered checklist an executor walks; references the spec for the "why". **`architecture/`** captures the *invariants* of shipped systems — the living truth, promoted in the implementing PR alongside the code. A plan paragraph that would still read correctly with all task numbers and checkboxes removed is design content and belongs in the spec.

**Three lanes.** Scale the artifact to the change. **Full** — a `design.md` + `plan.md` bundle — for real design judgment, a new file/module, a public-API change, cross-cutting/multi-file work, or non-trivial test design. **Lightweight** — a single `change.md` — for small-but-real changes (≲30 LOC net, ≤2 files, no new file, no public-API change, a single straightforward test). **Tiny** — no bundle, just a conventional commit — for a typo, dep bump, linter/formatter/CI tweak, a mechanical rename, or a single-line config change. Heavier lane wins on ambiguity; a `change.md` that outgrows its lane splits into `design.md` + `plan.md`.

Design docs and implementation plans live under `planning/` (not under `docs/`, so they're excluded from the mkdocs site automatically). When superpowers skills default to `docs/superpowers/specs/` or `docs/superpowers/plans/`, use the change bundle under `planning/changes/active/` here instead.
Design docs and implementation plans live under `planning/` (not under `docs/`, so they're excluded from the mkdocs site automatically). When superpowers skills default to `docs/superpowers/specs/` or `docs/superpowers/plans/`, use the change bundle under `planning/changes/` here instead.

## Code style

Expand Down
4 changes: 4 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ lint-ci:
uv run ruff check --no-fix
uv run ty check

# Print the planning change index (grouped by status) to stdout.
index:
uv run python planning/index.py

test *args:
uv run --no-sync pytest {{ args }}

Expand Down
66 changes: 20 additions & 46 deletions planning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,35 @@ at the repo root; this directory records *how it got there*.
## Conventions

> This section is the portable convention — identical across the
> modern-python repos. The Index below is repo-specific. To adopt elsewhere,
> modern-python repos. The generated change listing (`just index`) and the `## Other` pointers below are repo-local. To adopt elsewhere,
> copy this section plus [`_templates/`](_templates/) and point that repo's
> `CLAUDE.md` Workflow + truth home at it.

### Two axes, never mixed

- **`architecture/` (repo root) — the present.** One file per capability,
living prose, updated whenever a change ships. The truth home.
living prose, updated in the same PR that ships the change. The truth home.
- **`planning/changes/` — the past-and-pending.** One folder per change,
frozen once shipped.
kept in place after ship.

Shipping a change **promotes** its conclusions into the affected
`architecture/<capability>.md` by hand, then archives the bundle. That
hand-edit is what keeps `architecture/` true; the archived bundle carries the
*why*.
A change **promotes** its conclusions into the affected
`architecture/<capability>.md` by hand **in the implementing PR, alongside the
code** — the edit rides in the same diff and is reviewed with it, never applied
as a separate post-merge step. That hand-edit is what keeps `architecture/`
true; the bundle stays in `changes/` as the *why*.

### Change bundles

A change is a folder `changes/active/YYYY-MM-DD.NN-<slug>/`:
A change is a folder `changes/YYYY-MM-DD.NN-<slug>/`:

- `YYYY-MM-DD` — proposal date; `.NN` — zero-padded intra-day counter
(`.01`, `.02`, …) that breaks same-date ties so the timeline sorts stably.
- `<slug>` — kebab-case description, not a story ID.

On merge the folder moves to `changes/archive/` with `status: shipped`, `pr:`,
and `outcome:` filled, and its line moves from **Active** to **Archived** in
the Index below.
`summary` is written when the change is created (it is the change's
one-liner). The implementing PR then sets `status: shipped` and fills `pr`
and `outcome` **in the branch**, alongside the code and the `architecture/`
promotion — no post-merge bookkeeping, no folder move.

### Three lanes

Expand Down Expand Up @@ -62,44 +64,16 @@ Templates live in [`_templates/`](_templates/).
### Frontmatter

`design.md` / `change.md`: `status` (draft|approved|shipped|superseded),
`date`, `slug`, `supersedes`, `superseded_by`, `pr`, `outcome`.
`plan.md`: `status`, `date`, `slug`, `spec`, `pr`. Files in `architecture/`
carry **no** frontmatter — living prose, dated by git.
`date`, `slug`, `summary` (single line), `supersedes`, `superseded_by`, `pr`,
`outcome`. `plan.md`: `status`, `date`, `slug`, `spec`, `pr`. Files in
`architecture/` carry **no** frontmatter — living prose, dated by git.

## Index

### Active

_None._

### Archived (shipped)

- **[portable-planning-convention](changes/archive/2026-06-13.01-portable-planning-convention/design.md)**
(#120, 2026-06-13) — Adopt the portable two-axis convention: `architecture/`
truth home + `changes/` bundles, per-arc bundling of the audit arcs, fresh
Index.
- **[mkdocs-github-pages](changes/archive/2026-06-09.01-mkdocs-github-pages/design.md)**
(#112–#115, 2026-06-09) — Docs hosting moved from Read the Docs to GitHub
Actions + Pages.
- **[bug-audit-v2](changes/archive/2026-06-05.01-bug-audit-v2/design.md)**
(#108–#110, 2026-06-05) — 26 findings (UX · logic · security · tests) shipped
across three themed PRs.
- **[deferred-refactors](changes/archive/2026-06-01.03-deferred-refactors/design.md)**
(#96–#103, 2026-06-01) — The 20 deferred items from the 2026-05-31 audit
(REF/TEST/LOW) across eight PRs.
- **[fastmcp-bootstrapper](changes/archive/2026-06-01.02-fastmcp-bootstrapper/design.md)**
(2026-06-01) — New `FastMcpBootstrapper` mirroring microbootstrap's fastmcp
support.
- **[instrument-skip-rework](changes/archive/2026-06-01.01-instrument-skip-rework/design.md)**
(2026-06-01) — Replace `InstrumentNotReadyWarning` with a pre-instantiation
config check + summary log. *Partially superseded by
[stdlib-logging-and-build-summary](changes/archive/2026-06-02.01-stdlib-logging-and-build-summary/design.md).*
- **[stdlib-logging-and-build-summary](changes/archive/2026-06-02.01-stdlib-logging-and-build-summary/design.md)**
(#107, 2026-06-02) — Stdlib `logging` in `bootstrappers/base.py` + public
`build_summary()`.
- **[audit-implementation](changes/archive/2026-05-31.01-audit-implementation/design.md)**
(#89–#95, 2026-05-31) — Criticals (CRIT-1..3) + design issues (DES-1..5) +
paired tests across seven sequenced PRs.
The change listing is **generated**, not maintained — run `just index` to
print it (grouped by `status`: In progress / Shipped / Superseded). The
frontmatter in each bundle is the single source of truth; there is no
committed copy to drift.

## Other

Expand Down
1 change: 1 addition & 0 deletions planning/_templates/change.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: draft
date: YYYY-MM-DD
slug: my-change
summary: One line — shown in the generated index. Fill at ship time.
supersedes: null
superseded_by: null
pr: null
Expand Down
1 change: 1 addition & 0 deletions planning/_templates/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: draft
date: YYYY-MM-DD
slug: my-change
summary: One line — shown in the generated index. Fill at ship time.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-05-31
slug: audit-implementation
summary: Criticals (CRIT-1..3) + design issues (DES-1..5) + paired tests across seven sequenced PRs.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-01
slug: instrument-skip-rework
summary: Replace `InstrumentNotReadyWarning` with a pre-instantiation config check + summary log.
supersedes: null
superseded_by: stdlib-logging-and-build-summary
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-01
slug: fastmcp-bootstrapper
summary: New `FastMcpBootstrapper` mirroring microbootstrap's fastmcp support.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-01
slug: deferred-refactors
summary: The 20 deferred items from the 2026-05-31 audit (REF/TEST/LOW) across eight PRs.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-02
slug: stdlib-logging-and-build-summary
summary: Stdlib `logging` in `bootstrappers/base.py` + public `build_summary()`.
supersedes: instrument-skip-rework
superseded_by: null
pr: "107"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-05
slug: bug-audit-v2
summary: 26 findings (UX · logic · security · tests) shipped across three themed PRs.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-09
slug: mkdocs-github-pages
summary: Docs hosting moved from Read the Docs to GitHub Actions + Pages.
supersedes: null
superseded_by: null
pr: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
status: shipped
date: 2026-06-13
slug: portable-planning-convention
summary: Adopt the portable two-axis convention: `architecture/` truth home + `changes/` bundles, per-arc bundling of the audit arcs, fresh Index.
supersedes: null
superseded_by: null
pr: "120"
Expand Down
Loading