@felixdotgo/aidlc-kit 0.2.0 → 0.3.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/DEVELOPMENT.md +13 -26
- package/README.md +35 -39
- package/dist/assets/.agents/aidlc/orchestrator.md +1 -1
- package/dist/assets/.agents/aidlc/schemas/state.schema.json +2 -0
- package/dist/assets/.agents/aidlc/scripts/lib/assignment-store.mjs +94 -48
- package/dist/assets/.agents/aidlc/scripts/lib/context-runtime.mjs +5 -4
- package/dist/assets/.agents/aidlc/scripts/lib/loop-authority.mjs +21 -5
- package/dist/assets/.agents/aidlc/scripts/lib/loop-daemon.mjs +52 -78
- package/dist/assets/.agents/aidlc/scripts/lib/loop-drivers.mjs +88 -14
- package/dist/assets/.agents/aidlc/scripts/lib/loop-env.mjs +279 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-cli.mjs +20 -5
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-remote.mjs +10 -1
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-supervisor.mjs +2 -1
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet.mjs +3 -2
- package/dist/assets/.agents/aidlc/scripts/lib/loop-git.mjs +9 -3
- package/dist/assets/.agents/aidlc/scripts/lib/loop-holder.mjs +376 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-intake.mjs +11 -3
- package/dist/assets/.agents/aidlc/scripts/lib/loop-lease.mjs +67 -61
- package/dist/assets/.agents/aidlc/scripts/lib/loop-leases.mjs +268 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-local-workers.mjs +78 -17
- package/dist/assets/.agents/aidlc/scripts/lib/loop-runtime.mjs +42 -10
- package/dist/assets/.agents/aidlc/scripts/lib/loop-stream.mjs +66 -9
- package/dist/assets/.agents/aidlc/scripts/lib/loop-supervisor-local.mjs +16 -56
- package/dist/assets/.agents/aidlc/scripts/lib/loop-supervisor-run-local.mjs +12 -6
- package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-docker.mjs +14 -2
- package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-log.mjs +158 -0
- package/dist/assets/.agents/aidlc/scripts/lib/repo-head.mjs +22 -0
- package/dist/assets/.agents/aidlc/scripts/lib/store.mjs +11 -0
- package/dist/assets/.agents/aidlc/scripts/lib/task-runtime-migrate.mjs +75 -0
- package/dist/assets/.agents/aidlc/scripts/lib/task-runtime.mjs +97 -0
- package/dist/assets/.agents/aidlc/scripts/loop-entry.mjs +87 -4
- package/dist/assets/.agents/aidlc/scripts/loop.cmd +101 -0
- package/dist/assets/.agents/aidlc/scripts/loop.sh +71 -0
- package/dist/assets/.agents/aidlc/scripts/remote-state.mjs +10 -4
- package/dist/assets/.agents/aidlc/scripts/state.mjs +16 -8
- package/dist/assets/ui/changes.js +83 -0
- package/dist/assets/ui/common.js +664 -0
- package/dist/assets/ui/dashboard.css +281 -59
- package/dist/assets/ui/dashboard.js +77 -0
- package/dist/assets/ui/detail.js +159 -0
- package/dist/assets/ui/live-log.js +332 -0
- package/dist/services/aidlc-coordination/package.json +1 -1
- package/dist/services/aidlc-coordination/src/lifecycle-core.mjs +11 -0
- package/dist/src/cli/argv.js +10 -4
- package/dist/src/cli/commands.js +52 -22
- package/dist/src/cli/loop-launcher.d.ts +47 -0
- package/dist/src/cli/loop-launcher.js +322 -0
- package/dist/src/cli.js +3 -0
- package/dist/src/installer.js +4 -2
- package/dist/src/model/records.d.ts +4 -0
- package/dist/src/state/validate.js +5 -0
- package/dist/src/task-ui.d.ts +31 -52
- package/dist/src/task-ui.js +25 -1562
- package/dist/src/ui/assets.d.ts +14 -0
- package/dist/src/ui/assets.js +45 -0
- package/dist/src/ui/changes.d.ts +83 -0
- package/dist/src/ui/changes.js +498 -0
- package/dist/src/ui/containers.d.ts +71 -0
- package/dist/src/ui/containers.js +214 -0
- package/dist/src/ui/daemon.d.ts +75 -0
- package/dist/src/ui/daemon.js +232 -0
- package/dist/src/ui/data.d.ts +42 -0
- package/dist/src/ui/data.js +89 -0
- package/dist/src/ui/docs.d.ts +13 -0
- package/dist/src/ui/docs.js +39 -0
- package/dist/src/ui/files.d.ts +3 -0
- package/dist/src/ui/files.js +20 -0
- package/dist/src/ui/http.d.ts +14 -0
- package/dist/src/ui/http.js +80 -0
- package/dist/src/ui/live.d.ts +5 -0
- package/dist/src/ui/live.js +43 -0
- package/dist/src/ui/markdown.d.ts +2 -0
- package/dist/src/ui/markdown.js +127 -0
- package/dist/src/ui/options.d.ts +48 -0
- package/dist/src/ui/options.js +81 -0
- package/dist/src/ui/security.d.ts +34 -0
- package/dist/src/ui/security.js +38 -0
- package/dist/src/ui/server.d.ts +39 -0
- package/dist/src/ui/server.js +347 -0
- package/dist/src/ui/sse.d.ts +14 -0
- package/dist/src/ui/sse.js +281 -0
- package/dist/src/ui/views/board.d.ts +7 -0
- package/dist/src/ui/views/board.js +131 -0
- package/dist/src/ui/views/changes.d.ts +19 -0
- package/dist/src/ui/views/changes.js +154 -0
- package/dist/src/ui/views/components.d.ts +56 -0
- package/dist/src/ui/views/components.js +113 -0
- package/dist/src/ui/views/docs.d.ts +15 -0
- package/dist/src/ui/views/docs.js +64 -0
- package/dist/src/ui/views/layout.d.ts +44 -0
- package/dist/src/ui/views/layout.js +233 -0
- package/dist/src/ui/views/task.d.ts +25 -0
- package/dist/src/ui/views/task.js +320 -0
- package/dist/src/upgrade.js +5 -2
- package/dist/src/workflow.d.ts +4 -0
- package/dist/src/workflow.js +33 -1
- package/docs/README.md +48 -33
- package/docs/architecture.md +101 -38
- package/docs/command-reference.md +269 -93
- package/docs/configuration.md +62 -42
- package/docs/coordination-service.md +85 -36
- package/docs/design-decisions.md +35 -31
- package/docs/development.md +111 -61
- package/docs/loop-local-run.md +135 -402
- package/docs/loop-runbook.md +84 -105
- package/docs/operating-workflow.md +55 -42
- package/docs/testing-and-release.md +70 -51
- package/docs/troubleshooting.md +165 -69
- package/package.json +1 -1
package/docs/loop-runbook.md
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
# Loop setup runbook
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> The loop is **experimental** and pre-1.0 (`0.x`): the `loop.*` fields, provider mappings, environment variables, and diagnostics can change incompatibly in any release before `1.0.0`. **Local mode is usable** on a single Linux host today; **fleet mode is still under active development** and is not yet stable.
|
|
5
|
-
|
|
6
|
-
This runbook walks through the three most common operational journeys for the end-to-end loop, in order:
|
|
7
|
-
|
|
8
|
-
1. [Enable the loop from `off`](#enable-the-loop-from-off)
|
|
9
|
-
2. [Run the loop in `local` mode](#local-mode)
|
|
10
|
-
3. [Run the loop across multiple machines (`fleet`)](#fleet-multi-machine)
|
|
11
|
-
|
|
12
|
-
It is a step-by-step guide, not a reference. For the full field, flag, and environment reference, see [Configuration](./configuration.md), [Command reference](./command-reference.md), and [AI-DLC Coordination service](./coordination-service.md); this runbook links to those pages for depth instead of repeating them.
|
|
3
|
+
Setup for the end-to-end loop: a **lead** agent runs clarify, plan, and wrap, **workers** run build items in Docker, and the loop stops at every gate for a human. Journeys, in order: [Enable the loop from `off`](#enable-the-loop-from-off), [Local mode](#local-mode), [Fleet (multi-machine)](#fleet-multi-machine); day-to-day operation is the [Local loop walkthrough](./loop-local-run.md).
|
|
13
4
|
|
|
14
|
-
##
|
|
5
|
+
## Status and stability
|
|
15
6
|
|
|
16
|
-
|
|
7
|
+
> [!WARNING]
|
|
8
|
+
> **Experimental, pre-1.0 (`0.x`).** Local mode is usable on one Linux host; fleet mode and the Coordination service are under active development with known bugs.
|
|
9
|
+
> CLI flags, `loop.*`/`mcp.*` fields, environment variables, diagnostics, and installed layouts can change incompatibly before `1.0.0`.
|
|
10
|
+
> Selecting a mode never starts or approves anything; only `aidlc-kit loop start` (or `loop.sh up`) runs the loop.
|
|
17
11
|
|
|
18
12
|
## Enable the loop from `off`
|
|
19
13
|
|
|
20
|
-
`loop.mode` defaults to `off` (
|
|
14
|
+
`loop.mode` defaults to `off` (absent `loop` field included). Set it to `local` or `fleet` and give `loop.agents` one `lead` and one or more named `workers`, each `codex`, `claude`, or `opencode`:
|
|
21
15
|
|
|
22
16
|
```json
|
|
23
17
|
{
|
|
@@ -28,124 +22,108 @@ The loop drives a task end-to-end. A **lead** agent runs the clarify, plan, and
|
|
|
28
22
|
}
|
|
29
23
|
```
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Pick one of three ways to set `loop.mode` and `loop.agents`:
|
|
34
|
-
|
|
35
|
-
- **Edit `.agents/config.json` directly.** This is the project-owned config; the fields are described in [Configuration](./configuration.md#optional-loop-configuration).
|
|
36
|
-
- **Use `init`** for a new install:
|
|
25
|
+
- Edit `.agents/config.json` directly; fields in [Configuration](./configuration.md#optional-loop-configuration).
|
|
26
|
+
- New install, with `init`:
|
|
37
27
|
```sh
|
|
38
|
-
npx --package @felixdotgo/aidlc-kit@0.
|
|
28
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit init . \
|
|
39
29
|
--loop-mode local --loop-lead codex --loop-workers a=codex,b=opencode
|
|
40
30
|
```
|
|
41
|
-
-
|
|
31
|
+
- Existing install, with the human-only `upgrade` (omitting the loop flags preserves the config). Stop the daemon first; a newer loop refuses to start while an older one holds a task (`A loop from a previous aidlc-kit version is still running …`).
|
|
42
32
|
```sh
|
|
43
|
-
npx --package @felixdotgo/aidlc-kit@0.
|
|
33
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit upgrade . \
|
|
44
34
|
--loop-mode local --loop-lead codex --loop-workers a=codex,b=opencode --dry-run
|
|
45
35
|
```
|
|
46
36
|
|
|
47
|
-
|
|
37
|
+
Verify: every `aidlc-kit loop` invocation fails closed before anything starts unless:
|
|
48
38
|
|
|
49
|
-
|
|
39
|
+
- `loop.mode` is `local` or `fleet`, and `loop.agents` has a valid `lead` and at least one valid worker (`Loop requires a configured lead and worker providers`).
|
|
40
|
+
- Any `--mode` flag matches `loop.mode` (`Requested mode does not match configured authority`).
|
|
50
41
|
|
|
51
|
-
|
|
52
|
-
- `loop.agents` must have a valid `lead` provider and at least one valid `worker` mapping (`Loop requires a configured lead and worker providers`).
|
|
53
|
-
- The requested `--mode` must match the configured `loop.mode` (`Requested mode does not match configured authority`).
|
|
54
|
-
|
|
55
|
-
These checks run on any `aidlc-kit loop` invocation before anything starts, so a wrong configuration fails closed with a clear message rather than silently running. A valid configuration is only a selection: it does not install or start a service, authorise an upgrade, or grant gate approval. Run `aidlc-kit loop start` to actually start the loop, and keep provider credentials out of the config object.
|
|
42
|
+
A valid config is only a selection: it installs and starts nothing and grants no approval. Keep credentials out of the config object.
|
|
56
43
|
|
|
57
44
|
## Local mode
|
|
58
45
|
|
|
59
|
-
|
|
46
|
+
One Linux host: the lead runs on the host (Codex, Claude Code, or OpenCode), build items fan out to Docker-isolated workers, and the canonical state is the local `state.mjs`.
|
|
60
47
|
|
|
61
48
|
### Prerequisites
|
|
62
49
|
|
|
63
50
|
| Requirement | Notes |
|
|
64
51
|
| --- | --- |
|
|
65
|
-
| Linux host
|
|
52
|
+
| Linux host, non-root user | `loop-local-workers.mjs` rejects non-Linux hosts; Docker workers need a non-root uid/gid. |
|
|
66
53
|
| Docker engine | The worker batch preflights `docker info` and the worker image. |
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| Provider credentials | Exported in the environment; never written into `.agents/config.json`. |
|
|
54
|
+
| Worker Docker image | Auto-built on first build dispatch; `AIDLC_WORKER_DOCKER_IMAGE` only overrides the default. |
|
|
55
|
+
| Provider credentials | In `.agents/loop.env` (git-ignored) or exported; never in `.agents/config.json`. |
|
|
70
56
|
|
|
71
57
|
### Step 1 — Configure `local`
|
|
72
58
|
|
|
73
|
-
Set `loop.mode` to `local` with a lead and workers
|
|
59
|
+
Set `loop.mode` to `local` with a lead and workers, as shown in [Enable the loop from `off`](#enable-the-loop-from-off).
|
|
74
60
|
|
|
75
|
-
|
|
76
|
-
{
|
|
77
|
-
"loop": {
|
|
78
|
-
"mode": "local",
|
|
79
|
-
"agents": { "lead": "codex", "workers": { "worker-a": "codex", "worker-b": "opencode" } }
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
```
|
|
61
|
+
### Step 2 — Fill in `.agents/loop.env`
|
|
83
62
|
|
|
84
|
-
|
|
63
|
+
`init`/`upgrade` install `.agents/loop.env` as a commented template (git-ignored through `.agents/.gitignore`). Uncomment what you need; exported shell variables win, and values your tools already store are detected for the configured providers only:
|
|
85
64
|
|
|
86
|
-
| Variable | Required | Purpose |
|
|
65
|
+
| Variable | Required | Purpose and detected from |
|
|
87
66
|
| --- | --- | --- |
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `AIDLC_LOCAL_WORKTREES_ROOT` | no | Root for worker worktrees; defaults to a system temp directory. It must be outside the integration checkout. |
|
|
94
|
-
| `AIDLC_LOOP_EVENT_LOG` | no (see note) | Path to a JSONL event-log sidecar that feeds the web dashboard live log. The `aidlc-kit ui` **New task** action (when it starts the daemon) sets it to `.agents/data/loop/ui-events.jsonl` automatically; a **manually started** daemon must set it to the same path or the dashboard live log stays empty. |
|
|
67
|
+
| `AIDLC_OPENCODE_MODEL` | if any provider is `opencode` | `provider/model[#variant]` (for example `opencode-go/gpt-6-luna`); the turn fails closed without it. Detected: `"model"` in `opencode.json` (project, `OPENCODE_CONFIG`, or `~/.config/opencode`). |
|
|
68
|
+
| `OPENAI_API_KEY` | if a provider is `codex` | Codex worker credential. Detected: `~/.codex/auth.json` after `codex login --with-api-key` (a ChatGPT-only login is not enough). |
|
|
69
|
+
| `ANTHROPIC_API_KEY` | if a provider is `claude` | Claude Code worker credential. Detected: `"env"` in `.claude/settings.local.json`, `.claude/settings.json`, or `~/.claude/settings.json`. |
|
|
70
|
+
| `OPENCODE_API_KEY` | if a provider is `opencode` | OpenCode worker credential; the key follows the model prefix (`openai/` → `OPENAI_API_KEY`, `anthropic/` → `ANTHROPIC_API_KEY`, otherwise `OPENCODE_API_KEY`). Detected: `~/.local/share/opencode/auth.json`. |
|
|
71
|
+
| `AIDLC_WORKER_DOCKER_IMAGE` | no | Single-image override; the default `aidlc-worker-<provider>:local` is auto-built and recorded in `loop.workerImage`. |
|
|
95
72
|
|
|
96
|
-
|
|
73
|
+
Check the result (secrets never printed) with `./.agents/aidlc/scripts/loop.sh check` (= `aidlc-kit loop env`).
|
|
97
74
|
|
|
98
|
-
|
|
75
|
+
Rarely set: `AIDLC_LOCAL_WORKTREES_ROOT` (worker worktrees root, default a system temp directory, must be outside the integration checkout); `AIDLC_LOOP_EVENT_LOG` (always `.agents/data/loop/ui-events.jsonl` for a local daemon); `AIDLC_ENV_FILE` or `--loop-env PATH` (another env file). Lookup order: [Command reference](./command-reference.md#loop). Credential rule: [Provider credentials and OpenCode](./configuration.md#provider-credentials-and-opencode).
|
|
99
76
|
|
|
100
|
-
|
|
77
|
+
### Step 3 — Build the worker image (usually automatic)
|
|
101
78
|
|
|
102
79
|
```sh
|
|
103
80
|
npx @felixdotgo/aidlc-kit loop worker-image --provider codex # → aidlc-worker-codex:local
|
|
104
81
|
npx @felixdotgo/aidlc-kit loop worker-image --provider opencode # → aidlc-worker-opencode:local
|
|
105
82
|
```
|
|
106
83
|
|
|
107
|
-
|
|
84
|
+
- Records the tag in `loop.workerImage`; the supervisor auto-builds any missing per-provider image before dispatch.
|
|
85
|
+
- Batch preflight inspects the image and runs each provider CLI with `--version` in the container; a missing or mismatched image fails before any worker starts. Test fixtures: [Testing and release](./testing-and-release.md#loop-docker-and-postgresql-verification).
|
|
108
86
|
|
|
109
87
|
### Step 4 — Start the daemon, add tasks, and watch
|
|
110
88
|
|
|
111
|
-
`start` launches the singleton daemon (one per project) and reads no requirement. Add tasks with the web dashboard **New task** or loop intake, which reads the requirement from stdin (capped at 8192 bytes) and never from an argument:
|
|
112
|
-
|
|
113
89
|
```sh
|
|
114
|
-
|
|
115
|
-
|
|
90
|
+
./.agents/aidlc/scripts/loop.sh up # env check + daemon + dashboard; --open launches the browser, --no-ui skips the dashboard
|
|
91
|
+
./.agents/aidlc/scripts/loop.sh down # stop both (--now cancels the running turn); also: status, logs, check
|
|
116
92
|
```
|
|
117
93
|
|
|
118
|
-
|
|
94
|
+
`Ctrl-C` in the `up` terminal closes only the dashboard. On Windows use `.agents\aidlc\scripts\loop.cmd`.
|
|
119
95
|
|
|
120
|
-
`
|
|
96
|
+
Underneath, `loop start` runs the singleton daemon (one per project) and reads no requirement. Add tasks with the dashboard **New task** or with intake (stdin only, capped at 8192 bytes):
|
|
121
97
|
|
|
122
98
|
```sh
|
|
123
|
-
npx --package @felixdotgo/aidlc-kit@0.
|
|
99
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop start
|
|
100
|
+
echo "Add PDF report export" | npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop intake
|
|
124
101
|
```
|
|
125
102
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
103
|
+
- The daemon runs only loop-owned tasks, keeps polling after a gate or completion, and auto-resumes approved tasks; there is no `loop resume`.
|
|
104
|
+
- Stuck: `aidlc-kit loop leases`, then [Loop leases, locks and claims](./troubleshooting.md#loop-leases-locks-and-claims).
|
|
105
|
+
- Upgraded from a version that kept assignments, event logs, run records, and intake files under `.agents/data/loop/` or at the task directory root: the daemon moves them under `.agents/data/tasks/<id>/runtime/` when it starts; `aidlc-kit loop migrate-data --dry-run` previews, `aidlc-kit loop migrate-data` runs it by hand ([Command reference](./command-reference.md#loop)).
|
|
106
|
+
- Status, stopping, resuming, the streaming log, and the dashboard: [Local loop walkthrough](./loop-local-run.md#start-the-daemon-and-add-tasks).
|
|
129
107
|
|
|
130
|
-
### Step 5 — Approve gates from the trusted host terminal
|
|
108
|
+
### Step 5 — Approve gates, or send feedback, from the trusted host terminal
|
|
131
109
|
|
|
132
|
-
|
|
110
|
+
Only a human approves a gate, on the trusted host terminal or the signed-in dashboard; never a lead or worker container, never piped input:
|
|
133
111
|
|
|
134
112
|
```sh
|
|
135
|
-
node .agents/aidlc/scripts/loop-gate.mjs <task-id>
|
|
113
|
+
node .agents/aidlc/scripts/loop-gate.mjs <task-id> # type approve, or any other text as feedback (task stays at the gate)
|
|
136
114
|
```
|
|
137
115
|
|
|
138
|
-
The
|
|
116
|
+
The dashboard detail page offers the same two actions ([details](./loop-local-run.md#approve-a-gate-or-send-feedback)).
|
|
139
117
|
|
|
140
118
|
## Fleet (multi-machine)
|
|
141
119
|
|
|
142
|
-
Fleet mode spreads the loop across machines through the coordination service
|
|
120
|
+
Fleet mode spreads the loop across machines through the coordination service: `remote-state.mjs` replaces the local `state.mjs`, and the remote workspace is canonical. Deployment, storage, and credentials: [Coordination service](./coordination-service.md#multi-machine-loop-deployment).
|
|
143
121
|
|
|
144
122
|
### Prerequisites
|
|
145
123
|
|
|
146
|
-
- A deployed coordination service
|
|
147
|
-
- `loop.mode` set to `fleet
|
|
148
|
-
- Three distinct credential classes
|
|
124
|
+
- A deployed coordination service (PostgreSQL for multi-host) and a shared Git remote.
|
|
125
|
+
- `loop.mode` set to `fleet`, with workers matching your worker machines.
|
|
126
|
+
- Three distinct credential classes on the service: `MCP_FLEET_LEAD_TOKEN`, `MCP_FLEET_REVIEWER_TOKEN`, `MCP_FLEET_WORKER_TOKENS`.
|
|
149
127
|
|
|
150
128
|
### Step 1 — Configure `fleet`
|
|
151
129
|
|
|
@@ -162,74 +140,75 @@ Fleet mode spreads the loop across machines through the coordination service. It
|
|
|
162
140
|
|
|
163
141
|
| Variable | Required | Purpose |
|
|
164
142
|
| --- | --- | --- |
|
|
165
|
-
| `AIDLC_FLEET_URL` | yes |
|
|
166
|
-
| `AIDLC_FLEET_WORKSPACE` | yes |
|
|
167
|
-
| `AIDLC_FLEET_TOKEN` | yes |
|
|
168
|
-
| `AIDLC_FLEET_INTEGRATION_BRANCH` | yes |
|
|
169
|
-
| `AIDLC_FLEET_PROJECT_ROOT` | no | Set
|
|
170
|
-
| `AIDLC_FLEET_WORKER_IDS` / `AIDLC_FLEET_WORKER_PROVIDERS` | no | Derived from `loop.agents.workers`;
|
|
171
|
-
| `AIDLC_FLEET_GIT_REMOTE` | no | Git remote name;
|
|
172
|
-
| `
|
|
173
|
-
|
|
174
|
-
|
|
143
|
+
| `AIDLC_FLEET_URL` | yes | Full HTTPS `/mcp` URL of the service. |
|
|
144
|
+
| `AIDLC_FLEET_WORKSPACE` | yes | Remote workspace id. |
|
|
145
|
+
| `AIDLC_FLEET_TOKEN` | yes | Lead credential. |
|
|
146
|
+
| `AIDLC_FLEET_INTEGRATION_BRANCH` | yes | Shared integration branch; must exist on the remote. |
|
|
147
|
+
| `AIDLC_FLEET_PROJECT_ROOT` | no | Set by `aidlc-kit loop`; needed only for the direct `remote-state.mjs` / fleet-runner client. Must match the loop root. |
|
|
148
|
+
| `AIDLC_FLEET_WORKER_IDS` (comma-separated) / `AIDLC_FLEET_WORKER_PROVIDERS` | no | Derived from `loop.agents.workers`; must match it. |
|
|
149
|
+
| `AIDLC_FLEET_GIT_REMOTE` | no | Git remote name; default `origin`. |
|
|
150
|
+
| `AIDLC_FLEET_AGENT` | direct runner only | Lead provider when running `fleet-run.mjs` directly (default `codex`); `aidlc-kit loop` sets it from `loop.agents.lead`. Also the per-worker provider fallback. |
|
|
151
|
+
| `AIDLC_FLEET_MAX_TURNS`, `AIDLC_FLEET_TURN_TIMEOUT_MS`, `AIDLC_FLEET_MAX_STALL_TURNS`, `AIDLC_FLEET_POLL_MS` | no | Override `loop.limits` and `loop.pollMs`. |
|
|
152
|
+
|
|
153
|
+
The lead agent is `loop.agents.lead`. Do not export `AIDLC_FLEET_REVIEWER_TOKEN` in the lead shell; the daemon strips it from every lead and worker process.
|
|
175
154
|
|
|
176
155
|
### Step 3 — Start the daemon and add tasks
|
|
177
156
|
|
|
178
|
-
`
|
|
157
|
+
`loop start --mode fleet` preflights the service (`fleet_get`) and the remote integration branch, then runs the same daemon as local mode, failing closed instead of falling back to local:
|
|
179
158
|
|
|
180
159
|
```sh
|
|
181
|
-
npx --package @felixdotgo/aidlc-kit@0.
|
|
182
|
-
echo "Add PDF report export" | npx --package @felixdotgo/aidlc-kit@0.
|
|
160
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop start --mode fleet
|
|
161
|
+
echo "Add PDF report export" | npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop intake --mode fleet
|
|
183
162
|
```
|
|
184
163
|
|
|
185
|
-
Intake creates the remote task under a short lead claim and writes `.agents/data/tasks/<task-id>/
|
|
164
|
+
- **Intake** creates the remote task under a short lead claim and writes `.agents/data/tasks/<task-id>/runtime/intake.json` with `authority: "fleet"`; only those tasks are fleet loop-owned.
|
|
165
|
+
- **Each actionable task** runs the fleet supervisor bounded (claim the supervisor lease, fenced lead turns and worker dispatch, publish the gate snapshot, release); after reviewer approval the next poll re-claims it.
|
|
166
|
+
- An unreachable service shows as `daemon_poll_error`; the daemon keeps running.
|
|
186
167
|
|
|
187
|
-
The
|
|
168
|
+
The fleet runner also runs directly from the service deployment (`.agents/aidlc-coordination/`, or `dist/services/aidlc-coordination/` in a source checkout); `supervisor` waits at each gate and never approves:
|
|
188
169
|
|
|
189
170
|
```sh
|
|
190
171
|
node .agents/aidlc-coordination/src/fleet-run.mjs supervisor <task-id>
|
|
191
172
|
node .agents/aidlc-coordination/src/fleet-run.mjs coordinator <task-id> --once
|
|
192
173
|
```
|
|
193
174
|
|
|
194
|
-
Run directly, `supervisor` waits at each gate for the reviewer approval and resumes automatically; it never approves a gate.
|
|
195
|
-
|
|
196
175
|
### Step 4 — Run a worker on each worker machine
|
|
197
176
|
|
|
198
|
-
|
|
177
|
+
Same `AIDLC_FLEET_URL`, workspace, and `AIDLC_FLEET_PROJECT_ROOT` (a project checkout); this worker's own `AIDLC_FLEET_TOKEN`; and:
|
|
199
178
|
|
|
200
179
|
| Variable | Required | Purpose |
|
|
201
180
|
| --- | --- | --- |
|
|
202
|
-
| `AIDLC_FLEET_WORKER_ID` | yes | This machine's worker id (
|
|
181
|
+
| `AIDLC_FLEET_WORKER_ID` | yes | This machine's worker id (a configured worker). |
|
|
203
182
|
| `AIDLC_FLEET_WORKTREES_ROOT` | yes | Root for this worker's isolated worktrees. |
|
|
204
|
-
| `AIDLC_FLEET_WORKER_AGENT` | recommended |
|
|
205
|
-
| `AIDLC_WORKER_DOCKER_IMAGE` | no | Image override
|
|
183
|
+
| `AIDLC_FLEET_WORKER_AGENT` | recommended | Provider (`codex`, `claude`, or `opencode`); falls back to this worker's entry in `AIDLC_FLEET_WORKER_PROVIDERS`, then `AIDLC_FLEET_AGENT`. A worker rejects jobs for another provider. |
|
|
184
|
+
| `AIDLC_WORKER_DOCKER_IMAGE` | no | Image override; otherwise `loop.workerImage[provider]` or `aidlc-worker-<provider>:local`, auto-built. Required when the provider is unknown. |
|
|
206
185
|
| `AIDLC_OPENCODE_MODEL` | if the provider is `opencode` | `provider/model[#variant]`. |
|
|
207
|
-
| worker credential | yes | `OPENAI_API_KEY` (codex), `ANTHROPIC_API_KEY` (claude), or
|
|
208
|
-
|
|
209
|
-
Run one bounded assignment per invocation, or omit `--once` to keep polling:
|
|
186
|
+
| worker credential | yes | `OPENAI_API_KEY` (codex), `ANTHROPIC_API_KEY` (claude), or the key matching the opencode model prefix (`openai/`, `anthropic/`, otherwise `OPENCODE_API_KEY`). |
|
|
210
187
|
|
|
211
188
|
```sh
|
|
212
|
-
node .agents/aidlc-coordination/src/fleet-run.mjs worker --once
|
|
189
|
+
node .agents/aidlc-coordination/src/fleet-run.mjs worker --once # omit --once to keep polling
|
|
213
190
|
```
|
|
214
191
|
|
|
215
192
|
The worker resolves the image to its immutable `sha256:` id and preflights Docker and the provider CLI before claiming work.
|
|
216
193
|
|
|
217
194
|
### Step 5 — Approve gates as the reviewer
|
|
218
195
|
|
|
219
|
-
Use the reviewer credential in a connected reviewer conversation:
|
|
220
|
-
|
|
221
196
|
```sh
|
|
222
197
|
node .agents/aidlc/scripts/remote-state.mjs gate inbox
|
|
223
198
|
node .agents/aidlc/scripts/remote-state.mjs gate approve <task-id> --snapshot <snapshot-id> --source "<explicit user approval>"
|
|
224
199
|
```
|
|
225
200
|
|
|
226
|
-
|
|
201
|
+
- `gate approve` checks the snapshot is still current and uses the reviewer-only operation; run it only after the human explicitly approves the packet.
|
|
202
|
+
- Dashboard: start `aidlc-kit ui` with the Step 2 environment plus `AIDLC_FLEET_REVIEWER_TOKEN` or `--reviewer-token-file`; without it the approve API returns `403` and the page shows these commands.
|
|
203
|
+
- **Send feedback (stay at gate)** needs no reviewer credential: it runs `remote-state.mjs task status <task-id> --status active --mode audited` under the lead claim; the task stays at the gate and the supervisor publishes a revised snapshot.
|
|
227
204
|
|
|
228
205
|
## Authority boundary
|
|
229
206
|
|
|
230
|
-
`local`
|
|
207
|
+
`local` uses the canonical local state; `fleet` uses `remote-state.mjs`. While `AIDLC_FLEET_URL` is set, local lifecycle, context, gate, assignment, and standalone loop commands reject use; unset it only when deliberately returning to a local run. Contract: [State and synchronization contract](./coordination-service.md#state-and-synchronization-contract).
|
|
231
208
|
|
|
232
209
|
## Where to go next
|
|
233
210
|
|
|
234
|
-
- [
|
|
235
|
-
- [
|
|
211
|
+
- [Local loop walkthrough](./loop-local-run.md) — day-to-day operation.
|
|
212
|
+
- [AI-DLC Coordination service](./coordination-service.md) — deploying the fleet service.
|
|
213
|
+
- [Operating the workflow](./operating-workflow.md) — gates, approvals, handoffs.
|
|
214
|
+
- [Troubleshooting](./troubleshooting.md) — symptom and error-code recovery.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Operating the workflow
|
|
2
2
|
|
|
3
|
-
`aidlc-kit` gives an agent a repeatable delivery lifecycle
|
|
3
|
+
`aidlc-kit` gives an agent a repeatable delivery lifecycle — intent, design, implementation, final review — with a human approving each point where scope or risk changes. Settings: [Configuration](./configuration.md); exact flags: [Command reference](./command-reference.md).
|
|
4
4
|
|
|
5
5
|
## Lifecycle at a glance
|
|
6
6
|
|
|
@@ -15,11 +15,10 @@ request → clarify → Confirm requirements → plan → Approve plan → build
|
|
|
15
15
|
| Build | Approved change, verification, and adversarial review | Review the completed change at Review implementation. |
|
|
16
16
|
| Wrap | Delivery notes, lessons, and residual risk | Runs only after Review implementation approval. |
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
- The agent continues after every non-terminal transition and item or evidence mutation (completing one item is progress, not a turn boundary) and stops only for a gate ready for human action, a durable blocker, a terminal non-success outcome, or completion.
|
|
19
|
+
- The client conversation (Codex, Claude Code, or OpenCode) is the lead: it dispatches native agents for independent items and presents each gate. After a restart, ask it to resume the task ID; it rereads `task next`, inspects assignment records and worktree results, and continues dependency-ready work only.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
For example, a feature with API, UI, and integration tasks can be recorded as a feature graph:
|
|
21
|
+
Related tasks can form a feature graph:
|
|
23
22
|
|
|
24
23
|
```sh
|
|
25
24
|
node .agents/aidlc/scripts/state.mjs feature create checkout --branch feature/checkout
|
|
@@ -30,27 +29,24 @@ node .agents/aidlc/scripts/state.mjs feature ready checkout
|
|
|
30
29
|
node .agents/aidlc/scripts/state.mjs task ready checkout-api
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
- Task IDs must exist before `feature link`; add a sibling with `task create <id> --title <title> --feature checkout [--depends-on <task-id,...>]`. Each task passes its own G0/G1/G2.
|
|
33
|
+
- Build items declare `--depends-on <item-id,...>` via `task item`; `task ready` lists dispatchable items. Missing, cyclic, or incomplete dependencies are rejected.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
Unattended multi-machine work uses the optional coordination service as sole canonical authority: [Coordination service](./coordination-service.md#multi-machine-loop-deployment).
|
|
36
36
|
|
|
37
37
|
## Parallel workstreams
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
- The lead may delegate independent, bounded workstreams when the host has spare worker capacity: keep one slot, assign explicit ownership and completion criteria, integrate returned work before relying on it.
|
|
40
|
+
- The lead is the only writer for task state, evidence, review artifacts, and gates; parallel work never relaxes approvals.
|
|
41
|
+
- A build batch holds only items with non-overlapping file/area ownership; shared surfaces, integration, task-wide verification, and adversarial review stay lead-owned.
|
|
40
42
|
|
|
41
43
|
## Starting work
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```text
|
|
46
|
-
Add rate limiting to the login endpoint using the AI-DLC workflow.
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The adapter creates a task, writes an intent brief, and presents Confirm requirements. Do not treat a partial implementation as approved work before Approve plan, and do not treat a passing test as approval at Review implementation.
|
|
45
|
+
Make a normal change request, for example `Add rate limiting to the login endpoint using the AI-DLC workflow.` The adapter creates the task, writes an intent brief, and presents Confirm requirements. A partial implementation is not approved work; a passing test is not approval at Review implementation.
|
|
50
46
|
|
|
51
47
|
## State and review artifacts
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
Project data: `.agents/data/`; package-managed workflow: `.agents/aidlc/`. Never hand-edit lifecycle state:
|
|
54
50
|
|
|
55
51
|
```sh
|
|
56
52
|
node .agents/aidlc/scripts/state.mjs task list --limit 20
|
|
@@ -60,15 +56,26 @@ node .agents/aidlc/scripts/state.mjs task next <task-id>
|
|
|
60
56
|
node .agents/aidlc/scripts/gate-view.mjs <task-id>
|
|
61
57
|
```
|
|
62
58
|
|
|
63
|
-
`task next` is the authoritative instruction
|
|
59
|
+
`task next` is the authoritative next instruction; `gate-view` renders the review packet for every gate.
|
|
60
|
+
|
|
61
|
+
Each task owns `.agents/data/tasks/<task-id>/`: review artifacts (`intent.md`, `design.md`, `workplan.md`) at its root, operational files (assignment claims, event history, loop run record, intake, worker logs) under `runtime/`, which is never committed. Layout and the migration from older versions: [Architecture](./architecture.md#loop-runtime).
|
|
62
|
+
|
|
63
|
+
### Script contract in brief
|
|
64
|
+
|
|
65
|
+
- Every `state.mjs` and `task-next.mjs` command prints one JSON envelope `{ok, result, nextAction?}`; failures are one-line `{ok: false, error}` on stderr with exit code `1` (expected), `2` (continuation guard), or `3` (crash).
|
|
66
|
+
- Before any final response, run `task-next.mjs <task-id> --require-stop`; exit code `2` means execute `continuation.command` instead of replying. Recover from a premature reply with `task next <task-id>` in the next turn — never by re-approving a gate.
|
|
67
|
+
- Rendering, gate-check, and context commands may print Markdown or plain text instead of JSON.
|
|
68
|
+
- In build, `nextAction` names the next `in_progress` or `todo` item and stays `run_phase` after the last item until verification, adversarial review, and gate preparation finish.
|
|
69
|
+
- Options, root discovery, warnings, and the full envelope are in [Installed lifecycle scripts](./command-reference.md#installed-lifecycle-scripts).
|
|
64
70
|
|
|
65
|
-
|
|
71
|
+
### Task switch guard
|
|
66
72
|
|
|
67
|
-
|
|
73
|
+
- `task create` fails closed while another task is actionable until the agent passes the returned `--switch-from` acknowledgement with explicit user direction; this stamps a resume-marker diagnostic on the acknowledged task without mutating it.
|
|
74
|
+
- The coordination service does not enforce this guard (remote `upsertTask`/`replaceState` can add tasks alongside actionable work); MCP-backed hosts rely on the adapter protocol.
|
|
68
75
|
|
|
69
76
|
## Review steps and approvals
|
|
70
77
|
|
|
71
|
-
Review-step names are English in every task
|
|
78
|
+
Review-step names are English in every task; internal IDs are stable. Identify gates by `gate`, never by display text (`title`, `action`).
|
|
72
79
|
|
|
73
80
|
| Review step | Internal gate ID |
|
|
74
81
|
| --- | --- |
|
|
@@ -76,25 +83,27 @@ Review-step names are English in every task. Internal IDs remain unchanged for c
|
|
|
76
83
|
| Approve plan | `G1_review` |
|
|
77
84
|
| Review implementation | `G2_codereview` |
|
|
78
85
|
|
|
79
|
-
Display text such as JSON `title` and `action` uses these names; integrations should identify gates by `gate`, not by display text.
|
|
80
|
-
|
|
81
|
-
Approval is an explicit human action. When the agent receives an approval, it records the approval and advances the lifecycle atomically:
|
|
82
|
-
|
|
83
86
|
```sh
|
|
84
87
|
node .agents/aidlc/scripts/state.mjs gate approve <task-id> --gate <gate-name> --source "<explicit approval>"
|
|
85
88
|
```
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
- Approval is an explicit human action, recorded and advanced atomically by `gate approve` — the only command that creates approval evidence. Never invent approvals or approve unresolved design decisions.
|
|
91
|
+
- `--source` is provenance, not authentication. Call `gate approve` only in a later user turn that explicitly assents to the gate currently shown.
|
|
92
|
+
- Approve plan starts a build boundary; the verification, adversarial review, and Review implementation approval that enter wrap must belong to the current boundary.
|
|
93
|
+
- Reopening the plan invalidates Approve plan and Review implementation approvals, resets every non-deferred build item to `todo`, and requires current-build verification and review.
|
|
94
|
+
- Evidence is append-only; the current boundary is identified by evidence order, not timestamps.
|
|
95
|
+
- Per affected area: at least one `test` or `lint` result, and the latest result of every verification kind present must pass.
|
|
96
|
+
- Archiving commits the immutable record before the compact catalog; a retry recovers the interrupted-write window only when the catalog still proves the same active task and the orphan record has the same stable identity. Other conflicts need investigation, not overwrite.
|
|
97
|
+
- Rendered workplans are derived views, replaced atomically under the state lock by the standalone render command.
|
|
94
98
|
|
|
95
99
|
## Blocked work and successors
|
|
96
100
|
|
|
97
|
-
`blocked_on_user` means a valid human gate is ready
|
|
101
|
+
`blocked_on_user` means a valid human gate is ready, never that a failed change awaits a rubber stamp. When verification or review cannot pass, record a durable handoff:
|
|
102
|
+
|
|
103
|
+
- **Validation.** Wrap has no human gate and rejects `blocked_on_user`; `task status` validates gate prerequisites before persisting it, and `gate-view` refuses an active or unready task.
|
|
104
|
+
- **Leaving a gate wait.** Requires audited reason and source metadata plus diagnostic evidence; sourced closure and handoff records give the terminal trail.
|
|
105
|
+
- **Compatibility paths.** Only migration-stamped legacy Review implementation waits and recovery of an invalid `wrap`/`none` wait are exempt; neither is an approval. `legacyG2Wait` is written only by state-schema migration (`state.mjs state migrate` or a human-run installer upgrade), exempts only a still-ready pre-existing wait from the repair bound, and is cleared by every route out of the wait.
|
|
106
|
+
- **Repair bounds.** Three failed verify records per area or two failed review records in the current build flip `nextAction` to `blocked` and close Review implementation with `REPAIR_BOUND` until a durable handoff is recorded.
|
|
98
107
|
|
|
99
108
|
```sh
|
|
100
109
|
node .agents/aidlc/scripts/state.mjs task handoff <task-id> --kind <kind> --reason "<reason>" --source "<evidence>"
|
|
@@ -102,25 +111,29 @@ node .agents/aidlc/scripts/state.mjs task reopen <task-id> --to plan --reason "<
|
|
|
102
111
|
node .agents/aidlc/scripts/state.mjs task close <task-id> --reason "<reason>" --source "<explicit request>"
|
|
103
112
|
```
|
|
104
113
|
|
|
105
|
-
|
|
114
|
+
To continue in a fresh task, create it at Confirm requirements and link it as a successor. `closed` and `superseded` are terminal non-success outcomes: no approvals transfer, no delivery is implied.
|
|
106
115
|
|
|
107
116
|
## Operational rules
|
|
108
117
|
|
|
109
118
|
- The installed workflow never downloads runtime assets or checks a registry.
|
|
110
119
|
- Only a human may initiate or apply workflow upgrades.
|
|
111
|
-
-
|
|
112
|
-
- Put project-specific behaviour in project configuration or local rules,
|
|
113
|
-
|
|
114
|
-
See [Configuration](./configuration.md) for project customisation and [Command reference](./command-reference.md) for package commands.
|
|
115
|
-
|
|
120
|
+
- A status label never substitutes for test or review evidence.
|
|
121
|
+
- Put project-specific behaviour in project configuration or local rules, never in the package-managed kernel.
|
|
116
122
|
|
|
117
123
|
## Optional end-to-end loop
|
|
118
124
|
|
|
119
125
|
> [!WARNING]
|
|
120
|
-
>
|
|
126
|
+
> Experimental, pre-1.0. See [Status and stability](./loop-runbook.md#status-and-stability).
|
|
121
127
|
|
|
122
|
-
|
|
128
|
+
- With `loop.mode` enabled, `aidlc-kit loop start` (local: `./.agents/aidlc/scripts/loop.sh up`) runs one singleton daemon per project; it reads no requirement, runs only loop-owned tasks, and auto-resumes actionable ones.
|
|
129
|
+
- Add tasks with `aidlc-kit loop intake` (requirement on stdin) or the dashboard **New task**; the same ID and requirement reuse the task. There is no `loop resume`: re-activate with the dashboard **resume** or `state.mjs task status <id> --status active`.
|
|
130
|
+
- After a restart the daemon reconciles from canonical state; a consumed, stale, or mismatched checkpoint stops for manual reconciliation. A paused or handed-off task, outdated snapshot, or uncertain Git result is never auto-resumed.
|
|
131
|
+
- The loop never approves a gate: local mode uses the trusted terminal `loop-gate.mjs` or the signed-in dashboard, fleet mode only the reviewer credential.
|
|
132
|
+
- Leads and workers may be `codex`, `claude`, or `opencode`; only the container-isolated lead rejects OpenCode. Any `opencode` provider needs `AIDLC_OPENCODE_MODEL` ([Provider credentials and OpenCode](./configuration.md#provider-credentials-and-opencode)).
|
|
123
133
|
|
|
124
|
-
|
|
134
|
+
## Related
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
- [Loop setup runbook](./loop-runbook.md) — loop setup.
|
|
137
|
+
- [Local loop walkthrough](./loop-local-run.md) — local loop operation.
|
|
138
|
+
- [Command reference: `loop`](./command-reference.md#loop) — loop actions and environment.
|
|
139
|
+
- [Configuration](./configuration.md) — project, loop, and adapter settings.
|