Skip to content

Development workflow

talas9 edited this page Oct 9, 2026 · 2 revisions

Development workflow

How a change gets from an idea to dev, and from dev to users. The authoritative rules are in CONTRIBUTING.md, RELEASING.md and docs/DEVELOPMENT.md; this page connects them.

Tip

Mention the issue in the PR body (Closes #42): the roadmap manager marks it Done when the PR merges into dev.

1. Start from an issue

Every piece of work has an issue. Bugs and accepted features go through the issue forms, which ask for priority, area and a size estimate. A workflow turns the answers into priority:*, size:* and area:* labels and adds status:triage; the maintainer moves it to status:accepted, status:in-progress or status:blocked. Proposals that still need discussion start in Discussions → Ideas and become issues once agreed.

For a design question, write a page from Template: Design note and link it from the issue.

2. Branches

Branch Role
dev The working branch. Pushes run no CI. Force pushes and deletion are blocked.
main What users and the plugin directory install from. Changes only through a pull request from dev; the required dev-only and tests-passed checks gate it; merge commits only.
engine-proto The Rust engine integration branch. Goes to dev by pull request when a phase is done and tested (decision D55).
<type>/<issue#>-<slug> Short-lived branches for a contributor change, for example fix/42-statusline-deadline. Branch from dev, merge back into dev, delete after the merge.

Contributors open pull requests against dev. A pull request to main from anywhere else cannot merge.

3. Make the change

  • Both ports. A change to a hook, skill or model-routing doc lands on the Claude side and on the Codex mirror under plugins/anti-hall/codex/, or the pull request says why one side does not apply.
  • New capability goes into the engine, not into new Node code; the Node hooks get bug fixes only (decision D80). See Architecture.
  • No hardcoding. Engine settings, limits, texts and rules live in plugins/anti-hall/engine/, never in Rust source. See Engine internals.
  • Every feature has a setting in plugins/anti-hall/hooks/lib/settings-schema.js, reachable through /anti-hall:settings.
  • Fail-open. A hook error exits 0 and never wedges a turn; a guard blocks only on a positive match of the dangerous form.
  • Document it. A new hook, skill or setting needs rows in docs/GUIDE.md, llms.txt and the briefing skill; tests/hygiene/docs-coverage.test.js names what is missing.
  • Public repo. No private names, paths or emails in shipped files, other than the author credit.

Adding or changing a guard has its own checklist in CONTRIBUTING.md → Adding or changing a guard; porting a guard to the engine is in DEVELOPMENT.md → Porting a guard to the engine.

4. Test in batches

Run what your change touches while you work, and the full suite once before you push, not after every edit:

node --test tests/hooks/git-guard.test.js            # the files you touched, while working
node --test                                          # the whole plugin suite, once, before pushing
node plugins/anti-hall/hooks/doctor.js --check       # health check of the working copy

For engine changes, the targeted form is cargo nextest run -E 'test(/^<module>::/)' from ah-engine/, and ./test.sh is the full run (see Engine internals). Run one test runner at a time: the suites are heavy and spawn many processes.

Before an engine release the whole dispatcher is also replayed against the Node hooks on a frozen sample of recorded payloads, so a change is judged on real traffic as well as on its unit tests.

Tests never touch the real home directory: anything that spawns a hook or script runs with HOME and USERPROFILE pointed at a temp dir, and hygiene tests enforce it.

Warning

A green local run is not a green CI run. Pushes to dev run no CI. Check the Actions result before calling a release done.

When CI that runs
Pull requests Lean: Node 24, 2 Linux shards and 2 macOS shards
rc-v* and v* tags, pushes to main, weekly (Monday) Full matrix: Linux and macOS, Node 22 and 24, sharded
Nightly (nightly.yml) Gated parity suites and timing benchmarks; one "Nightly test failure" issue on red
PR to main touching docs Strict docs build (pages.yml)

Automation around issues and PRs is described in Repo automation.

5. Commit and open the pull request

  • Conventional messages: type(area): summary, for example fix(hooks): ..., feat(engine): ..., docs: ..., chore(repo): .... Mention the issue (#42).
  • The pull request body says Closes #42, one line per issue.
  • No AI credit lines in commits or in pull request, issue or release text; git-guard blocks them.
  • Never force-push. Never delete branches or data without the maintainer's say-so.
  • Fill in the pull request template honestly; "N/A, because ..." is a fine answer.

6. Dogfooding

anti-hall is developed with anti-hall running, and every anti-hall message in a development session is treated as test output. The maintainer uses a development-only dogfood skill for this; it lives outside plugins/anti-hall/, so it is never installed for users.

  1. Judge every message as it arrives (blocks, advisories, nudges, statusline segments, DevSwarm notices): true positive, false positive (wrong about the facts), noise (right but useless or repeated), or wrong wording. Anything but a true positive is logged with the message text and the fact that contradicts it. Repeats are logged again, because frequency is data.
  2. Check health regularly (hourly, at milestones and before ending a session): engine status and errors, the engine-versus-Node comparison (any check where the engine is weaker than Node is a P0), per-feature success and mistake rates, and leftovers such as stale git locks, leaked daemons or temp-dir growth.
  3. Collect reports from other sessions that run anti-hall on the same machine, asking for misfires with the exact message text.
  4. Fix by check, not by message. Group the open entries per check, confirm the cause from code and data, add a regression test that proves the true-positive case still fires, then fix it in plugin config or logic (or the engine). Entries are marked fixed or won't-fix with a reason; they are never deleted.
  5. Track it on GitHub. A misfire that needs a code fix gets an issue (type:bug and the check's area).

Never disable a guard to get past it: log the misfire and work within it.

7. Release

Contributors normally do not bump versions. The maintainer releases from dev through a pull request to main and then tags; the engine has its own release procedure. See Release runbook.

Home

🗺️ How it works

🛠️ How we work

📄 Templates

🔗 Elsewhere

Clone this wiki locally