AGENTS.md · git:20261009.ab33e4b · 2026-10-09 · sha256 66468066d7a82257
AGENTS.md git:20261009.ab33e4bA
Immutable. This exact content never changes and is served at /api/v1/blob/66468066d7a82257.
# Apra Fleet - Agent Context
<!-- Generated from CLAUDE.md by `node scripts/sync-agent-docs.mjs` -- do not hand-edit the shared sections below (the tool-specific appendix at the end of this file is exempt). Edit CLAUDE.md and rerun the script. -->
> Beads: run `bd prime --no-memories` first. DB name (`.beads/metadata.json`) is local/gitignored and can differ per clone -- not a sync requirement. If `bd bootstrap` errors "database exists" on a clean clone, retry with `--database <other-name>`.
Read `README.md` in this repo for the full tool reference, installation, member registration, multi-provider setup, git authentication, PM skill commands, and troubleshooting.
## Dev commands
```bash
npm install && npm run build # Build from source
npm test # Unit tests (vitest + apra-fleet-se), wall-clock bounded
npm run build:binary # Build single-executable binary
node dist/index.js install # Dev-mode install
```
Run tests only through `npm test` (`scripts/run-all-tests.mjs`) or the
apra-fleet-se workspace's own `npm test` (`packages/apra-fleet-se/scripts/run-tests.mjs`)
-- both are wall-clock bounded (default 15 minutes per suite, override with
`APRA_TEST_TIMEOUT_MS`) and kill the whole child process tree (not just the
immediate child) on timeout, so a hung suite can never hold a dispatch open
indefinitely. Do not invoke `vitest run` or `node --test` directly for a
tracked task's verification step. `test:slow` in `packages/apra-fleet-se`
is a deliberate exception: it is a manual/regression-playbook lane invoked
directly, not part of the `npm test` chain, so it is intentionally left
unbounded by this rule.
## Conventions
- Branch naming: `feat/<topic>`, `fix/<topic>`, `chore/<topic>`
- Commit style: `<type>(<scope>): <description>` - e.g. `fix(ssh): handle key rotation timeout`
- Never push to `main` directly; open a PR
- See [Architecture](docs/architecture.md) for internal structure
- ASCII only: never write non-ASCII characters to any file. Use `-` for dashes, `->` for arrows, `[OK]` for checkmarks, etc.
- Permission blocks must be surfaced, not routed around: if a tool or git invocation is blocked by the permission layer, stop and report the block to the user/orchestrator. Do not author a wrapper script, alternate binary, or other workaround whose purpose is to bypass the block, even if the underlying operation is judged safe.
- `packages/apra-fleet-client` must always be updated to catch up with any changes to the fleet MCP tools (`src/tools/*` schemas/behavior) in the same change -- it is the thin client wrapper other packages (fleet-sprint, apra-pm, workflows) use to call those tools, and a drifted client silently gives callers a stale or inconsistent view of what the server actually accepts/does. This is not optional cleanup; treat it as part of the tool change itself.
- Any change to the memory subsystem (its tools, schemas, or bindings) must land together with the corresponding `memory-contract/v1` spec, schema, and conformance updates in the same change -- not as a separate follow-up cleanup -- because a drifted contract silently misrepresents what the server actually accepts and does.
- Never rely on shell-level variable expansion in a member-bound command string ($VAR/path, ~/, backticks) -- the target member's shell may be PowerShell, not POSIX. Resolve paths in JavaScript before building the command using `probeCommandFor(targetOs, shell)` (src/services/member-home.ts) or branching on the member's OS/shell via `isPosixShell(agentOs, shell)` (src/providers/claude.ts). Wrap PowerShell commands explicitly (powershell -EncodedCommand, per src/os/windows.ts) rather than assuming the member's shell. A POSIX-only feature must hard-fail on Windows or gate with a surfaced error -- an advisory warning that never blocks is a false success.
- Never cite a bead id (apra-fleet-XXXX) in any LLM-facing text: prompts, playbooks, schema descriptions, or strings a script prints/writes at runtime. Bead ids are fine only in code comments and docs/.
- The fleet-sprint engine (`packages/apra-fleet-se/fleet-sprint/**` plus the role prompts in `packages/apra-fleet-se/apra-pm/agents/**`) is a GENERIC product that runs sprints for any target repo; apra-fleet building itself with it is the build method, not the product scope. LLM-facing text there (prompt strings, role-prompt markdown) must never assume the target is apra-fleet -- its build commands, env vars, ports, repo layout, bead ids, or deploy.md/playbook sections beyond the documented contract. Target-specific content belongs in the target's own deploy.md/playbooks/CLAUDE.md. Enforced by `packages/apra-fleet-se/scripts/check-generic-boundary.mjs` (part of `npm test`); rule and exception mechanism in docs/generic-engine-boundary.md.
## Fix the product, not the environment
Learn from every failure and misbehaviour by improving the PRODUCT, never by
patching the environment it runs in. We are not building a cradle for a baby;
we are maturing the baby into a strong adult. Thousands of people are meant to
run this software on machines we will never see.
- A manual intervention repeated is a product requirement that was not
escalated. Its second occurrence stops being a workaround and becomes scoped
product work, ranked against current work rather than deferred behind it.
- When reporting a failure, the deliverable is the generic fix, not the local
recovery you performed to keep things moving.
- No fix may depend on a line in this file, an agent's memory, or operator
tribal knowledge. If a user without those would hit the same trap, it is not
fixed -- writing the workaround down protects one operator and leaves every
other user in the trap.
- `human` is an acceptable fallback only where a human genuinely must decide.
Everywhere else it is an unshipped feature.
- Watch for the recurring shape: implicit environment decides behaviour and
failure is silent. The answer is explicit configuration plus loud failure,
in the engine.
## DeepWiki
Always use DeepWiki (MCP server `https://mcp.deepwiki.com/mcp`) while exploring this codebase -- prefer it over cold file reads for architecture/unfamiliar-component questions:
- `mcp__deepwiki__read_wiki_structure(repo)` -- architecture map; call first when starting on an unfamiliar area
- `mcp__deepwiki__read_wiki_contents(repo, topic)` -- a specific doc topic
- `mcp__deepwiki__ask_question(repo, question)` -- faster than local grep for understanding a component
`repo` format: `owner/repo`. Use `Apra-Labs/apra-fleet` for this repo; also useful for related repos this project depends on: `Apra-Labs/apra-pm`, `gastownhall/beads`, `Apra-Labs/fleet-e2e-toy`. To claim what a *specific script does*, read the script -- DeepWiki is for architecture/orientation, not a substitute for reading code you're about to modify.
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:970c3bf2 -->
## Beads Issue Tracker
This project uses **bd (beads)** for issue tracking. Run `bd prime --no-memories` to see full workflow context and commands.
### Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
bd prime --no-memories # Refresh Beads context
```
### Rules
- Use `bd` for ALL task tracking - do NOT use TodoWrite, TaskCreate, or markdown TODO lists
- Run `bd prime --no-memories` for detailed command reference and session close protocol
- Use `bd remember` for persistent knowledge - do NOT use MEMORY.md files
- Operational memories are role-scoped: see "Role-scoped operational memories" below this block.
**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
### Persistent Memory - Which System
Three memory systems exist; when asked to "remember" something, route by content:
- **User/assistant preferences** (user's role, standing feedback on how the assistant collaborates, anything not about this repo's code) -> Claude's own auto-memory (`~/.claude/projects/.../memory/`). Not managed by this repo; named here only so it is not confused with the two below.
- **Operational rules** (short, actionable directives for any dispatched agent during this project's beads-tracked work - test-harness gotchas, required flags, launch conventions) -> `bd remember`. Keep entries terse: the actionable rule only, no PR/bead/commit-ref padding. Keys are role-scoped: see "Role-scoped operational memories" below this block.
- **Technical facts about the codebase** (architecture decisions, gotchas, "why is it built this way" - tied to specific files/symbols, worth confidence-grading and contradiction-checking, shareable via `kb_export` to `.fleet/kb-canonical.json`) -> KB (`kb_capture`).
When a rule is both operational and technical: prefer KB if it anchors to specific files/symbols and benefits from confidence-grading over time; prefer `bd remember` if it is a procedural directive with no file/symbol anchor.
KB is opt-in per repo. If `kb_capture`/`kb_query` errors because `kb_setup` has not run here, do not treat it as a hard failure or drop the memory - fall back to `bd remember` (or tell the user) so the request still lands.
## Agent Context Profiles
The managed Beads block is task-tracking guidance, not permission to override repository, user, or orchestrator instructions.
- **Conservative (default)**: Use `bd` for task tracking. Do not run git commits, git pushes, or Dolt remote sync unless explicitly asked. At handoff, report changed files, validation, and suggested next commands.
- **Minimal**: Keep tool instruction files as pointers to `bd prime --no-memories`; use the same conservative git policy unless active instructions say otherwise.
- **Team-maintainer**: Only when the repository explicitly opts in, agents may close beads, run quality gates, commit, and push as part of session close. A current "do not commit" or "do not push" instruction still wins.
## Session Completion
This protocol applies when ending a Beads implementation workflow. It is subordinate to explicit user, repository, and orchestrator instructions.
1. **File issues for remaining work** - Create beads for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **Handle git/sync by active profile**:
```bash
# Conservative/minimal/default: report status and proposed commands; wait for approval.
git status
# Team-maintainer opt-in only, unless current instructions forbid it:
git pull --rebase
bd dolt push
git push
git status
```
5. **Hand off** - Summarize changes, validation, issue status, and any blocked sync/commit/push step
**Critical rules:**
- Explicit user or orchestrator instructions override this Beads block.
- Do not commit or push without clear authority from the active profile or the current user request.
- If a required sync or push is blocked, stop and report the exact command and error.
<!-- END BEADS INTEGRATION -->
## Role-scoped operational memories
Kept outside the bd-managed block above so `bd setup` cannot drop it. Every `bd remember` key is role-scoped -- wrap each role token in `+` on both sides, then `:<slug>`:
- universal (every role): `+all+:<slug>`, e.g. `bd remember --key "+all+:multi-llm-providers" "..."`
- one role: `+<role>+:<slug>`, e.g. `+orchestrator+:sprint-launch-via-supervisor-api`
- several roles: `+<role1>+<role2>+:<slug>`, e.g. `+doer+reviewer+:secret-placeholder-syntax`
- roles: `planner`, `plan-reviewer`, `doer`, `reviewer`, `deployer`, `integ-test-runner`, `regression-test-runner`, `harvester`, `ci-watcher`, `groomer`, `orchestrator`.
- Never write an unscoped key or a one-sided prefix (`reviewer:`). `node packages/apra-fleet-se/scripts/rekey-beads-memories.mjs` re-keys older `role:all:`/`<role>:` keys.
Readers: `bd prime --no-memories` injects no memories. Dispatched roles run `bd memories --json +all+` plus `bd memories --json +<role>+` from their role prompt and apply only entries whose key carries their token (`bd memories` is a case-insensitive substring search over keys and values; the `+` on both sides keeps `+reviewer+` from matching `+plan-reviewer+`; text output truncates long values, `--json` returns them in full). Interactive/orchestrator Claude Code sessions get `+all+` and `+orchestrator+` in full from the SessionStart/PreCompact hook `node scripts/beads-session-memories.mjs +all+ +orchestrator+` in `.claude/settings.json`; an interactive session in a tool without that hook runs the same command itself at session start.
<!-- gitnexus:start -->
# GitNexus -- Code Intelligence
This project is indexed by GitNexus as **apra-fleet** (12888 symbols, 30673 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
> Index stale? Run `node .gitnexus/run.cjs analyze` from the project root -- it auto-selects an available runner. No `.gitnexus/run.cjs` yet? `npx gitnexus analyze` (npm 11 crash -> `npm i -g gitnexus`; #1939).
## Always Do
- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
- **MUST run `detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: `detect_changes({scope: "compare", base_ref: "main"})`.
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
- When exploring unfamiliar code, use `query({search_query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
- When you need full context on a specific symbol -- callers, callees, which execution flows it participates in -- use `context({name: "symbolName"})`.
- For security review, `explain({target: "fileOrSymbol"})` lists taint findings (source->sink flows; needs `analyze --pdg`).
## Never Do
- NEVER edit a function, class, or method without first running `impact` on it.
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
- NEVER rename symbols with find-and-replace -- use `rename` which understands the call graph.
- NEVER commit changes without running `detect_changes()` to check affected scope.
## Resources
| Resource | Use for |
|----------|---------|
| `gitnexus://repo/apra-fleet/context` | Codebase overview, check index freshness |
| `gitnexus://repo/apra-fleet/clusters` | All functional areas |
| `gitnexus://repo/apra-fleet/processes` | All execution flows |
| `gitnexus://repo/apra-fleet/process/{name}` | Step-by-step execution trace |
## CLI
| Task | Read this skill file |
|------|---------------------|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
<!-- gitnexus:end -->
<!-- BEGIN BEADS CODEX SETUP: generated by bd setup codex -->
## Beads Issue Tracker
Use Beads (`bd`) for durable task tracking in repositories that include it. Use the `beads` skill at `.agents/skills/beads/SKILL.md` (project install) or `~/.agents/skills/beads/SKILL.md` (global install) for Beads workflow guidance, then use the `bd` CLI for issue operations.
### Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
bd prime --no-memories # Refresh Beads context
```
### Rules
- Use `bd` for all task tracking; do not create markdown TODO lists.
- Run `bd prime --no-memories` when Beads context is missing or stale. Codex 0.129.0+ can load Beads context automatically through native hooks; use `/hooks` to inspect or toggle them.
- Keep persistent project memory in Beads via `bd remember`; do not create ad hoc memory files.
- Operational memories are role-scoped: see "Role-scoped operational memories" above.
**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
<!-- END BEADS CODEX SETUP -->