diff --git a/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md b/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md index 7b2cc1a..94f0d43 100644 --- a/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md +++ b/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md @@ -40,8 +40,8 @@ resolve. Commits sit on local `master`, none pushed. — read its `§0. Revisions` first; §3 and §7 are now pre-pivot intent only. - User-stories validation: [`../specs/2026-05-10-user-stories-from-history.md`](../specs/2026-05-10-user-stories-from-history.md). -- Implementation plan: `~/.claude/plans/btw-are-you-sure-crystalline-balloon.md` - (frozen pre-pivot artifact, outside the repo). +- Implementation plan: [`../plans/2026-05-10-agent-friendliness-plan.md`](../plans/2026-05-10-agent-friendliness-plan.md) + (frozen pre-pivot artifact; see its top-of-file note). ## What's open diff --git a/docs/superpowers/plans/2026-05-10-agent-friendliness-plan.md b/docs/superpowers/plans/2026-05-10-agent-friendliness-plan.md new file mode 100644 index 0000000..0e234ad --- /dev/null +++ b/docs/superpowers/plans/2026-05-10-agent-friendliness-plan.md @@ -0,0 +1,505 @@ +# Implementation plan — agent-friendliness docs + +> **Note (post-execution):** This plan is a frozen pre-pivot artifact. +> It captures the approach as designed before Phase 1 landed and the +> per-bundle convention pivoted from `AGENTS.md` to `README.md`. +> Sections describing per-bundle `AGENTS.md`, +> `bundles/AGENTS.template.md`, and the Phase-2 seed-bundle migration +> reflect the original intent, not what shipped. For the current +> shape, read the spec's §0 Revisions +> ([`../specs/2026-05-10-agent-friendliness-design.md`](../specs/2026-05-10-agent-friendliness-design.md)) +> and the handoff status note +> ([`../handoffs/2026-05-10-implementation-handoff.md`](../handoffs/2026-05-10-implementation-handoff.md)). +> Kept in tree as a record of how the work was scoped and what +> validation findings (workflow + user-story) shaped Phase 1. + +## Context + +This BundleWrap config repo (`ckn-bw`, ~22 nodes / 103 bundles) currently has +no agent-facing orientation: no `CLAUDE.md` / `AGENTS.md`, only ~10 of 103 +bundles have a `README`, and the root `README.md` is a personal TODO. Agents +landing cold spelunk to figure out conventions (demagify magic strings, +`metadata_reactor` patterns, lib helpers, what's safe to run). + +Goal: ship one PR that scaffolds the documentation surface described in +`docs/superpowers/specs/2026-05-10-agent-friendliness-design.md`, plus a +second PR seeding 10 high-value bundle docs. After this work, an agent can +land useful work in nodes / groups / bundles / libs without trial-and-error, +and never invokes a state-mutating `bw` command without explicit user request. + +**Corrections since the spec was written.** + +- Verification on 2026-05-10 found the active venv ran upstream `bundlewrap 4.24.0`, + the README's fork install was stale, and the user has since upgraded the + venv to PyPI `bundlewrap 5.0.3`. +- The user refreshed `/Users/mwiegand/Projekte/bundlewrap-fork` to track upstream + master at commit `a97cdb13` (also version 5.0.3), and decided to make the + fork agent-friendly *first* (separate session, separate plan), then return + here. The ckn-bw plan therefore drops the `docs/agents/bundlewrap/` folder + it originally planned — bundlewrap-language docs live in the fork now. + +This plan reflects the reduced ckn-bw scope. It is gated on the fork's +`AGENTS.md` existing, since this repo's root `AGENTS.md` links out to it. +See the handoff document delivered separately for the fork-session work. + +## Scope + +Two PRs. + +- **PR1 — scaffolding.** Root `AGENTS.md`, `CLAUDE.md` symlink, the + `docs/agents/` tree (just `conventions.md` and `commands.md` — no + `bundlewrap/` folder; that lives in the fork), all eight per-area + `AGENTS.md` files, the per-bundle template, the docstring/header pass on + `libs/*.py` / `hooks/*.py` / `bin/*`, and the README cleanup (remove the + stale fork section, keep everything else). Spec correction in the same PR. +- **PR2 — seed bundles.** Per-bundle `AGENTS.md` for the 10 seed bundles; + fold and remove any existing per-bundle `README.md` in those. + +Phase 3 from the spec ("leave-as-you-go") is a convention, not a code task — +captured in `bundles/AGENTS.md` as a contribution rule. + +## Approach (recommended) + +### PR1 — scaffolding + +Order is dependency-respecting; each step's output is referenced by later +steps' link targets. + +**Precondition:** the fork's root `AGENTS.md` exists at +`/Users/mwiegand/Projekte/bundlewrap-fork/AGENTS.md`. PR1 links out to it, +so PR1 cannot land cleanly until the fork session has produced that file. + +1. **Spec correction.** In + `docs/superpowers/specs/2026-05-10-agent-friendliness-design.md`: + - Replace "fork" framing with the actual reality: venv runs `bundlewrap + 5.0.3` (PyPI install today), the user maintains a separate fork at + `github.com/CroneKorkN/bundlewrap` whose `master` tracks upstream and + whose `AGENTS.md` is the canonical bundlewrap-language reference. + - Replace the `docs/agents/bundlewrap/` folder content (Section 2 IA, + Section 6) with a single bullet: "bundlewrap-language reference lives + in the fork at `/AGENTS.md`; ckn-bw links to it from root + `AGENTS.md` and `conventions.md`." + - Update Section 4 quickstart and Section 6 `conventions.md` accordingly. + - Single commit before any other ckn-bw docs are written. + +2. **`docs/agents/conventions.md`** (~80–120 lines): demagify magic strings; + bundlewrap version note (`5.0.3`, link to the fork's `AGENTS.md` for + language reference); group inheritance order; node/group naming + conventions; the `eval()` idiom in `nodes.py` / `groups.py` and what + that constrains for editors/agents (no top-level imports, etc.); + do-not-touch file list (`.secrets.cfg*`, `.venv`, `.cache`, + `.bw_debug_history`, `.envrc`). + +3. **`docs/agents/commands.md`** (~30–50 lines, slimmed). The fork's + `AGENTS.md` (at `https://github.com/CroneKorkN/bundlewrap/blob/main/AGENTS.md`) + now carries the canonical bw runbook — tiers, after-change table, + hash-diff workflow, `bw debug` sketch — verified against 5.0.3 source. + This file shrinks to ckn-bw-specific deltas: + - One-line lead pointing at the fork's `AGENTS.md` for the canonical + read-only allowlist + after-change runbook. + - **Apt-key after-change row** (S7 finding): editing + `data/apt/keys/*.{asc,gpg}` → first verify with + `gpg --show-keys ` locally + fingerprint diff against the + expected source. Trial via `bw apply` is the *failure* path (a wrong + key blocks unattended upgrades cluster-wide). Not in the fork's + runbook because it's repo-specific. + - **`*.py_` suspended-node interaction with `bw nodes`**: a node file + ending in `.py_` is silently excluded from the loader; `bw nodes` + won't list it. Document this so an agent doesn't think a node is + missing when it's actually parked. + - **Vault magic-string handling**: never echo decrypted output, even + in `bw debug` exploration. Cross-link to `conventions.md#secrets`. + +4. **Per-area `AGENTS.md`** — eight files, mechanism-focused, no + enumeration. Order: `bundles/`, `nodes/`, `groups/`, `libs/`, `hooks/`, + `data/`, `items/`, `bin/`. Each ~30–80 lines, same five-section shape + from spec Section 5. + +5. **`bundles/AGENTS.template.md`** — the per-bundle template (spec + Section 3 verbatim, with placeholder text in each section). + +6. **Root `AGENTS.md`** — written so all link targets exist. Spec + Section 4, with the "Conventions you must know" first bullet now + pointing at the fork's `AGENTS.md` (canonical bundlewrap language) + instead of an internal `bundlewrap/` folder. Quickstart bullet about + the fork updated to: "bundlewrap reference lives in `` — + read first if new to bundlewrap." Then create `CLAUDE.md` as a symlink: + `ln -s AGENTS.md CLAUDE.md`. + +7. **Docstring/header pass** — for every `libs/*.py` and `hooks/*.py` + without a top-of-file module docstring, add a one-liner. For every + `bin/*` script without a header comment, add a `# purpose: …` line. Do + not touch files that already have one. Mechanical: read each file's + first ~10 lines, decide, edit only if missing. + +8. **Root `README.md` cleanup** — remove the stale "install bw fork" + section (the `pip3 install --editable git+file:///…/bundlewrap-fork…` + block) since the venv runs PyPI 5.0.3. Leave the rest of the README + untouched. + +### PR2 — seed bundles + +For each of the 10 seed bundles, write `bundles//AGENTS.md` from +`bundles/AGENTS.template.md`. Where a bundle already has `README.md`, fold +its content into the new `AGENTS.md` and remove the old `README.md` in the +same commit. + +Seed list (from spec Section 7, validated empirically 2026-05-10): + +| # | Bundle | Existing README? | Notes | +|---|---|---|---| +| 1 | `monitored` | check | meta-bundle, often misunderstood | +| 2 | `postgresql` | check | foundational | +| 3 | `wireguard` | check | own lib + bin script | +| 4 | `routeros-monitoring` | no | most-churned bundle (15 commits / 18mo); replaces `php` per user-story rebalance | +| 5 | `apt` | check | own lib | +| 6 | `nginx` | check | web foundational | +| 7 | `telegraf` | check | high cross-bundle ripple | +| 8 | `backup` | check | cross-node coordination | +| 9 | `letsencrypt` | check | cross-cutting | +| 10 | `nextcloud` | yes (verified) | complex, recent activity | + +For each: derive `Metadata` dict by reading the bundle's `metadata.py` and +running `bw metadata ` to confirm the resolved +shape. Derive `Produces` from `items.py`. Derive `Depends on` by checking +which other bundles' artifacts (apt packages, systemd services) the +bundle's reactors and items reference. Use the ccc index (built 2026-05-10) +for fast cross-bundle lookups when filling `Depends on`. + +## Workflow validation findings (2026-05-10) — content additions + +Traced the "implement a new bundle" workflow against the planned docs. +Natural agent path is root → `bundles/AGENTS.md` → example bundle → write +files → wire to a node → verify. Seven gaps found; six are one-line +additions to `bundles/AGENTS.md`, one is a rewrite of root §6's example +pointers (~8 lines). All low-cost; fold into the corresponding files when +written in PR1. + +1. **`bundles/AGENTS.md` — "Before you start" header.** `conventions.md` + is off the natural path; call it out as required reading at the top, + not just in "see also." This repo's idioms (vault calls in reactors, + `repo.libs.hashable.hashable(...)`, demagify) live there. An agent + who skips it will write subtly wrong code (e.g. dict-in-set + `TypeError`, vault calls in the wrong place). + +2. **Root `AGENTS.md` §6 — use-case keyed example pointers.** Replace the + spec's "small bundle / complex bundle / node file" with one-line + pointers per pattern: vault usage, templated files, cross-bundle + reactor writing, `download` custom item. Pick concrete bundles at write + time (grep for the patterns to find good exemplars). ~8 lines. + +3. **`bundles/AGENTS.md` "How to add" — explicit wiring step.** Add a + numbered step: "(4) Wire to nodes — see `groups/AGENTS.md` for + application-style group wiring or `nodes/AGENTS.md` for direct + attachment via a node's `bundles` list." Currently the wiring step is + implicit; agent has to discover by cross-reading two area docs. + +4. **`bundles/AGENTS.md` Conventions — bundle naming.** One line: + bundle directory names are lowercase with hyphens (e.g. `backup-server`, + `bind-acme`, `dm-crypt`); avoid underscores. Verify the convention by + `ls bundles | grep _` before writing — if the convention is mixed, + document the actual rule. + +5. **`bundles/AGENTS.md` "See also" — items and templates.** Cross-link + to `items/AGENTS.md` (for the `download` custom item and how to write + new custom item types) and to the fork's + `docs/content/guide/item_file_templates.md` (template syntax). Both + are common needs an agent writing a new bundle hits early. + +6. **`bundles/AGENTS.md` — first-thing-to-run after writing.** One-liner + pointing at `commands.md` with the canonical sequence: `bw test` + (sanity) → `bw items ` (do items show up?) → `bw hash ` + (changed as expected?). Saves the agent from hunting the runbook. + +7. **`bundles/AGENTS.template.md` — empty-section guidance.** Add a note + at the top of the template: "For a brand-new bundle without consumers + yet, leave `Depends on` and `Produces` empty or marked TBD; fill in + after the first verify run." + +## User-story validation findings (2026-05-10) — additional content adds + +Empirical user-story extraction from 1169 commits (full history, with +detailed analysis of the last 222 commits / 18 months) is at +`docs/superpowers/specs/2026-05-10-user-stories-from-history.md`. It +identified 21 recurring user stories. Coverage assessment vs the planned +docs: 5 ✅ / 13 ⚠ / 3 ❌. Below are the 16 additional content adds, grouped +by target file. Each is one paragraph or less. The ❌ items shape an +agent's *judgment* (highest value); the ⚠ items shape lookups. + +### Root `AGENTS.md` + +- **F9 — Personal TODO callout.** "Note: `README.md` is the maintainer's + personal scratchpad, not project documentation. Onboarding lives here in + `AGENTS.md`." One sentence in §1 ("What this repo is"). + +### `docs/agents/conventions.md` + +- **S4 ❌ — Iterative-commit workflow style.** "User commits are + iterative checkpoints, not landing-ready snapshots. Terse messages + (`+`, `fix`, `whitespace`, `dowsnt exist`) and successive 'fix' commits + on the same file are normal. Don't rebase WIP without asking. As an + agent, prefer to land complete-feeling commits rather than mimic the + iterative style." +- **S5 ❌ — Burst-state awareness.** "Before writing into a subsystem, + check `git log --since='1 month ago' bundles/` (or `nodes/.py`, + etc.). If it shows ≥10 recent commits, the subsystem is in flux and + your assumptions about its metadata shape may already be stale. Read + the most recent diffs first." +- **S11 ❌ — Suspension idiom ("for now / disable / dummy / offline").** + "Commits with these markers indicate deliberate suspension, not bugs. + If you encounter a stub or commented-out block, check + `git log -- ` for the suspension reason before re-enabling. The + user reverses these manually when ready." +- **F6 — `_old` / `_old2` soft-delete pattern.** "Suffixed-with-`_old` + directories are the user's recovery buffer during big refactors. Don't + delete them without asking, even if they look orphaned." +- **F8 — Branch naming for PRs.** "PRs go through self-hosted + Gitea/Forgejo. Branch names are lowercase-snake_case descriptive + (`debian-13`, `htz.mails_debian_13_squash`, `l4d2_the_next`)." +- **S20 — Bundlewrap version-migration recipe (optional).** "When the + next major bw version lands: read upstream migration guide → grep for + affected reactor patterns → rewrite each → bump `requirements.txt` + last." Captures the pattern from `186d503` (bw 4 → 5). Useful given + the maintainer's tool-design pivot. + +### `docs/agents/commands.md` + +- **S7 — Apt-keys verification.** Add a row to the after-change table: + `data/apt/keys/*.{asc,gpg}` → first check is `gpg --show-keys + ` locally + visual diff against expected fingerprint. Trial + via `bw apply` is the *failure* path (a wrong key blocks unattended + upgrades cluster-wide). +- ~~**S21 — `bw debug` content sketch.**~~ Resolved upstream: the fork's + `AGENTS.md` now carries the canonical `bw debug` content sketch (probes + for `repo.get_node(...).metadata`, `repo.libs.`, `repo.path`). No + ckn-bw addition needed — Approach step 3 already points at the fork. + +### `bundles/AGENTS.md` + +- **S3 — Template recognition.** One paragraph: "Files under + `bundles//files/` are static unless the `file:` item declares + `content_type='mako'` or the file extension triggers templating + (see fork's `docs/content/guide/item_file_templates.md`). To check: + read the matching `file:` entry in `items.py`." +- **S13 — How to remove a bundle.** 5-line section, symmetric to "How + to add": "(1) `git grep ''` to find references in nodes/groups/ + other bundles; (2) remove those references; (3) `rm -rf bundles//`; + (4) `bw test` and `bw nodes` to confirm clean." +- **S18 — README transition state.** "If a bundle has both `README.md` + and `AGENTS.md`, `AGENTS.md` is canonical; the README is being phased + out. ~23 bundle READMEs remain after the seed PR — Phase 3 leave- + as-you-go folds them in over time." + +### `bundles/AGENTS.template.md` + +- **S12 — Optional `## Writes into` section.** Add to template (after + `## Depends on`): "List other namespaces this bundle's `defaults` or + reactors write into (e.g. nextcloud writes into `apt.packages` and + `archive.paths`). Skip section if none — most bundles don't write + cross-namespace, but the ones that do create the highest-blast- + radius surprises." + +### `nodes/AGENTS.md` + +- **S2 — Silent eval-load-failure pitfall.** "Node files are `eval()`'d. + A syntax error or top-level `import` causes the loader to silently + drop the node. If `bw nodes` reports fewer nodes than expected, check + `groups.py` (the user added explicit error printing in commit + `dc40295` after being bitten)." +- **S9 — `*.py_` suspend convention.** "Appending `_` to a node + filename (e.g. `htz.l4d2.py_`) parks it without loading. Used to keep + decommissioned-but-not-deleted node configs in tree." +- **S9 — Symmetric "How to add a node" workflow.** Numbered steps + parallel to `bundles/AGENTS.md` "How to add": (1) create + `nodes/..py` with `eval()`-safe expression syntax, + (2) populate `id`, `hostname`, `groups`, `bundles`, `metadata`, (3) + add to relevant `groups//.py` if group membership is the + attachment point, (4) verify with `bw nodes`, `bw nodes -a groups`, + `bw metadata `. +- **S19 — Node-rename failure mode.** "Renaming a node file renames + the node. Vault entries (via `!password_for:`), `bw hash` + records, and ssh known_hosts associations all key on node name — + search and replace before renaming, or vault lookups silently + return new (wrong) values." + +### `groups/AGENTS.md` + +- **S10 — Family-file pattern.** "OS variants commonly share a + `*-common.py` parent (e.g. `debian-13-common.py` shared by + `debian-13.py` and `debian-13-pve.py`). Use this when introducing + related-but-distinct OS group families." +- **S10/S15 — New-OS-variant recipe.** "To introduce a new OS major: + (1) add `groups/os/debian-N.py` + `debian-N-common.py` parallel to + the existing files (don't edit in place); (2) add + `data/apt/keys/debian-N-*.{asc,gpg}`; (3) bump dependent bundles + that branch on OS string (e.g. `bundles/bind/items.py`); (4) bump + affected nodes' `groups` lists one at a time; (5) delete the old + OS file when no node references it." + +### `data/AGENTS.md` + +- **S7 — Two distinct content models.** "`data/apt/keys/` holds binary + GPG keys consumed by `bundles/apt`; `data/grafana/rows/` holds Python + modules for Mako-templated dashboards. Same directory shape, different + content models — when adding a new data subdir, declare which model + it follows." +- **F4 — `data/` vs `bundles//files/` heuristic.** "If a data asset + is read by exactly one bundle, prefer `bundles//files/`. Use + `data/` for shared/multi-consumer artifacts. Single-instance evidence: + `78a8abc` moved `mikrotik.mib` from data/ into the bundle for this + reason." + +### `hooks/AGENTS.md` + +- **S17 — Broken-hook failure mode.** "A hook that errors at load time + breaks every `bw` command that fires that lifecycle (including + `bw test`, defeating the obvious diagnostic). Test new hooks in + isolation first: `bw debug` then `import sys; sys.path.insert(0, + 'hooks'); import `. Iterate there until the import is + clean." + +### `libs/AGENTS.md` + +- **S16 — Find-consumers snippet.** Add as a one-liner under + Pitfalls: "Before changing a lib's API, find consumers: + `git grep -l 'repo.libs.'`. Lib changes have repo-wide blast + radius — every bundle that imports the lib re-evaluates." + +### `bin/AGENTS.md` + +- **S14 — `bin/script_template`.** "When introducing a new operator + script, start from `bin/script_template` (the user maintains it as + the canonical starter)." + +## Phase 2 seed list rebalance + +User-story analysis (story 5, subsystem-burst evidence) found that 3 of +5 recent burst targets are unseeded. Strongest single swap: + +- **Drop `php`** (8 node refs but ~zero recent commits — usage hub that + doesn't change). Add **`routeros-monitoring`** (15 recent commits, the + most-touched bundle in 18 months; not a dependency hub but high churn). + +Optional second swap (judgment call): + +- **Drop `apt`** (6 refs, has own lib, foundational but stable) and add + **`bootshorn`** (recent burst target, has its own subsystem). Or keep + `apt` for usage-hub coverage and accept that the seed misses bootshorn + — Phase 3 covers it lazily. + +Default this plan to the **single swap** (php → routeros-monitoring); +note `apt → bootshorn` as a second-swap option if the user wants it. + +## Critical files + +**New:** + +- `AGENTS.md` (root) +- `CLAUDE.md` (symlink → `AGENTS.md`) +- `docs/agents/conventions.md` +- `docs/agents/commands.md` +- `bundles/AGENTS.md`, `bundles/AGENTS.template.md` +- `nodes/AGENTS.md`, `groups/AGENTS.md`, `libs/AGENTS.md`, + `hooks/AGENTS.md`, `data/AGENTS.md`, `items/AGENTS.md`, `bin/AGENTS.md` +- `bundles/{monitored,postgresql,wireguard,routeros-monitoring,apt,nginx,telegraf,backup,letsencrypt,nextcloud}/AGENTS.md` + +**Modified:** + +- `docs/superpowers/specs/2026-05-10-agent-friendliness-design.md` (fork → upstream correction). +- `README.md` (remove stale "install bw fork" section). +- `libs/*.py`, `hooks/*.py` (add module docstrings where missing). +- `bin/*` (add `# purpose:` header where missing). + +**Deleted:** + +- `bundles//README.md` for each of the ~10 seed bundles that have one + (content folded into `AGENTS.md`). + +## Existing utilities & assets to reuse + +- **Spec** at `docs/superpowers/specs/2026-05-10-agent-friendliness-design.md` — + the source of truth for what each file contains. Sections 3, 4, 5, 6 of + the spec are nearly copyable into the actual files. +- **User-story validation doc** at + `docs/superpowers/specs/2026-05-10-user-stories-from-history.md` — + 21 stories grounded in git history with concrete commit evidence. + When writing per-bundle docs, look up the relevant story for evidence + of typical changes (e.g. for `nextcloud`, see Story 1 + Story 5 + l4d2-style burst comparison). The "Implications for agent docs" + paragraphs in each story map directly to the additions in §"User- + story validation findings" above. +- **ccc index** built at `.cocoindex_code/` on 2026-05-10 (768 chunks, 340 + files) — useful in PR2 for finding bundles that consume a metadata key + or import a particular lib. +- **Bundlewrap CLI** for verification: `bw metadata `, `bw items `, + `bw test`, `bw hash`. Read-only; safe to run during writing. +- **Existing bundle READMEs** at `bundles/{freescout,influxdb2,dm-crypt,gcloud,flask,nextcloud,build-server,raspberrymatic-cert,letsencrypt,nodejs}/README.md` + (and any others — verify with `find bundles -name README.md`) — content + to fold into the matching `AGENTS.md`. These are the only existing + human-prose source for those bundles; do not lose information when migrating. + +## Verification + +Run after PR1: + +1. `bw test` — repo-level sanity (passes today; should still pass). +2. `bw nodes`, `bw groups`, `bw bundles` — sanity that loaders work after + the docstring/header additions. +3. Check every internal link in `AGENTS.md` and `docs/agents/**.md` + resolves to a real file. A tiny shell loop with `grep -oE '\]\([^)]+\.md[^)]*\)'` + then `test -f` each path. +4. `readlink CLAUDE.md` resolves to `AGENTS.md`. +5. `grep -L '"""' libs/*.py hooks/*.py` reports zero files (every lib/hook + has a module docstring). +6. `grep -L '^# purpose' bin/*` reports zero non-binary scripts. +7. `git grep -i "bw fork\|bundlewrap-fork"` reports only the corrected + docs locations (no leftover fork references in `README.md`). +8. **Workflow walk-through.** Trace the "implement a new bundle" path + end-to-end against the written docs: root → `bundles/AGENTS.md` → + example pointer → can the writer locate vault/hashable/template + guidance from there without spelunking? Confirms the §"Workflow + validation findings" fixes actually closed the gaps. + +Run after PR2: + +1. `bw test` — still green. +2. For each seed bundle ``: pick one node that has it, run + `bw metadata ` and confirm the keys listed in + `bundles//AGENTS.md` `Metadata` section actually appear in the + resolved metadata. Catches drift between docs and reality. +3. `find bundles -name README.md` — confirm none exist for the 10 seed + bundles (folded into `AGENTS.md`). +4. Each new `bundles//AGENTS.md` follows the template structure + (`grep -L '^## Metadata' bundles/*/AGENTS.md` reports zero). + +## Non-goals (re-asserted from spec) + +- No tooling changes (no `bw` wrapper, no Makefile, no lint, no CI). +- No code refactoring, renaming, or splitting bundles. +- No mass-fill of the remaining ~93 bundles up front. +- No upstream contribution to bundlewrap (acknowledged future work). +- The root `README.md` keeps everything except the fork section. + +## Risks & mitigations + +- **Drift between docs and code.** Mitigation: per-bundle docs are short + (low maintenance), the area docs are mechanism-focused (changes less + often than enumerations), and PR2 verification step 2 catches metadata + drift at write time. +- **PR1 is gated on the fork's `AGENTS.md` existing.** If you want to + start ckn-bw work before the fork session lands, you can stub the link + to the fork's `AGENTS.md` (e.g. point at the repo URL even if the file + isn't there yet) and merge PR1, but that risks broken links if the fork + URL or filename changes. Cleaner: do the fork session first, then PR1. +- **PR1 is now a moderate writing chunk** (~800–1000 lines instead of + ~1500–2000), since the bundlewrap folder moved out. Single PR is + comfortable. The user-story validation findings (16 small adds) push + it to ~1000–1200; still manageable as one PR. +- **README undercount.** The plan/spec estimated ~10 existing bundle + READMEs to fold; actual is **33** (verified 2026-05-10 from git + history). The seed list intersects with only 4–5 of those (nextcloud + has one verified; others — `find bundles -name README.md` will + enumerate). PR2 only folds READMEs in seed bundles; ~28 remain + untouched, addressed lazily by Phase 3. `bundles/AGENTS.md` notes + this transition state explicitly (per user-story finding §S18) so + agents reading both don't get confused.