From 7b44a8ad3a007c73c5c89e8b8019150a780e25b4 Mon Sep 17 00:00:00 2001 From: CroneKorkN Date: Sun, 10 May 2026 16:06:25 +0200 Subject: [PATCH] spec/handoff: record per-bundle README pivot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - spec §0 gets a new revision bullet noting that per-bundle docs are README.md (not AGENTS.md), the rigid template is gone, and Phase 2 was dropped. flags §3 and §7 as pre-pivot intent only; doesn't back-fit them. - handoff replaced with a short status note (~50 lines vs the original ~390): what landed, where current truth lives, and the fact that nothing is planned for a next session. implementation plan in ~/.claude/plans/ is left as a frozen pre-pivot artifact. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../2026-05-10-implementation-handoff.md | 448 +++--------------- .../2026-05-10-agent-friendliness-design.md | 13 + 2 files changed, 72 insertions(+), 389 deletions(-) diff --git a/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md b/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md index c619b65..7b2cc1a 100644 --- a/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md +++ b/docs/superpowers/handoffs/2026-05-10-implementation-handoff.md @@ -1,389 +1,59 @@ -# Handoff — implement agent-friendly docs for ckn-bw - -Date written: 2026-05-10. Working directory for the next session: -`/Users/mwiegand/Projekte/ckn-bw`. - -This handoff is self-contained. Read top-to-bottom. Source documents -referenced are tracked in this repo unless noted. - -## Why this work exists - -This BundleWrap config repo (`ckn-bw`, ~22 nodes / 103 bundles) had no -agent-facing orientation: no `CLAUDE.md` / `AGENTS.md`, only ~33 of 103 -bundles have a `README`, and the root `README.md` is the maintainer's -personal TODO list. Agents landing cold spelunked through magic-string -secrets, eval()-loaded node files, vault helpers, lib helpers, and a custom -bundlewrap fork. - -The work over the last few sessions was: brainstorm → spec → plan → fork -work (separate session) → user-story validation → Phase 0 prep → handoff -(this file). The next session implements Phase 1 (PR1 scaffolding) and -Phase 2 (seed bundle docs). - -The maintainer is also using this work as design exploration for a future -agent-friendly config-management tool. Concrete bundlewrap-language -gotchas surfaced here (silent eval-load, magic strings, reactor -namespace-write side effects) inform that future tool's design. - -## Where we are right now (commit checkpoint) - -`git log --oneline` (4 commits ahead of origin/master, none pushed): - -``` -1da7097 README: drop stale 'install bw fork' instruction -3daf70d spec: incorporate fork pivot and bw-syntax corrections -b804350 add user-stories validation doc -7486c78 switch bundlewrap install to editable from CroneKorkN/bundlewrap@main -8ec99db add agent-friendliness design spec ← prior session -``` - -Working tree at handoff: - -``` -?? .claude/ # local Claude settings, leave alone -?? bundles/left4dead2/files/scripts/overlays/test # pre-existing, unrelated, leave alone -``` - -The venv runs **bundlewrap 5.0.3 editable** from -`https://github.com/CroneKorkN/bundlewrap.git@main`, cloned at -`.venv/src/bundlewrap/`. `bw test` passes through the (full-network) -sandbox. - -## Source documents (read in this order) - -1. **Spec** — `docs/superpowers/specs/2026-05-10-agent-friendliness-design.md`. - Section §0 documents revisions; the rest describes target file shapes - in detail. **Treat as source of truth for what each file must contain.** - -2. **User-stories validation** — - `docs/superpowers/specs/2026-05-10-user-stories-from-history.md`. - 21 stories grounded in 1169 commits of git history. Each story's - "Implications for agent docs" section maps to specific content adds - that the plan (below) records as "User-story validation findings." - -3. **Implementation plan** — - `~/.claude/plans/btw-are-you-sure-crystalline-balloon.md`. Contains the - Approach (numbered steps), Workflow validation findings (7 content - adds), User-story validation findings (16 content adds), seed list, - and verification. **Read it.** Lives outside the repo because it was - produced under Claude's plan-mode workflow. - -4. **Fork's `AGENTS.md`** — at - `https://github.com/CroneKorkN/bundlewrap/blob/main/AGENTS.md`. The - canonical bundlewrap-language reference: safety envelope (3 tiers), - after-change runbook, hash-diff workflow, dep-keyword cheat-sheet, - metadata.py pitfalls. ckn-bw's docs link out to it instead of - duplicating. - -## Phase 0 — already done (don't redo) - -✓ `requirements.txt` swapped from `bundlewrap ~=5.0, >=5.0.3` to the -editable github reference. Don't change back. - -✓ User-stories doc added at `docs/superpowers/specs/2026-05-10-user-stories-from-history.md`. - -✓ Spec corrected at `docs/superpowers/specs/2026-05-10-agent-friendliness-design.md`: -fork pivot, slim `commands.md` scope, bw-syntax corrections, seed-list -rebalance, and a new `§0. Revisions` log. Section numbering is unchanged -otherwise. - -✓ Root `README.md` cleaned: stale "install bw fork" section removed. -Personal TODO above and the `# monitor timers` / `# git signing` blocks -below are untouched. - -## Phase 0 — what's left - -**Docstring/header pass on `libs/`, `hooks/`, `bin/`** — partially started -in this session, then reverted to a clean state at user request to land -this handoff. The next session does the whole pass cleanly. - -Spec §5 corollary defines the rule: "Every `libs/*.py` and `hooks/*.py` -starts with a one-line module docstring. Every `bin/*` script starts with -a `# purpose:` header comment." - -Files that need a docstring/header (verified absent at handoff time): - -``` -libs/ — 19 files: apt, bind, derive_string, grafana, hashable, hmac, - ini, ip, local, nextcloud, nginx, postgres, rsa, ssh, systemd, - tools, version, wireguard, wol (all .py) -hooks/ — 5 files: known_hosts, skip_local_nodes, test_ptr_records, - unique_node_ids, wake_on_lan (all .py) -bin/ — 9 scripts: mikrotik-firmware-updater, passwords-for, rcon, - script_template, sync_1password, timestamp_icloud_photos_for_nextcloud, - upgrade_and_restart_all, wake, wireguard-client-config -``` - -For each: read the file, write a concise one-line description capturing -**what it's for**, not how it works. Place the docstring at the very top -of the file (after the shebang, if present), followed by a blank line, -then the existing first line. Example shapes: - -```python -# libs/wireguard.py -"""wireguard: deterministic WireGuard private/public key + PSK derivation backed by repo.vault.""" - -import base64 -... -``` - -```bash -# bin/wake -#!/usr/bin/env python3 -# purpose: wake one node via WoL by name — usage: wake . - -from bundlewrap.repo import Repository -... -``` - -For files with `#!/usr/bin/env python` shebang in `libs/` (only -`derive_string.py` currently), put the docstring on the line immediately -after the shebang. - -For files with a leading comment in `libs/` (only `rsa.py` has the -`# https://stackoverflow.com/a/18266970` link), place the docstring above -that comment so it's still the first statement. - -Commit message style for this pass: `libs/hooks/bin: add one-line module -docstrings and # purpose: headers`. Single commit for the whole pass. - -Use the file headers / function names / surrounding code to derive the -descriptions; don't trust git log alone — terse commit messages won't -explain a lib's purpose. The user-stories doc gives indirect signal for -some (`libs/version.py` was introduced for `bin/mikrotik-firmware-updater`, -etc.). - -## Phase 1 — main scaffolding (PR1) - -The core writing work, ~800–1000 lines total per the plan's scope estimate. - -### Order - -Per plan Approach: - -1. `docs/agents/conventions.md` -2. `docs/agents/commands.md` -3. The 8 per-area `AGENTS.md` files (`bundles/`, `nodes/`, `groups/`, - `libs/`, `hooks/`, `data/`, `items/`, `bin/`) -4. `bundles/AGENTS.template.md` -5. Root `AGENTS.md` (last so all link targets exist) -6. `ln -s AGENTS.md CLAUDE.md` (the symlink) - -Each file's exact target content is in the spec (see paths above). -Augmentations beyond the spec are recorded in the plan as -"Workflow validation findings" (7 items) and "User-story validation -findings" (16 items). Examples of augmentations: - -- `bundles/AGENTS.md` gets a "Before you start" header pointing at - `conventions.md` as required reading (workflow validation §1). -- `nodes/AGENTS.md` gets the silent-eval-load pitfall (user-story §S2), - the `*.py_` suspend convention (§S9), and the rename-failure-mode - pitfall (§S19). -- `conventions.md` gets the suspension idiom ("for now / disable / dummy" - — §S11), the iterative-commit context (§S4), the burst-state awareness - (§S5), and the `_old` soft-delete pattern (§F6). -- Per-bundle template gets an optional `## Writes into` section for - bundles whose reactors write cross-namespace (§S12). - -**Read both validation-findings sections in the plan in full before -starting Phase 1.** They're scoped, file-keyed, and small individually, -but cumulatively they're the difference between "docs that look right" and -"docs that an agent can actually use." - -### Style guardrails - -- One balanced doc per audience boundary. The per-bundle `AGENTS.md` - template (spec §3) is the canonical shape: prose at top, structured - Python dict for metadata schema, optional sections only when useful. -- Mechanism over enumeration. Area docs say *how the area works*, not - *what's currently in it*. Specifics live in self-describing files - (per the docstring rule above). -- No editorializing. Don't write advice; write conventions. -- No comments unless they explain a non-obvious *why*. Same for prose: - short, factual. -- Use the path conventions the spec uses (`docs/agents/...`, not - `docs/agents/...md` repeatedly). Use full URLs to the fork - (`https://github.com/CroneKorkN/bundlewrap/blob/main/AGENTS.md`) so - links work in any rendered context. - -### Verification before committing - -Run all of these (some need network sandbox; sandbox is configured for -full-network access — see "Operating environment" below): - -1. `bw test` — must pass (exit 0). -2. `bw nodes`, `bw groups`, `bw bundles` — repo loaders still work. -3. Internal-link integrity: `grep -oE '\]\([^)]+\.md[^)]*\)' AGENTS.md - docs/agents/**/*.md bundles/AGENTS*.md` then `test -f` each path. -4. `readlink CLAUDE.md` resolves to `AGENTS.md`. -5. `grep -L '"""' libs/*.py hooks/*.py` reports zero files. -6. `grep -L '^# purpose' bin/*` reports zero non-binary scripts. -7. `git grep -i "bw fork\|bundlewrap-fork"` reports only legitimate - fork-as-source references (no leftover stale install instructions). -8. **Workflow walk-through.** Trace the "implement a new bundle" path - end-to-end against the written docs as if you were a fresh agent. - Confirms the workflow-validation fixes actually closed the gaps. - -## Phase 2 — seed bundle docs (PR2) - -Ten bundles, each gets a `bundles//AGENTS.md` from the template. - -| # | Bundle | Existing README? | Notes | -|---|---|---|---| -| 1 | `monitored` | check via `find bundles/ -name README.md` | 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) | -| 5 | `apt` | check | own lib | -| 6 | `nginx` | check | web foundational | -| 7 | `telegraf` | check | high cross-bundle ripple (writes into many namespaces) | -| 8 | `backup` | check | cross-node coordination | -| 9 | `letsencrypt` | check | cross-cutting | -| 10 | `nextcloud` | yes | complex, recent activity | - -For each: derive the **Metadata** section 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 what other bundles' artifacts (apt packages, -systemd services) the bundle's reactors and items reference — use -`ccc search` (cocoindex; index already built at `.cocoindex_code/`) for -cross-bundle lookups when filling this in. - -Where a bundle has an existing `README.md`, fold its content into the new -`AGENTS.md` and remove the old `README.md` in the same commit. Do not -lose information — those READMEs are the only existing human-prose -description for those bundles. - -For bundles whose reactors write into other bundles' namespaces (notably -`telegraf`, `monitored`, `archive`, `wol-waker`, `apt`, `nextcloud`), -fill in the optional `## Writes into` section. - -About 23 other bundles also have a `README.md` (not on the seed list). -Those stay in tree, untouched, until Phase 3 leave-as-you-go folds them. -Document this transition state in `bundles/AGENTS.md` so an agent -reading both isn't confused. - -## Phase 3 — leave-as-you-go convention - -Not a code task. The rule lives in `bundles/AGENTS.md`: any time an agent -or the maintainer materially edits a bundle, top-up or create its -`AGENTS.md`. The remaining ~93 bundles are filled lazily as they're -touched. - -## Decisions captured (do not relitigate) - -- **Doc audience.** One balanced doc per artifact, serving both humans - and agents. No separate `README.md` + `AGENTS.md` split per bundle. -- **Fork hosts bundlewrap-language docs.** Don't duplicate items / metadata - semantics in ckn-bw. Link out. -- **Read-only by default.** Agents do not run `bw apply`, `bw run`, or - `bw lock` autonomously. Never. Even with `-i`. The fork's AGENTS.md - spells this out as Tier 3. -- **No tooling work in this scope.** No `bw` wrapper, no Makefile, no CI, - no lint. The plan and spec both call this out as a non-goal. -- **Per-bundle metadata as Python dict** (not bullet list). Matches how - `metadata.py` actually looks; trailing comments carry type / required / - default. -- **Bundle naming**: lowercase-hyphenated (`bind-acme`, `routeros-monitoring`, - `wol-waker`). Underscores were used in deleted `_old` bundles, none - remain. -- **Node naming**: `..py` (e.g. `home.server.py`, `htz.mails.py`). -- **`*.py_` suspend convention** is real and intentional — never delete. -- **Commit-message style**: lowercase, terse subject; multi-line body - with bullets when relevant; `Co-Authored-By: Claude Opus 4.7 (1M context) - ` trailer when Claude assisted. Look at recent - commits for tone. -- **Don't push without asking.** Local commits only unless the user - explicitly says push. - -## Pitfalls — things that bite - -- **`bw hash` does NOT accept selectors.** Only literal node/group names. - Selectors (`bundle:`, `group:`) work for `bw apply`, `bw run`, - `bw nodes`, but `bw hash` is the exception. To scope to a bundle: - `bw nodes bundle:` to enumerate, then `bw hash ` per result. -- **`bw items -p` is wrong** — the flag doesn't exist. Use - bare form for expected state, `--preview` (`-f`) for rendered file - content, `--attrs` for internal attributes. -- **`bw groups -n ` doesn't exist** — use `bw nodes -a groups`. -- **Sandbox + macOS `localhost` quirk.** If you hit `errno 47 - EAFNOSUPPORT` on a localhost-proxy connection, `/etc/hosts` may have - collapsed `127.0.0.1 localhost` and `::1 localhost` onto malformed - lines. Verify with `python3 -c "import socket; - print(socket.getaddrinfo('localhost', 80, type=socket.SOCK_STREAM))"` — - must include both `('127.0.0.1', 80)` and `('::1', 80, 0, 0)`. (This - was already fixed in this session; documenting in case it regresses.) -- **`bw test` makes outbound HEAD requests** to verify download URLs. - Sandbox needs `allowedDomains: ["*"]` (or equivalent) for it to pass. - Fall back to `dangerouslyDisableSandbox: true` if sandbox network - blocks unexpectedly. -- **Eval-loaded node files.** `nodes/*.py` and `groups/*.py` are - `eval()`'d as Python expressions. No top-level imports allowed. A - syntax error or import causes the loader to silently drop the node - from `bw nodes` (vanilla bundlewrap behavior). The maintainer's - `groups.py` was patched in `dc40295` to print errors — a real foot-gun - to document in `nodes/AGENTS.md`. -- **Don't restore the 9 partially-edited libs from the prior session.** - They were intentionally reverted to give the next session a clean - starting point; redo from scratch using your own judgment + file - contents. - -## Operating environment - -- **Working dir**: `/Users/mwiegand/Projekte/ckn-bw`. -- **venv path**: `.venv/`. `bundlewrap` is editable at `.venv/src/bundlewrap/` - on branch `main`, currently at commit `42dabfc2`. To pull upstream changes: - `(cd .venv/src/bundlewrap && git pull)`. -- **Sandbox**: enabled, `network.allowedDomains: ["*"]`, network passes - after `/etc/hosts` was un-corrupted. `bw test` works under the sandbox. -- **ccc index** at `.cocoindex_code/` — already built (768 chunks, 340 - files). Use `ccc search ""` for semantic codebase exploration. - Particularly useful in Phase 2 for finding what consumes a given - metadata key or imports a given lib. - -## What is intentionally NOT in scope - -Re-listing so the next session doesn't drift: - -- No tooling: no Makefile, no `bw` wrapper, no lint, no CI, no - pre-commit hooks. -- No code refactoring, renaming, or splitting bundles. -- No mass-fill of all 103 bundles' `AGENTS.md` up front. Phase 3 is - leave-as-you-go. -- The root `README.md` (personal TODO) stays as-is now that the stale - fork-install section is gone. Don't add a project-readme on top. -- No upstream contribution to bundlewrap (acknowledged future work, not - this scope). -- No edits to the bundlewrap fork — that's a separate repo. The fork - agent already shipped its `AGENTS.md`. - -## Success criteria - -Phase 0 docstring pass complete + Phase 1 scaffolding done + Phase 2 seed -bundle docs done. Verifiable by: - -- `find . -name 'AGENTS.md' -not -path './.venv/*' -not -path './.git/*'` - lists root, 8 area docs, the per-bundle template, and 10 seed bundle - docs. (~20 files.) -- `readlink CLAUDE.md` → `AGENTS.md`. -- All internal links resolve (verification step 3 above). -- All `libs/*.py`, `hooks/*.py`, `bin/*` self-describe. -- `bw test` passes. -- A fresh agent can trace "implement a new bundle" through root → bundles - → example → write → wire → verify, without spelunking. - -## Quick start for the new session - -If the new session has zero prior context: - -```bash -cd /Users/mwiegand/Projekte/ckn-bw -git log --oneline -5 # see Phase 0 commits -cat docs/superpowers/handoffs/2026-05-10-implementation-handoff.md # this file -cat docs/superpowers/specs/2026-05-10-agent-friendliness-design.md # the spec -cat ~/.claude/plans/btw-are-you-sure-crystalline-balloon.md # the plan -.venv/bin/bw test # confirm baseline still green -``` - -Then start with the docstring pass (Phase 0 remainder), commit, then move -into Phase 1 file-by-file in the order listed above. +# Handoff — agent-friendly docs for ckn-bw (status: complete) + +The 2026-05-10 work is finished. This file replaces the original +multi-page handoff (which described work that's now done plus a +Phase 2 that was dropped). Kept as a breadcrumb so future agents +know what landed. + +## What landed + +- **Phase 0** (`730625e`) — top-of-file docstrings on every + `libs/*.py` and `hooks/*.py`; `# purpose:` headers on every + `bin/*` script. Discovery is `ls + head -1`. +- **Phase 1** (`04558a9`) — root `AGENTS.md` (with `CLAUDE.md` + symlink), `docs/agents/{conventions,commands}.md`, per-area + `AGENTS.md` for `bundles/`, `nodes/`, `groups/`, `libs/`, + `hooks/`, `data/`, `items/`, `bin/`. Mechanism-focused; no + enumeration of contents. +- **Convention pivot** (`9e1bb2a`) — per-bundle docs are plain + `README.md`, not `AGENTS.md`. No template. `bundles/AGENTS.md` + "Per-bundle README" gives loose orientation pointing at the + more substantial existing READMEs. + +`bw test` exit 0 throughout. All internal links in the new docs +resolve. Commits sit on local `master`, none pushed. + +## Where current truth lives + +- Root entry: [`AGENTS.md`](../../../AGENTS.md) (symlinked to + `CLAUDE.md`). +- Repo conventions + bw command deltas: + [`docs/agents/`](../../agents/). +- Per-area docs: `/AGENTS.md` for each top-level dir. +- Per-bundle docs: existing `README.md` files (~33 of them); + guidance in [`bundles/AGENTS.md`](../../../bundles/AGENTS.md). +- Self-describing files: `libs/*.py`, `hooks/*.py`, `bin/*`. + +## Source documents + +- Spec: [`../specs/2026-05-10-agent-friendliness-design.md`](../specs/2026-05-10-agent-friendliness-design.md) + — 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). + +## What's open + +Nothing planned. Per-bundle README updates are reactive — when a +bundle gets materially edited, top up its `README.md` then. The +~33 existing READMEs vary in quality and shape; that's accepted. + +Two minor items the maintainer may want to clean up at some point: + +- The implementation plan and the spec's §3 / §7 still describe + the pre-pivot per-bundle `AGENTS.md` convention. Spec's §0 flags + this; the plan is a frozen artifact and probably stays as-is. +- The original handoff's verification list mentioned `bw bundles`, + which isn't a real bw subcommand. Not user-facing in any current + doc. diff --git a/docs/superpowers/specs/2026-05-10-agent-friendliness-design.md b/docs/superpowers/specs/2026-05-10-agent-friendliness-design.md index c847612..18f8718 100644 --- a/docs/superpowers/specs/2026-05-10-agent-friendliness-design.md +++ b/docs/superpowers/specs/2026-05-10-agent-friendliness-design.md @@ -36,6 +36,19 @@ reading the spec sees the current shape rather than the original intent. `conventions.md`) are recorded in the implementation plan rather than back-fitted into this spec — they're additions to file content, not scope changes. +- **Per-bundle docs are `README.md`, not `AGENTS.md`** (revised + 2026-05-10, after Phase 1 scaffolding landed). The spec originally + specified one balanced `AGENTS.md` per bundle (§3 template) plus a + Phase 2 seed migration that folded existing READMEs into new + AGENTS.md files (§7). After Phase 1 landed, the maintainer flagged + that the rigid template wouldn't survive contact with the existing + READMEs (which range from one-paragraph balanced docs to operational + scratchpads — see `bundles/{flask,dm-crypt,apt,nextcloud}/README.md`). + Resolution: one `README.md` per bundle, no fixed shape, no template; + Phase 2 dropped; existing READMEs stay in place under leave-as-you-go. + Current convention lives in `bundles/AGENTS.md` "Per-bundle README". + **Sections §3 and §7 are no longer authoritative — read them as + pre-pivot intent only.** ## 1. Goals & non-goals