bundlewrap/hooks/AGENTS.md
CroneKorkN 70c7175f35
fix(hooks): check mailserver A/PTR records via DNS-over-HTTPS
dig @9.9.9.9 fails in the agent sandbox, which allows no UDP, so bw
test aborted there. The check now asks dns.google over HTTPS and runs
once per bw test instead of once per node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RywMtsL8qXG7GDY3MHq9Uh
2026-10-23 12:27:31 +02:00

63 lines
2.3 KiB
Markdown

# hooks/
## What's here
Repo-level lifecycle hooks. Each `*.py` exports one or more functions
named after the lifecycle event they listen to (`apply_start`,
`node_apply_start`, `node_run_start`, `test`, `test_node`, …). Bw
discovers them by importing each module from `hooks/`.
Discovery is by `ls hooks/` + the one-line docstring at the top of
each file:
```sh
head -1 hooks/*.py
```
## Conventions
- **One-line module docstring.** Every `hooks/*.py` starts with
`"""<name>: <one-line purpose>."""`. Add one when introducing a new
hook; baseline is enforced by `grep -L '"""' hooks/*.py`.
- **Function name = event name.** Bw calls
`apply_start(repo, target, nodes, interactive=False, **kwargs)`,
`node_apply_start(repo, node, interactive, **kwargs)`,
`test(repo, **kwargs)`, etc. Always accept `**kwargs` so future bw
arguments don't break the hook.
- **Test gates use `test` / `test_node`.** Anything that should fail
`bw test` (and therefore CI / pre-apply sanity) goes here; avoid
doing test-style assertions in `apply_start`.
## How to add a hook
1. Pick the lifecycle event (see fork's `AGENTS.md` for the full list).
2. Create `hooks/<name>.py` with the matching function and a
docstring.
3. Run `bw test` once to confirm the hook loads cleanly.
## Pitfalls
- **A hook that errors at import breaks every `bw` invocation** that
fires the hook's lifecycle — including `bw test` itself, which
defeats the obvious diagnostic. Test new hooks in isolation first:
```sh
bw debug -c "import sys; sys.path.insert(0, 'hooks'); import <hookmodule>"
```
Iterate there until the import is clean, then commit.
- **Hooks have access to the full repo (`repo`, `node`, `nodes`).**
Don't make them block on network unless that's the explicit purpose
(e.g. `test_ptr_records.py` resolves via DNS-over-HTTPS, since the
agent sandbox allows no UDP).
- **Order is not guaranteed across hook files.** Two hooks that both
define `apply_start` will both fire; don't assume which runs first.
## See also
- [`docs/agents/conventions.md`](../docs/agents/conventions.md) —
files-not-to-touch, vault rules.
- [`docs/agents/commands.md`](../docs/agents/commands.md) — test
workflow.
- Fork's [`AGENTS.md`](https://github.com/CroneKorkN/bundlewrap/blob/main/AGENTS.md)
— full hook lifecycle and signatures.