@naxodev/apnea 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTEXT.md +61 -0
- package/CONTRIBUTING.md +21 -0
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/SECURITY.md +35 -0
- package/briefs/coder.md +40 -0
- package/briefs/orchestrator.md +49 -0
- package/briefs/planner.md +54 -0
- package/briefs/reviewer.md +40 -0
- package/dist/cli.js +39397 -0
- package/docs/adr/0001-completion-signaling.md +3 -0
- package/docs/adr/0002-orchestrator-authority.md +3 -0
- package/docs/adr/0003-verify-at-gate.md +3 -0
- package/docs/adr/0004-artifact-layout-and-naming.md +3 -0
- package/docs/adr/0005-harness-profiles.md +5 -0
- package/docs/adr/0006-config-trust-model.md +3 -0
- package/docs/adr/0007-jj-first-commits.md +3 -0
- package/docs/adr/0008-effect-v4-internals.md +3 -0
- package/docs/adr/0009-cli-driver-split.md +9 -0
- package/docs/adr/0010-package-split.md +23 -0
- package/docs/protocol/artifacts.md +68 -0
- package/docs/protocol/config.md +186 -0
- package/docs/protocol/manual-gate.md +38 -0
- package/docs/protocol/overview.md +96 -0
- package/extension/adapters/commit.ts +15 -0
- package/extension/adapters/dispatch.ts +15 -0
- package/extension/adapters/setup.ts +34 -0
- package/extension/adapters/start.ts +16 -0
- package/extension/adapters/status.ts +24 -0
- package/extension/adapters/wait.ts +20 -0
- package/extension/api.ts +16 -0
- package/extension/cli/format.ts +44 -0
- package/extension/cli/human-gate.ts +44 -0
- package/extension/cli/main.ts +218 -0
- package/extension/cli/parse.ts +48 -0
- package/extension/domain/artifact-kind.ts +26 -0
- package/extension/domain/frontmatter.ts +69 -0
- package/extension/domain/herdr.ts +109 -0
- package/extension/domain/paths.ts +139 -0
- package/extension/domain/recovery.ts +25 -0
- package/extension/domain/rounds.ts +16 -0
- package/extension/domain/setup.ts +158 -0
- package/extension/domain/slug.ts +9 -0
- package/extension/domain/state-machine.ts +132 -0
- package/extension/domain/timeouts.ts +24 -0
- package/extension/domain/types.ts +145 -0
- package/extension/domain/verify-commands.ts +128 -0
- package/extension/errors.ts +247 -0
- package/extension/host-adapter.ts +8 -0
- package/extension/registry.ts +323 -0
- package/extension/result.ts +55 -0
- package/extension/run-tool.ts +43 -0
- package/extension/schema/config.ts +315 -0
- package/extension/schema/frontmatter.ts +34 -0
- package/extension/schema/state.ts +119 -0
- package/extension/services/app-live.ts +24 -0
- package/extension/services/config.ts +103 -0
- package/extension/services/file-system.ts +178 -0
- package/extension/services/herdr.ts +860 -0
- package/extension/services/run-store.ts +99 -0
- package/extension/services/vcs.ts +246 -0
- package/extension/workflows/commit.ts +148 -0
- package/extension/workflows/dispatch.ts +693 -0
- package/extension/workflows/reset.ts +26 -0
- package/extension/workflows/setup.ts +301 -0
- package/extension/workflows/start.ts +149 -0
- package/extension/workflows/status.ts +45 -0
- package/extension/workflows/wait.ts +793 -0
- package/herdr-plugin/herdr-plugin.toml +15 -0
- package/herdr-plugin/scripts/run-task.sh +8 -0
- package/package.json +75 -0
- package/schemas/artifact-frontmatter.md +38 -0
- package/schemas/config.schema.json +50 -0
- package/schemas/state.schema.json +63 -0
package/CONTEXT.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Apnea
|
|
2
|
+
|
|
3
|
+
A host-neutral package that runs a multi-role development workflow inside Herdr panes, using file-backed handoffs instead of hidden subagents.
|
|
4
|
+
|
|
5
|
+
## Language
|
|
6
|
+
|
|
7
|
+
**Run**:
|
|
8
|
+
One user goal executed end-to-end until a PR description artifact exists.
|
|
9
|
+
_Avoid_: Session, job, workflow instance
|
|
10
|
+
|
|
11
|
+
**Phase**:
|
|
12
|
+
A planner-owned vertical slice of the goal with acceptance checks and verify commands.
|
|
13
|
+
_Avoid_: Step, ticket, task (when meaning the slice)
|
|
14
|
+
|
|
15
|
+
**Phase package**:
|
|
16
|
+
The written contract that bounds one phase for the coder (files, steps, checks, non-goals).
|
|
17
|
+
_Avoid_: Spec, ticket body, prompt
|
|
18
|
+
|
|
19
|
+
**Dispatch**:
|
|
20
|
+
One assignment of work to a single role for a single gate.
|
|
21
|
+
_Avoid_: Subagent call, tool call, spawn
|
|
22
|
+
|
|
23
|
+
**Round**:
|
|
24
|
+
One rework iteration on a (phase, gate) after CHANGES_REQUIRED.
|
|
25
|
+
_Avoid_: Retry, attempt (unless crash/timeout)
|
|
26
|
+
|
|
27
|
+
**Verdict**:
|
|
28
|
+
The reviewer's binary decision: APPROVED or CHANGES_REQUIRED.
|
|
29
|
+
_Avoid_: Status, result (use those for dispatch completion)
|
|
30
|
+
|
|
31
|
+
**Nits**:
|
|
32
|
+
Optional non-blocking notes attached to an APPROVED verdict.
|
|
33
|
+
_Avoid_: Soft fail, approved with changes
|
|
34
|
+
|
|
35
|
+
**Brief**:
|
|
36
|
+
Package-owned role identity document (harness-agnostic).
|
|
37
|
+
_Avoid_: System prompt, agent md (when meaning the shared contract)
|
|
38
|
+
|
|
39
|
+
**Artifact**:
|
|
40
|
+
A role's required output file for a dispatch, with machine-readable front-matter.
|
|
41
|
+
_Avoid_: Log, transcript, marker
|
|
42
|
+
|
|
43
|
+
**Gate**:
|
|
44
|
+
A tool-enforced precondition (step legality, verdict, verify commands, dirty-tree).
|
|
45
|
+
_Avoid_: Check, hook
|
|
46
|
+
|
|
47
|
+
**Profile**:
|
|
48
|
+
A globally defined harness launch template declaring oneshot and/or interactive commands.
|
|
49
|
+
_Avoid_: Model, provider, harness (when meaning the named config entry)
|
|
50
|
+
|
|
51
|
+
**Role**:
|
|
52
|
+
A fixed part in the loop (orchestrator, planner, reviewer, coder) with a fixed interaction mode.
|
|
53
|
+
_Avoid_: Agent, subagent
|
|
54
|
+
|
|
55
|
+
**Orchestrator**:
|
|
56
|
+
The hybrid scheduler that drives tools and never implements product code.
|
|
57
|
+
_Avoid_: Parent agent, main agent
|
|
58
|
+
|
|
59
|
+
**Verify command**:
|
|
60
|
+
A shell command from the phase package that must exit zero before commit.
|
|
61
|
+
_Avoid_: Test (when meaning the gate command list)
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Contributing to Apnea
|
|
2
|
+
|
|
3
|
+
See the workspace [CONTRIBUTING.md](../../CONTRIBUTING.md) for setup, release, and trusted publishing instructions.
|
|
4
|
+
|
|
5
|
+
Run the core package gates with:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bunx nx run-many -t typecheck test format:check package:check smoke --projects=apnea
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Run the Pi adapter gates with:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
bunx nx run-many -t typecheck test format:check package:check smoke --projects=pi-apnea
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Keep workflow behavior, protocol resources, briefs, and schemas in `@naxodev/apnea`. Keep Pi registration, Pi resources, and Pi-specific role launching in `@naxodev/pi-apnea`.
|
|
18
|
+
|
|
19
|
+
Both adapters must bind the shared operation registry. The Pi adapter must call it in process rather than invoke the CLI.
|
|
20
|
+
|
|
21
|
+
Compatible core patches flow through the Pi package's dependency range. Incompatible host interface changes require coordinated releases of both packages.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nacho Vazquez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# @naxodev/apnea
|
|
2
|
+
|
|
3
|
+
Apnea drives a multi-role development loop — plan, review, code, review, verify, commit — where
|
|
4
|
+
each role runs in its own real terminal pane and hands off work through files on disk instead of
|
|
5
|
+
a hidden subagent. Any harness that can run a shell command can hold the orchestrator seat.
|
|
6
|
+
|
|
7
|
+
## The loop
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
plan → plan review → phase package → code → code review → verify+commit → …
|
|
11
|
+
→ pr-description
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Roles can be different harnesses (Pi, Claude, Codex, …) via **global profiles**. Project config
|
|
15
|
+
only rebinds roles to profile names that already exist.
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- **bun `>=1.3.7`.** Needed to **run** the tool, not just to build it: the installed `bin` is
|
|
20
|
+
`dist/cli.js` with a `#!/usr/bin/env bun` shebang, and npm does not enforce the `engines.bun`
|
|
21
|
+
key. If you install `@naxodev/apnea` globally with only `node` on `PATH`, the `apnea` command
|
|
22
|
+
will fail on first invocation — this is the most likely first-run failure for a new user.
|
|
23
|
+
- **herdr**, for pane-based dispatch. The optional `floating` pane style additionally needs
|
|
24
|
+
**herdr ≥ 0.7.4** plus the linked plugin (see [`docs/protocol/config.md`](docs/protocol/config.md)).
|
|
25
|
+
- **jj or git.** Per [ADR 0007](docs/adr/0007-jj-first-commits.md), if neither is present
|
|
26
|
+
auto-commit is refused.
|
|
27
|
+
- **At least one agent CLI** — `pi`, `claude`, or `codex`.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bun install -g @naxodev/apnea
|
|
33
|
+
# or
|
|
34
|
+
npm install -g @naxodev/apnea
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For Pi, install the separate adapter:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pi install npm:@naxodev/pi-apnea
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
From source, for contributors:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd packages/apnea
|
|
47
|
+
bun install
|
|
48
|
+
bun run build
|
|
49
|
+
./dist/cli.js help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Optionally put it on `PATH`, e.g. `ln -s "$(pwd)/dist/cli.js" ~/.local/bin/apnea`.
|
|
53
|
+
|
|
54
|
+
## Sixty-second quickstart
|
|
55
|
+
|
|
56
|
+
1. `apnea setup` — writes global profiles to `~/.config/apnea/config.json` (and the herdr
|
|
57
|
+
`apnea` plugin, if herdr is present).
|
|
58
|
+
2. `apnea start "<goal>"` — starts a run against your working copy.
|
|
59
|
+
3. `apnea status` — a read-only snapshot of where the run stands and what to call next.
|
|
60
|
+
|
|
61
|
+
`apnea status` with no run in progress looks like this:
|
|
62
|
+
|
|
63
|
+
```console
|
|
64
|
+
$ apnea status
|
|
65
|
+
OK: no active run
|
|
66
|
+
next: apnea start
|
|
67
|
+
{
|
|
68
|
+
"has_state": false
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## CLI reference
|
|
73
|
+
|
|
74
|
+
Any harness that can run a shell command can hold the orchestrator seat — the CLI and the Pi
|
|
75
|
+
tools share one definition in `extension/registry.ts`, so they cannot drift apart (see
|
|
76
|
+
[ADR 0009](docs/adr/0009-cli-driver-split.md)).
|
|
77
|
+
|
|
78
|
+
### Operations
|
|
79
|
+
|
|
80
|
+
One row per operation. The CLI verb and the `/apnea` subcommand are the same word — they share a
|
|
81
|
+
single definition in `extension/registry.ts`, so they cannot drift apart (see
|
|
82
|
+
[ADR 0009](docs/adr/0009-cli-driver-split.md)). The two were listed as separate tables until one
|
|
83
|
+
of them went stale; a reader could not tell which.
|
|
84
|
+
|
|
85
|
+
| Operation | Pi tool | Flags | Purpose |
|
|
86
|
+
| --------------------- | ----------------------- | -------------------------------------------- | -------------------------------------------------------------- |
|
|
87
|
+
| `setup` | — | `[--project] [--force] [--agents-md]` | global profiles, optional project bindings, `AGENTS.md` primer |
|
|
88
|
+
| `start <goal>` | `workflow_start` | `[--allow-dirty] [--slug=name]` _(CLI only)_ | start a run |
|
|
89
|
+
| `resume` / `abandon` | `workflow_start` | | resume or abandon |
|
|
90
|
+
| `status` | `workflow_status` | | read-only snapshot |
|
|
91
|
+
| `dispatch <kind>` | `dispatch_role` | `[--rework]` | launch a role |
|
|
92
|
+
| `wait` | `workflow_wait` | `[--poll=<ms>] [--budget=<ms>]` _(CLI only)_ | wait for the pending artifact |
|
|
93
|
+
| `commit [message]` | `workflow_commit_phase` | `[--done]` | verify + commit phase |
|
|
94
|
+
| `reset-rounds <gate>` | — | `[--i-am-human]` _(CLI only)_ | **human only** |
|
|
95
|
+
|
|
96
|
+
Prefix with `/` inside Pi (`/apnea status`), or run it as a shell command (`apnea status`).
|
|
97
|
+
`/apnea-start` and `/apnea-status` are short aliases.
|
|
98
|
+
|
|
99
|
+
`reset-rounds` is not a Pi tool. It exists only as `apnea reset-rounds` and `/apnea reset-rounds`.
|
|
100
|
+
Only the CLI gates it — it refuses unless stdin/stdout are a terminal and a human retypes the gate
|
|
101
|
+
key, or passes `--i-am-human`. The slash command has no such gate: `/apnea` is already a human at
|
|
102
|
+
a terminal. See [ADR 0002](docs/adr/0002-orchestrator-authority.md).
|
|
103
|
+
|
|
104
|
+
`apnea wait` is resumable: exit `3` means the call's budget ran out but the role hasn't timed out,
|
|
105
|
+
so call `apnea wait` again. Exit codes: `0` ok, `1` refused/error, `2` usage, `3` still waiting.
|
|
106
|
+
See [`docs/protocol/config.md`](docs/protocol/config.md) for the budget-floor arithmetic behind
|
|
107
|
+
`--poll` and `--budget`.
|
|
108
|
+
|
|
109
|
+
### Setup flags
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
/apnea setup # ~/.config/apnea/config.json from PATH (+ herdr apnea plugin when herdr is present)
|
|
113
|
+
/apnea setup --project # also .apnea/config.json role→profile only
|
|
114
|
+
/apnea setup --agents-md # also write/refresh an AGENTS.md loop primer at the repo root
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`pane_style` (`regular` default, `floating` opt-in) lives in config; floating needs herdr ≥ 0.7.4
|
|
118
|
+
|
|
119
|
+
- the linked plugin — see [`docs/protocol/config.md`](docs/protocol/config.md).
|
|
120
|
+
|
|
121
|
+
The `@naxodev/pi-apnea` adapter applies Pi-specific role launch behavior. The core package remains
|
|
122
|
+
host-neutral.
|
|
123
|
+
|
|
124
|
+
Fallback: skill `apnea-setup` or prompt `/apnea-init` (both point at the same rules). **No config
|
|
125
|
+
UI in v1.**
|
|
126
|
+
|
|
127
|
+
## Maturity status
|
|
128
|
+
|
|
129
|
+
**What you can rely on:** the loop, the artifact contract, and the CLI are implemented, and the
|
|
130
|
+
extension suite is green — CI runs it on every pull request.
|
|
131
|
+
|
|
132
|
+
**What may still change:** the command surface and config shape may move before `1.0`. This is
|
|
133
|
+
`0.1.0` — breaking changes will land in minor bumps, not patches.
|
|
134
|
+
|
|
135
|
+
**Non-goals for v1:** worktrees, parallel coders, push/PR automation, memory store, native
|
|
136
|
+
CLAUDE.md injection, force-approve, config UI.
|
|
137
|
+
|
|
138
|
+
## Docs
|
|
139
|
+
|
|
140
|
+
| Doc | Purpose |
|
|
141
|
+
| -------------------------------------------------------------- | ---------------------- |
|
|
142
|
+
| [`CONTEXT.md`](CONTEXT.md) | Glossary |
|
|
143
|
+
| [`docs/protocol/overview.md`](docs/protocol/overview.md) | Loop, steps, tools |
|
|
144
|
+
| [`docs/protocol/artifacts.md`](docs/protocol/artifacts.md) | Paths + front-matter |
|
|
145
|
+
| [`docs/protocol/config.md`](docs/protocol/config.md) | Profiles + trust model |
|
|
146
|
+
| [`docs/protocol/manual-gate.md`](docs/protocol/manual-gate.md) | Bootstrap acceptance |
|
|
147
|
+
| [`docs/adr/`](docs/adr/) | Decisions |
|
|
148
|
+
| [`briefs/`](briefs/) | Role briefs |
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Build, test, typecheck commands, version-control conventions, and what CI enforces are in
|
|
153
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
154
|
+
|
|
155
|
+
## Security
|
|
156
|
+
|
|
157
|
+
Apnea runs repo-controlled text through agent CLIs by design — read
|
|
158
|
+
[`SECURITY.md`](SECURITY.md) for the trust model before pointing it at a repository you don't
|
|
159
|
+
trust, and for how to report a vulnerability.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT — see [`LICENSE`](LICENSE).
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
Apnea runs an automated loop that executes repo-controlled text through agent CLIs. That is a
|
|
4
|
+
real trust boundary, not an incidental detail, and it is worth stating plainly before you point
|
|
5
|
+
this tool at a repository.
|
|
6
|
+
|
|
7
|
+
## Trust model
|
|
8
|
+
|
|
9
|
+
- **Repo-controlled argv is not allowed.** Profiles and every `cmd_*` array resolve only from
|
|
10
|
+
`~/.config/apnea/config.json` plus package defaults. A project-local `.apnea/config.json`
|
|
11
|
+
that sets `cmd`, `cmd_oneshot`, `cmd_interactive`, or `bin` hard-errors at start. Project
|
|
12
|
+
config may only rebind roles to profile names that already exist, and set caps and timeouts.
|
|
13
|
+
- **Repo-controlled text is an accepted prompt-injection surface.** Tasks, plans, verify
|
|
14
|
+
commands, and vendored briefs are all repo text that reaches an agent CLI. This is
|
|
15
|
+
**disclosed, not solved.** Running Apnea over a repository you do not trust hands that
|
|
16
|
+
repository's text to an agent running with your credentials.
|
|
17
|
+
- **Planner-authored verify commands execute at the commit gate**, in the project working
|
|
18
|
+
directory, in the same trust domain as the coder writing source. Their output goes to
|
|
19
|
+
`verify.log`.
|
|
20
|
+
|
|
21
|
+
See [`docs/protocol/config.md`](docs/protocol/config.md) (Trust model section) and
|
|
22
|
+
[`docs/adr/0006-config-trust-model.md`](docs/adr/0006-config-trust-model.md) for the full
|
|
23
|
+
rationale.
|
|
24
|
+
|
|
25
|
+
## Supported versions
|
|
26
|
+
|
|
27
|
+
The package is pre-1.0. Only the latest release receives fixes.
|
|
28
|
+
|
|
29
|
+
## Reporting a vulnerability
|
|
30
|
+
|
|
31
|
+
Please report vulnerabilities through
|
|
32
|
+
[GitHub private vulnerability reporting](https://github.com/naxodev/ai/security) on
|
|
33
|
+
`naxodev/ai` - open the repository's Security tab and select "Report a vulnerability".
|
|
34
|
+
|
|
35
|
+
Do not open a public issue for a security report.
|
package/briefs/coder.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Brief: coder
|
|
2
|
+
|
|
3
|
+
You implement exactly one **Phase package**. You do not commit, re-plan, or expand scope.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
Task file names:
|
|
8
|
+
|
|
9
|
+
- path to phase package (read fully)
|
|
10
|
+
- optional path to prior code-review on rework
|
|
11
|
+
- exact **Artifact** path for your result
|
|
12
|
+
|
|
13
|
+
## Work
|
|
14
|
+
|
|
15
|
+
1. Read the phase package.
|
|
16
|
+
2. Implement only listed steps/files.
|
|
17
|
+
3. Run the package’s verify commands yourself; paste command + exit + tail of output into your result body.
|
|
18
|
+
4. Write the result artifact:
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
---
|
|
22
|
+
status: done
|
|
23
|
+
---
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Body: what changed, files touched, verify transcript, residual risks.
|
|
27
|
+
|
|
28
|
+
## Rework
|
|
29
|
+
|
|
30
|
+
If the task is a follow-up after `CHANGES_REQUIRED`:
|
|
31
|
+
|
|
32
|
+
- Read the code-review artifact.
|
|
33
|
+
- Fix only what the review requires within the same phase package.
|
|
34
|
+
- Do not renegotiate scope; escalate via your result body if the package is wrong.
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- No `git commit` / `jj describe` / push — orchestrator commits after review + verify gate.
|
|
39
|
+
- Do not edit `.apnea/state.json`.
|
|
40
|
+
- Prefer smallest diff that satisfies acceptance checks.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Brief: orchestrator
|
|
2
|
+
|
|
3
|
+
You schedule an Apnea **Run**. You do not implement product code, edit app source, or hand-edit `.apnea/state.json`.
|
|
4
|
+
|
|
5
|
+
## Authority
|
|
6
|
+
|
|
7
|
+
- Prefer Apnea tools when available: `workflow_start`, `dispatch_role`, `workflow_wait`, `workflow_commit_phase`, `workflow_status`.
|
|
8
|
+
- Do **not** call `workflow_reset_rounds` — reset-rounds is not a model-facing tool at all; it is human-only, on the CLI and `/apnea reset-rounds` (ADR 0002).
|
|
9
|
+
- If Apnea tools are absent, use the `apnea` CLI — same loop, same refusals.
|
|
10
|
+
|
|
11
|
+
## Loop
|
|
12
|
+
|
|
13
|
+
1. Start run (clean tree unless allow-dirty / resume). **Start only writes state — do not stop here.**
|
|
14
|
+
2. Immediately dispatch **planner** (`kind=plan`) → wait for plan artifact.
|
|
15
|
+
3. Dispatch **reviewer** (plan review) → wait for verdict.
|
|
16
|
+
4. On `CHANGES_REQUIRED`, re-dispatch planner then reviewer (new round).
|
|
17
|
+
5. On `APPROVED`, dispatch planner for **phase package**.
|
|
18
|
+
6. Dispatch **coder** with phase package path.
|
|
19
|
+
7. Dispatch **reviewer** (code review) → wait.
|
|
20
|
+
8. On `CHANGES_REQUIRED` with `rework: code` or no rework field, re-dispatch coder with `rework=true`, then reviewer.
|
|
21
|
+
9. On `CHANGES_REQUIRED` with `rework: phase_package`, dispatch planner for the revised phase package, then coder and reviewer. The package dispatch advances the review round automatically.
|
|
22
|
+
10. On `APPROVED`, commit phase (run verify commands first).
|
|
23
|
+
11. Repeat from phase packaging until planner reports no remaining phases.
|
|
24
|
+
12. Dispatch planner for `pr-description.md`.
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
- One outstanding Dispatch at a time.
|
|
29
|
+
- Read verdicts only from artifact front-matter.
|
|
30
|
+
- Never push remotes or open PRs.
|
|
31
|
+
|
|
32
|
+
## Active recovery (do this before escalating)
|
|
33
|
+
|
|
34
|
+
On timeout, idle-without-artifact, or a silent role pane: **fix it yourself** before
|
|
35
|
+
bothering the human. Tools already auto-nudge and re-submit prompts; when they
|
|
36
|
+
don't, the orchestrator still owns recovery.
|
|
37
|
+
|
|
38
|
+
1. `herdr pane get <pending_pane_id>` — is the pane alive? agent_status?
|
|
39
|
+
2. `herdr pane read <id> --source recent-unwrapped --lines 80` — did the prompt land?
|
|
40
|
+
- Prompt sitting in the input / INSERT / "Pasted text" → `herdr pane send-keys <id> Enter`.
|
|
41
|
+
- Agent idle, no artifact → `herdr pane run <id>` with a short nudge naming the exact artifact path.
|
|
42
|
+
- Agent working / API retrying → `workflow_wait` again (do not re-dispatch yet).
|
|
43
|
+
- Pane missing / harness exited to bare shell → `dispatch_role` same kind (no rework flag).
|
|
44
|
+
3. Only escalate after recovery failed twice, or on: round cap, dirty reviewer tree, illegal step, VCS confusion.
|
|
45
|
+
|
|
46
|
+
## Escalate (after recovery fails)
|
|
47
|
+
|
|
48
|
+
Cap hit, dirty reviewer tree, illegal state, or two failed recovery attempts.
|
|
49
|
+
Report a status-style summary (step, pending artifact, pane, last agent_status, what you tried).
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Brief: planner
|
|
2
|
+
|
|
3
|
+
You produce plans and phase packages for an Apnea **Run**. You do not implement product code.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
The Dispatch task file names:
|
|
8
|
+
|
|
9
|
+
- goal
|
|
10
|
+
- paths for prior artifacts (plan, plan-review, etc.)
|
|
11
|
+
- exact **Artifact** path you must write
|
|
12
|
+
|
|
13
|
+
## Outputs
|
|
14
|
+
|
|
15
|
+
### Full plan (`plan.md` or tasked path)
|
|
16
|
+
|
|
17
|
+
Include:
|
|
18
|
+
|
|
19
|
+
- goal restatement
|
|
20
|
+
- ordered **Phases** (vertical slices)
|
|
21
|
+
- per phase: intent, files likely touched, acceptance checks, **verify commands**, dependencies, non-goals
|
|
22
|
+
- definition of done for the whole run
|
|
23
|
+
|
|
24
|
+
Front-matter:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
---
|
|
28
|
+
status: done
|
|
29
|
+
---
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Phase package (`phase-package.md`)
|
|
33
|
+
|
|
34
|
+
Only the **current** phase, detailed enough for a weaker coder:
|
|
35
|
+
|
|
36
|
+
- exact steps
|
|
37
|
+
- files to touch / not touch
|
|
38
|
+
- acceptance checks
|
|
39
|
+
- verify commands (must be runnable)
|
|
40
|
+
- non-goals
|
|
41
|
+
|
|
42
|
+
Front-matter: `status: done` only.
|
|
43
|
+
|
|
44
|
+
When code review requests `rework: phase_package`, revise the package at the newly tasked round path. Read the cited review, preserve approved-plan scope, and do not overwrite the prior round's package.
|
|
45
|
+
|
|
46
|
+
### PR description (`pr-description.md`)
|
|
47
|
+
|
|
48
|
+
When tasked at terminus: summarize phases delivered, test plan, residual risk. Front-matter: `status: done` only.
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
- On plan rework, revise the **full plan**, not a silent delta file (unless the task says otherwise).
|
|
53
|
+
- Never invent artifact paths; use the task’s path.
|
|
54
|
+
- Prefer small phases that each leave the tree green under verify commands.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Brief: reviewer
|
|
2
|
+
|
|
3
|
+
You are a **Gate**. You do not implement product code. You must not modify application source or tests (file-content dirty tree is a protocol failure).
|
|
4
|
+
|
|
5
|
+
## Plan review
|
|
6
|
+
|
|
7
|
+
Read `plan.md` (path in task). Check:
|
|
8
|
+
|
|
9
|
+
- phases are vertical slices with acceptance + **verify commands**
|
|
10
|
+
- verify commands look sane (not `rm -rf`, not empty)
|
|
11
|
+
- scope is coherent; missing risks called out
|
|
12
|
+
|
|
13
|
+
Write the tasked artifact with:
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
---
|
|
17
|
+
status: done
|
|
18
|
+
verdict: APPROVED # or CHANGES_REQUIRED
|
|
19
|
+
nits: | # optional; only with APPROVED
|
|
20
|
+
...
|
|
21
|
+
---
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Body: findings, ordered by severity.
|
|
25
|
+
|
|
26
|
+
## Code review
|
|
27
|
+
|
|
28
|
+
Order matters:
|
|
29
|
+
|
|
30
|
+
1. Read **phase package** and compare to approved **plan**. If the package drifts, return `CHANGES_REQUIRED` with `rework: phase_package` before deep code review.
|
|
31
|
+
2. Review diff / coder result against the phase package only (no scope expansion).
|
|
32
|
+
3. Check claimed verify output if present; you do not need to re-run tests if readonly, but flag missing evidence.
|
|
33
|
+
|
|
34
|
+
Use `rework: code | phase_package` with a code-review `CHANGES_REQUIRED` verdict. Use `code` for implementation defects and `phase_package` for planner-owned package defects. Omit `rework` on `APPROVED`.
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- Binary **Verdict** only; nits never replace CHANGES_REQUIRED.
|
|
39
|
+
- Do not commit, push, or “fix while reviewing.”
|
|
40
|
+
- Write only the tasked artifact path (and nothing under app source).
|