introduces a balanced set of agent + human docs: - root AGENTS.md (with CLAUDE.md symlink) — 5-rule quickstart, layout map, mental model, use-case keyed example pointers. - docs/agents/conventions.md — vault/demagify, eval-loader constraints, group inheritance, naming, do-not-touch list, suspension idioms, working-style notes. - docs/agents/commands.md — repo-specific deltas to the fork's bw runbook (apt-key offline-verify, *.py_ suspended-node visibility, vault-echo rule). - per-area AGENTS.md for bundles/, nodes/, groups/, libs/, hooks/, data/, items/, bin/ — mechanism-focused, no enumeration. - bundles/AGENTS.template.md — per-bundle doc template with optional `## Writes into` section for cross-namespace reactors. bundlewrap-language reference (item types, dep keywords, reactors, runbook, three-tier safety envelope) is not duplicated here; we link out to the fork's AGENTS.md instead. bw test still green. all internal links resolve. Phase 0 invariants preserved (libs/hooks docstrings, bin/* # purpose: headers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.9 KiB
5.9 KiB
bundles/
Before you start
Read docs/agents/conventions.md first
— it covers vault calls, demagify, the repo.libs.<x> helpers, and the
files agents must not modify. Skipping it leads to subtly broken bundles
(vault calls in the wrong place, dict-in-set TypeError because of
unhashable nesting, etc.).
For bundlewrap-language reference (item types, dep keywords,
metadata_reactor, defaults, item-file template syntax) see the fork's
AGENTS.md
and its docs/content/guide/item_file_templates.md.
What's here
103 bundles. Each is a directory bundles/<name>/ containing some of:
bundles/<name>/
├── items.py # the items this bundle creates (files, services, packages, …)
├── metadata.py # `defaults` + `@metadata_reactor` functions
├── files/ # static or templated file payloads referenced from items.py
├── AGENTS.md # this bundle's doc (template at AGENTS.template.md)
└── README.md # legacy; being phased out (see "Documentation transition" below)
Conventions
- Bundle names are lowercase, hyphen-separated:
backup-server,bind-acme,dm-crypt. No underscores in new bundle names — seeconventions.md#naming-conventions. items.pyis plain Python; it producesfiles = {...},pkg_apt = {...},svc_systemd = {...}, etc. dicts at module scope. Cross-item dependencies useneeds/triggers/triggered_by— see the fork'sAGENTS.mdfor the full keyword cheat sheet.metadata.pyusesdefaults = {...}for static seed values and@metadata_reactor.provides(...)for derived values. Reactors are pure functions of(metadata,)— no side effects, no I/O.- Helpers go in
libs/when they're useful to more than one bundle. Don't duplicate logic across bundles. - Custom item types (e.g.
download:) live initems/, not per-bundle.
How to add a new bundle
mkdir bundles/<name>/(lowercase, hyphenated).- Write
items.pyand (if anything is configurable)metadata.py. Userepo.libs.hashable.hashable(...)when you need to nest a dict or set inside a metadata set; raw dicts/sets aren't hashable. - Drop static payloads into
bundles/<name>/files/. For Mako-templated files, declare'content_type': 'mako'on thefile:item — see the fork's item-file-templates guide. - Wire to nodes. Either add an entry to the relevant
groups/<axis>/<x>.py(preferred for shared bundles) or to the node'sbundleslist directly (nodes/AGENTS.md). - Verify, in this order:
bw test— sanity (loaders + reactors).bw items <node>— confirm new items appear on a node that opts in.bw hash <node>— confirm the change is what you expected. Seedocs/agents/commands.mdand the fork's hash-diff workflow.
- Create
bundles/<name>/AGENTS.mdfromAGENTS.template.md. For a brand-new bundle without consumers yet, leaveDepends onandProducesempty or marked TBD; fill them in after the first verify run.
How to remove a bundle
git grep '<name>'innodes/,groups/, and otherbundles/to find references.- Remove those references.
rm -rf bundles/<name>/.bw testandbw nodesto confirm clean.
Pitfalls
metadata.pyis evaluated at load time for every node, every invocation ofbw. Heavy work or I/O slows the whole repo. Keep reactors pure and fast; pre-compute inlibs/if you must.- Static files vs templates.
bundles/<x>/files/<f>is static unless the matchingfile:item declarescontent_type='mako'(or a templating extension triggers it). To check, read the matchingfile:entry initems.py. - Reactors writing across namespaces. Some bundles' reactors write
into other bundles' metadata namespaces (e.g.
nextcloudwrites intoapt.packages,archive.paths). When you change such a bundle, every consumer's metadata changes too. Per-bundle docs declare these in an optional## Writes intosection — read it before assuming the blast radius is local. bw hashdoesn't accept selectors. Usebw hash <node>per literal name; see the fork's runbook.
Documentation transition
This repo is migrating from bundle README.md files to per-bundle
AGENTS.md files (one balanced doc per bundle, agents + humans).
- Where both exist,
AGENTS.mdis canonical; theREADME.mdis being phased out. - ~28 bundle READMEs survive after the seed migration (the seed PR folds in 5–10 of them; the rest are addressed lazily on the next material edit — Phase 3 leave-as-you-go).
- Phase-3 rule: any time you (or any agent) materially edits a bundle,
top-up its
AGENTS.mdor create one fromAGENTS.template.md. If a staleREADME.mdis still around in the bundle, fold it in and remove it in the same commit.
See also
AGENTS.template.md— per-bundle doc template.docs/agents/conventions.md— repo idioms (vault, demagify, naming, do-not-touch list).docs/agents/commands.md— repo-specific command deltas.items/AGENTS.md— custom item types (download:); when to write a new one vs usefile:.libs/AGENTS.md— shared helpers.- Fork's
AGENTS.md— bundlewrap-language reference + safety envelope.