@felixdotgo/aidlc-kit 0.1.1 → 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 +14 -13
- package/README.md +37 -43
- package/dist/assets/.agents/aidlc/docker/Dockerfile.claude +7 -0
- package/dist/assets/.agents/aidlc/docker/Dockerfile.codex +9 -0
- package/dist/assets/.agents/aidlc/docker/Dockerfile.opencode +8 -0
- package/dist/assets/.agents/aidlc/orchestrator.md +2 -2
- package/dist/assets/.agents/aidlc/phase-clarify.md +1 -1
- package/dist/assets/.agents/aidlc/phase-plan.md +2 -2
- package/dist/assets/.agents/aidlc/schemas/config.schema.json +2 -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 +261 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-commit-message.mjs +45 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-daemon.mjs +206 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-drivers.mjs +100 -14
- package/dist/assets/.agents/aidlc/scripts/lib/loop-env.mjs +279 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-cli.mjs +105 -32
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-remote.mjs +17 -1
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-supervisor.mjs +24 -7
- package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet.mjs +42 -16
- package/dist/assets/.agents/aidlc/scripts/lib/loop-git.mjs +20 -6
- package/dist/assets/.agents/aidlc/scripts/lib/loop-holder.mjs +376 -0
- package/dist/assets/.agents/aidlc/scripts/lib/loop-intake.mjs +33 -7
- 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 +116 -28
- package/dist/assets/.agents/aidlc/scripts/lib/loop-runtime.mjs +114 -12
- package/dist/assets/.agents/aidlc/scripts/lib/loop-stream.mjs +117 -0
- 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 +149 -6
- package/dist/assets/.agents/aidlc/scripts/lib/loop-supervisor.mjs +9 -1
- package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-docker.mjs +44 -6
- package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-image.mjs +64 -0
- 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 +68 -2
- 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 +168 -73
- package/dist/assets/.agents/aidlc/scripts/loop-gate.mjs +19 -7
- package/dist/assets/.agents/aidlc/scripts/loop.cmd +101 -0
- package/dist/assets/.agents/aidlc/scripts/loop.mjs +2 -1
- 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/.agents/aidlc/templates/design.md +9 -0
- package/dist/assets/.agents/aidlc/templates/intent.md +4 -0
- package/dist/assets/.agents/aidlc/templates/workplan.md +1 -1
- package/dist/assets/.agents/skills/aidlc-plan/SKILL.md +1 -1
- package/dist/assets/ui/bulma.min.css +3 -0
- package/dist/assets/ui/changes.js +83 -0
- package/dist/assets/ui/common.js +664 -0
- package/dist/assets/ui/dashboard.css +636 -0
- 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/Dockerfile +11 -3
- package/dist/services/aidlc-coordination/compose.yaml +12 -0
- package/dist/services/aidlc-coordination/package-lock.json +3 -1
- package/dist/services/aidlc-coordination/package.json +9 -4
- package/dist/services/aidlc-coordination/src/lifecycle-core.mjs +68 -2
- package/dist/services/aidlc-coordination/src/repository.mjs +66 -0
- package/dist/services/aidlc-coordination/src/server.mjs +9 -3
- package/dist/services/aidlc-coordination/test/fleet.test.mjs +21 -0
- package/dist/services/aidlc-coordination/test/server-health-auth.test.mjs +67 -0
- package/dist/src/adapters.d.ts +0 -3
- package/dist/src/adapters.js +3 -5
- package/dist/src/cli/argv.d.ts +12 -0
- package/dist/src/cli/argv.js +68 -0
- package/dist/src/cli/commands.d.ts +8 -0
- package/dist/src/cli/commands.js +159 -0
- package/dist/src/cli/loop-launcher.d.ts +47 -0
- package/dist/src/cli/loop-launcher.js +322 -0
- package/dist/src/cli/options.d.ts +25 -0
- package/dist/src/cli/options.js +32 -0
- package/dist/src/cli/prompt.d.ts +9 -0
- package/dist/src/cli/prompt.js +66 -0
- package/dist/src/cli.js +28 -191
- package/dist/src/gate.js +3 -2
- package/dist/src/installer.d.ts +14 -7
- package/dist/src/installer.js +42 -143
- package/dist/src/legacy.js +1 -0
- package/dist/src/managed-content.d.ts +7 -0
- package/dist/src/managed-content.js +15 -4
- package/dist/src/managed-planning.d.ts +65 -0
- package/dist/src/managed-planning.js +219 -0
- package/dist/src/mcp-setup.js +3 -1
- package/dist/src/model/config-contracts.d.ts +65 -0
- package/dist/src/model/config-contracts.js +1 -0
- package/dist/src/model/install-contracts.d.ts +29 -0
- package/dist/src/model/install-contracts.js +1 -0
- package/dist/src/model/lifecycle-enums.d.ts +13 -0
- package/dist/src/model/lifecycle-enums.js +1 -0
- package/dist/src/model/loop.d.ts +20 -0
- package/dist/src/model/loop.js +1 -0
- package/dist/src/model/manifest.d.ts +16 -0
- package/dist/src/model/manifest.js +1 -0
- package/dist/src/model/records.d.ts +142 -0
- package/dist/src/model/records.js +1 -0
- package/dist/src/model.d.ts +11 -264
- package/dist/src/model.js +1 -1
- package/dist/src/profiles.d.ts +2 -0
- package/dist/src/profiles.js +53 -9
- package/dist/src/state/archive-record.d.ts +9 -0
- package/dist/src/state/archive-record.js +26 -0
- package/dist/src/state/commands.d.ts +18 -0
- package/dist/src/state/commands.js +27 -0
- package/dist/src/state/domain.d.ts +9 -0
- package/dist/src/state/domain.js +9 -0
- package/dist/src/state/guards.d.ts +7 -0
- package/dist/src/state/guards.js +17 -0
- package/dist/src/state/io.d.ts +10 -0
- package/dist/src/state/io.js +35 -0
- package/dist/src/state/items.d.ts +3 -4
- package/dist/src/state/items.js +58 -57
- package/dist/src/state/lessons.js +14 -7
- package/dist/src/state/lifecycle.js +2 -2
- package/dist/src/state/lock.js +7 -6
- package/dist/src/state/memory.js +24 -12
- package/dist/src/state/{archive.js → migrate.js} +7 -7
- package/dist/src/state/partition.d.ts +15 -0
- package/dist/src/state/partition.js +90 -0
- package/dist/src/state/paths.d.ts +11 -0
- package/dist/src/state/paths.js +12 -0
- package/dist/src/state/render.js +9 -6
- package/dist/src/state/store.js +9 -15
- package/dist/src/state/transitions.js +9 -7
- package/dist/src/state/validate.js +55 -7
- package/dist/src/state.d.ts +16 -11
- package/dist/src/state.js +16 -11
- package/dist/src/task-ui.d.ts +33 -0
- package/dist/src/task-ui.js +33 -0
- 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-board.js +10 -10
- package/dist/src/upgrade.d.ts +0 -1
- package/dist/src/upgrade.js +24 -85
- package/dist/src/workflow.d.ts +4 -0
- package/dist/src/workflow.js +36 -4
- package/docs/README.md +41 -22
- package/docs/architecture.md +101 -37
- package/docs/command-reference.md +289 -52
- package/docs/configuration.md +70 -30
- package/docs/coordination-service.md +91 -30
- package/docs/design-decisions.md +87 -0
- package/docs/development.md +124 -49
- package/docs/loop-local-run.md +228 -0
- package/docs/loop-runbook.md +214 -0
- package/docs/operating-workflow.md +55 -42
- package/docs/testing-and-release.md +72 -49
- package/docs/troubleshooting.md +221 -0
- package/package.json +4 -1
- package/dist/src/ledger.d.ts +0 -22
- package/dist/src/ledger.js +0 -119
- package/dist/src/state/shared.d.ts +0 -29
- package/dist/src/state/shared.js +0 -71
- package/dist/src/tracker.d.ts +0 -36
- package/dist/src/tracker.js +0 -44
- /package/dist/src/state/{archive.d.ts → migrate.d.ts} +0 -0
package/docs/development.md
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
# Development guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Local setup, dogfooding, source ownership, and the rules that keep package runtime and installed workflow aligned. To use the workflow in your own project, start at the [documentation index](./README.md).
|
|
4
4
|
|
|
5
5
|
## Requirements and dependencies
|
|
6
6
|
|
|
7
|
-
- Node.js 20.17 or newer
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Development uses TypeScript and `@types/node` as declared in `package.json`.
|
|
7
|
+
- Node.js 20.17 or newer; npm installs the dev dependencies (TypeScript, `@types/node`).
|
|
8
|
+
- `@inquirer/prompts` is the only runtime dependency; installed lifecycle scripts are dependency-free.
|
|
9
|
+
- Codex, Claude Code, or OpenCode: only for real evaluator drivers; OpenCode also needs `AIDLC_OPENCODE_MODEL` (`provider/model[#variant]`).
|
|
11
10
|
|
|
12
11
|
```sh
|
|
13
12
|
npm install
|
|
14
13
|
```
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
## Platform support
|
|
16
|
+
|
|
17
|
+
| Platform | Status | Notes |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Linux | Supported | Full CI coverage; Docker worker isolation available. |
|
|
20
|
+
| macOS | Supported | Full test coverage; POSIX shell recipes apply. |
|
|
21
|
+
| Windows | Best-effort | Use WSL or Git Bash for shell recipes. win32 separators handled in `src/state/guards.ts`, `src/profiles.ts`, installed `lib/store.mjs` and `context-runtime.mjs`; state lock liveness via `process.kill(pid, 0)`. Not in CI. |
|
|
22
|
+
| Loop / fleet | Linux only | Needs Docker and a POSIX shell; `loop-local-workers.mjs` rejects other hosts. E2e tests need `AIDLC_TEST_WORKER_IMAGE` and `AIDLC_WORKER_DOCKER_IMAGE`. |
|
|
17
23
|
|
|
18
24
|
## Repository layout
|
|
19
25
|
|
|
20
26
|
```text
|
|
21
27
|
assets/aidlc/ Source workflow contracts, schemas, and installed scripts
|
|
22
28
|
skills/ Source thin phase adapters
|
|
23
|
-
src/
|
|
29
|
+
src/ Package CLI (src/cli/), installer, shared planning core, lifecycle domain (src/model/, src/state/), profiles, migrations
|
|
24
30
|
dev/evaluator/ Development-only evaluator harness and runners
|
|
25
31
|
scripts/build-assets.mjs Bundles workflow assets for package distribution
|
|
26
32
|
test/unit/ Unit and installed-runtime parity tests
|
|
@@ -28,25 +34,22 @@ docs/ User, operator, and contributor documentation
|
|
|
28
34
|
dist/ Generated TypeScript and bundled assets; do not hand-edit
|
|
29
35
|
```
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
Three layouts: source (`assets/aidlc/`, `skills/`), bundle (`dist/assets/.agents/`), installed (consumer `.agents/aidlc/` and `.agents/skills/`). Say which you mean.
|
|
32
38
|
|
|
33
39
|
## Local commands
|
|
34
40
|
|
|
35
41
|
| Command | Purpose |
|
|
36
42
|
| --- | --- |
|
|
37
|
-
| `npm run build` |
|
|
43
|
+
| `npm run build` | Bundle workflow assets and compile TypeScript into `dist/`. |
|
|
44
|
+
| `npm run sync-core` | Copy `assets/aidlc/scripts/lib/store.mjs` to `services/aidlc-coordination/src/lifecycle-core.mjs` byte-identically. |
|
|
38
45
|
| `npm run lint` | Type-check without emitting files. |
|
|
39
|
-
| `npm test` | Build, then run
|
|
40
|
-
| `node --test dist/test/unit/<file>.test.js` | Run
|
|
41
|
-
| `npm run release:check` |
|
|
42
|
-
|
|
43
|
-
Run the narrowest relevant test while iterating, then run `npm test` and `npm run lint` before handing off a non-trivial change. See [Testing and release](./testing-and-release.md) for the package smoke test and evaluator.
|
|
46
|
+
| `npm test` | Build, then run all compiled unit tests (Node test runner). |
|
|
47
|
+
| `node --test dist/test/unit/<file>.test.js` | Run one compiled test after building. |
|
|
48
|
+
| `npm run release:check` | Release-evidence policy check. |
|
|
44
49
|
|
|
45
50
|
## Local build and registry-free installation
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Run the following POSIX shell commands from the repository root:
|
|
52
|
+
Install the checkout's assets into a disposable consumer project via the compiled CLI (no `npm install`, `npx`, or registry). From the repository root:
|
|
50
53
|
|
|
51
54
|
```sh
|
|
52
55
|
AIDLC_REPO="$(pwd)"
|
|
@@ -62,59 +65,131 @@ node "$AIDLC_LOCAL_PROJECT/.agents/aidlc/scripts/state.mjs" task list --root "$A
|
|
|
62
65
|
printf 'Local test project: %s\n' "$AIDLC_LOCAL_PROJECT"
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
- Use a new empty directory each time (reuse across versions triggers the human-only upgrade protection); remove it manually. On Windows, create it in PowerShell and pass the absolute path.
|
|
69
|
+
- Do not target a real project unless its managed files and state are intentional test targets.
|
|
70
|
+
- This checks the compiled checkout only, not the published allowlist, bin metadata, or tarball exclusions; run the [package smoke test](./testing-and-release.md#package-smoke-test) before release.
|
|
71
|
+
|
|
72
|
+
## Run `npx` from a local package archive
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
npm pack
|
|
76
|
+
npx --package felixdotgo-aidlc-kit-0.3.0.tgz -- aidlc-kit init .
|
|
77
|
+
```
|
|
66
78
|
|
|
67
|
-
|
|
79
|
+
Run from the archive's directory; pass a disposable project instead of `.` to avoid writing into the current directory.
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
## Dogfooding this repository
|
|
70
82
|
|
|
71
|
-
|
|
83
|
+
`.agents/` is gitignored; each contributor installs the repository's own workflow from the checkout.
|
|
72
84
|
|
|
73
|
-
|
|
85
|
+
### Install the workflow from source
|
|
74
86
|
|
|
75
87
|
```sh
|
|
76
|
-
npm
|
|
77
|
-
|
|
88
|
+
npm install
|
|
89
|
+
npm run build
|
|
90
|
+
node dist/src/cli.js init . --agent <codex|claude|opencode> --loop-mode off --yes
|
|
78
91
|
```
|
|
79
92
|
|
|
80
|
-
|
|
93
|
+
Edit `.agents/config.json` as below (`commands` as executable-and-argument arrays; your adapter id → `"scripted"` in `agentState`), then `node dist/src/cli.js profile validate .`.
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"commands": {
|
|
98
|
+
"build": { "command": "npm", "args": ["run", "build"] },
|
|
99
|
+
"test": { "command": "npm", "args": ["test"] },
|
|
100
|
+
"lint": { "command": "npm", "args": ["run", "lint"] }
|
|
101
|
+
},
|
|
102
|
+
"agentState": { "opencode": "scripted" }
|
|
103
|
+
}
|
|
104
|
+
```
|
|
81
105
|
|
|
82
|
-
|
|
106
|
+
### Check for drift and re-sync
|
|
83
107
|
|
|
84
|
-
|
|
108
|
+
After changing `assets/aidlc/`, check for a stale install (any output means stale; symptom: `loop: Isolated local worker dispatcher is not integrated; loop execution is unavailable`):
|
|
85
109
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
110
|
+
```sh
|
|
111
|
+
diff -rq assets/aidlc/scripts .agents/aidlc/scripts
|
|
112
|
+
```
|
|
89
113
|
|
|
90
|
-
|
|
114
|
+
Re-sync is a human-only upgrade (TTY required); stop the loop daemon first (`node dist/src/cli.js loop down --root .` or `loop stop`), then re-run `diff -rq`:
|
|
91
115
|
|
|
92
|
-
|
|
116
|
+
```sh
|
|
117
|
+
npm run build
|
|
118
|
+
node dist/src/cli.js upgrade . --dry-run # preview the plan
|
|
119
|
+
node dist/src/cli.js upgrade . # type the package version when prompted
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Run the loop from a source checkout
|
|
123
|
+
|
|
124
|
+
> [!WARNING]
|
|
125
|
+
> Experimental, pre-1.0. See [Status and stability](./loop-runbook.md#status-and-stability).
|
|
126
|
+
|
|
127
|
+
In place of `npx --package @felixdotgo/aidlc-kit@<version> aidlc-kit …`, run the compiled CLI after `npm run build`:
|
|
93
128
|
|
|
94
|
-
|
|
129
|
+
| Task | Command |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| Start the daemon and dashboard | `node dist/src/cli.js loop up --root .` |
|
|
132
|
+
| Check daemon and task status | `node dist/src/cli.js loop status --root . [--task-id <task-id>]` |
|
|
133
|
+
| Serve only the dashboard | `node dist/src/cli.js ui .` |
|
|
134
|
+
|
|
135
|
+
See [Local loop walkthrough](./loop-local-run.md) and [Command reference](./command-reference.md#loop).
|
|
95
136
|
|
|
96
|
-
|
|
137
|
+
## Ownership boundaries
|
|
138
|
+
|
|
139
|
+
- `.agents/aidlc/`: package-managed kernel assets.
|
|
140
|
+
- `.agents/project/`: project-owned config, profiles, rules, and evaluation material.
|
|
141
|
+
- `.agents/data/`: project-owned task state and derived data; never add a second lifecycle board or hand-edit it.
|
|
142
|
+
|
|
143
|
+
## Mirrored runtime behaviour
|
|
144
|
+
|
|
145
|
+
- TypeScript powers the package CLI; installed projects use the dependency-free mirror in `assets/aidlc/scripts/`. Lifecycle, state, gate, profile, or context changes keep parity and add coverage for both.
|
|
146
|
+
- A public configuration or schema change updates validator, JSON schema, installed assets, package inventory, docs, and tests together.
|
|
147
|
+
- Dual-core sync rule: after editing `assets/aidlc/scripts/lib/store.mjs`, run `npm run sync-core` so `services/aidlc-coordination/src/lifecycle-core.mjs` stays byte-identical.
|
|
97
148
|
|
|
98
149
|
## Code style and conventions
|
|
99
150
|
|
|
100
|
-
|
|
151
|
+
Baseline (decision `D1-convention-standard`, task `refactor-source-readability`):
|
|
101
152
|
|
|
102
|
-
- **Strict TypeScript
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
105
|
-
- **Naming.**
|
|
106
|
-
- **
|
|
107
|
-
- **Dependencies.** Pass
|
|
108
|
-
- **Public API.**
|
|
109
|
-
- **Behavior preservation.** Refactors
|
|
110
|
-
- **Verification.**
|
|
153
|
+
- **Strict TypeScript.** Keep `strict`; enforce via `npm run lint` (`tsc --noEmit`). No ESLint/Prettier or other tooling deps.
|
|
154
|
+
- **Size.** ≤250 lines per file, ≤60 per function; split by responsibility.
|
|
155
|
+
- **Modules.** One responsibility each; a facade may re-export a public API (e.g. `src/state.ts`).
|
|
156
|
+
- **Naming.** camelCase functions/variables, `PascalCase` types, `SCREAMING_SNAKE_CASE` constants; file name matches primary export.
|
|
157
|
+
- **Errors.** Typed one-line errors; never swallow; validate inputs before I/O.
|
|
158
|
+
- **Dependencies.** Pass fetch, clock, environment explicitly; no module-level mutable state.
|
|
159
|
+
- **Public API.** JSDoc exported symbols with non-obvious contracts.
|
|
160
|
+
- **Behavior preservation.** Refactors never change CLI output, state schema, file layout, or installed assets; run parity tests.
|
|
161
|
+
- **Verification.** Narrowest test while iterating; `npm test` + `npm run lint` before handoff.
|
|
111
162
|
|
|
112
163
|
## Safe implementation rules
|
|
113
164
|
|
|
114
|
-
- Resolve
|
|
115
|
-
- Keep
|
|
165
|
+
- Resolve project-relative paths through the shared path helpers; reject traversal and symlink escape.
|
|
166
|
+
- Keep install, migration, and upgrade plans deterministic and conflict-first.
|
|
116
167
|
- Preserve project-owned configuration and state when changing managed assets.
|
|
117
|
-
-
|
|
118
|
-
-
|
|
168
|
+
- Never add remote profile discovery, runtime asset downloads, executable plugin hooks, registry checks, or shell-string execution.
|
|
169
|
+
- Human-gated lifecycle transitions are atomic, auditable state operations.
|
|
170
|
+
- Read [Architecture](./architecture.md) before changing a module boundary, migration, installed script, or bundle layout.
|
|
171
|
+
|
|
172
|
+
## Contributing to prompt assets
|
|
173
|
+
|
|
174
|
+
Prompt assets are the contracts under `assets/aidlc/` (`orchestrator.md`, `phase-*.md`) that `context.mjs` turns into phase packets.
|
|
175
|
+
|
|
176
|
+
- Keep them compact: default packet budget is 16,000 characters (`config.context.maxChars`); optional rules and diagnostics drop first.
|
|
177
|
+
- Never truncated (generation fails instead): next-action contract, phase contract, approved decisions, safety/spec anchors, task state, latest applicable evidence.
|
|
178
|
+
- Heading invariants enforced by `gate-check.mjs`:
|
|
179
|
+
- Intent (`G0_confirm`): `## 📋 Problem`, `## 🗺️ Affected areas`, `## 💭 Assumptions`, `## ❓ Open questions`, `## 🎯 Scope`.
|
|
180
|
+
- Design (`G1_review`): `## 🧩 Solution per affected area`, `## 📌 Spec traceability`, `## 🔗 Cross-service contracts`, `## ⚠️ Risks / edge cases`.
|
|
181
|
+
- After changing contracts, run `npm run release:check` (`--adapters opencode`) and the evaluator suite; update docs and tests in the same change. Rationale: [Design decisions](./design-decisions.md) D6.
|
|
182
|
+
|
|
183
|
+
## Documentation conventions
|
|
184
|
+
|
|
185
|
+
Follow [Adding or changing a page](./README.md#adding-or-changing-a-page). In addition:
|
|
186
|
+
|
|
187
|
+
- A public contract change (command, config field, schema, installed asset) updates its guide and the asserting test in the same change.
|
|
188
|
+
- Never duplicate canonical agent instructions from `assets/aidlc/`; link to the installed asset.
|
|
189
|
+
|
|
190
|
+
## Related
|
|
119
191
|
|
|
120
|
-
|
|
192
|
+
- [Testing and release](./testing-and-release.md)
|
|
193
|
+
- [Architecture](./architecture.md)
|
|
194
|
+
- [Design decisions](./design-decisions.md)
|
|
195
|
+
- [Configuration](./configuration.md)
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Local loop walkthrough
|
|
2
|
+
|
|
3
|
+
Day-to-day operation of the loop in `local` mode on one machine: start the daemon, add tasks, watch, answer gates, resume. To enable the loop first, follow the [Loop setup runbook](./loop-runbook.md#local-mode).
|
|
4
|
+
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> Experimental, pre-1.0. See [Status and stability](./loop-runbook.md#status-and-stability).
|
|
7
|
+
|
|
8
|
+
Commands use the published package (`npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit …`) or the installed launcher `./.agents/aidlc/scripts/loop.sh`; both drive the installed `loop-entry.mjs`. Source checkout: [Dogfooding this repository](./development.md#dogfooding-this-repository).
|
|
9
|
+
|
|
10
|
+
## How the loop works
|
|
11
|
+
|
|
12
|
+
- The **lead** runs `clarify` (gate `G0_confirm`), `plan` (`G1_review`), and `wrap` on the host, no Docker; **workers** run only `build` items (`G2_codereview`), isolated in Docker. Gates: [Operating the workflow](./operating-workflow.md).
|
|
13
|
+
- Each iteration reads `state.mjs task next`, runs one agent turn on the returned `nextAction`, re-reads canonical state, and updates the checkpoint/fingerprint.
|
|
14
|
+
- The loop **stops at every gate** and **never self-approves**; only a human on the trusted terminal or the signed-in dashboard approves.
|
|
15
|
+
- It also stops after the per-run `maxTurns` budget (a resumed run gets a fresh one), after `maxStallTurns` unchanged turns, or at `blocked`/`terminal`/`complete` (`loop.limits`: [Configuration](./configuration.md#optional-loop-configuration)).
|
|
16
|
+
- Config alone runs nothing; only `loop start` or `loop.sh up` runs the loop.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- Linux host with Docker (`docker info` must pass for the build phase) and a POSIX shell; Node.js ≥ 20.17.
|
|
21
|
+
- Lead provider CLI (`opencode`, `codex`, or `claude`) on the host `PATH`, matching `loop.agents.lead`.
|
|
22
|
+
- If any provider is `opencode`: `AIDLC_OPENCODE_MODEL` naming a model listed by `opencode models`.
|
|
23
|
+
- Worker credentials per provider/model: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENCODE_API_KEY`. The worker image is built automatically ([Worker Docker image](#worker-docker-image)).
|
|
24
|
+
|
|
25
|
+
## Set the environment
|
|
26
|
+
|
|
27
|
+
Put loop variables in `.agents/loop.env` (installed as a commented template, git-ignored through `.agents/.gitignore`) or `export` them in the shell that starts the daemon; exported values win. `loop start`, `loop up`, and a dashboard-started daemon load the file.
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
# .agents/loop.env
|
|
31
|
+
# Required for opencode unless "model" is set in opencode.json; use a model from `opencode models`:
|
|
32
|
+
AIDLC_OPENCODE_MODEL=<provider/model>
|
|
33
|
+
# Worker key for the build phase; read from ~/.local/share/opencode/auth.json when unset:
|
|
34
|
+
# OPENCODE_API_KEY=...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
./.agents/aidlc/scripts/loop.sh check # what the daemon will see; secrets are never printed
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`AIDLC_LOOP_EVENT_LOG` is set to `.agents/data/loop/ui-events.jsonl` automatically. All variables: [runbook](./loop-runbook.md#step-2--fill-in-agentsloopenv); lookup order: [Command reference](./command-reference.md#loop).
|
|
42
|
+
|
|
43
|
+
> [!IMPORTANT]
|
|
44
|
+
> A running daemon keeps the environment it started with. After editing `.agents/loop.env`, run `loop.sh down`, then `loop.sh up`; `loop up` warns when the file changed after the daemon started.
|
|
45
|
+
|
|
46
|
+
## Start the daemon and add tasks
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
./.agents/aidlc/scripts/loop.sh up # --open launches the browser; --no-ui starts only the daemon
|
|
50
|
+
./.agents/aidlc/scripts/loop.sh status # daemon, dashboard, environment
|
|
51
|
+
./.agents/aidlc/scripts/loop.sh logs # follow the daemon log
|
|
52
|
+
./.agents/aidlc/scripts/loop.sh down # stop both; --now cancels the running turn
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`Ctrl-C` in the `up` terminal closes only the dashboard. Windows: `.agents\aidlc\scripts\loop.cmd`, same commands.
|
|
56
|
+
|
|
57
|
+
Underneath, `loop start` runs the persistent daemon in the foreground and reads no requirement; one per project (a second fails with `Loop daemon already running (pid N)`):
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop start
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- The daemon runs only **loop-owned** tasks: created through loop intake (`.agents/data/tasks/<id>/runtime/intake.json`) or holding a loop run record (`runtime/run.json`). An interactively created task (`state.mjs task create`) is never picked up, so the daemon cannot race an interactive lead.
|
|
64
|
+
- It runs one bounded run per actionable task in turn and keeps polling after a gate or completion.
|
|
65
|
+
|
|
66
|
+
Add a loop-owned task:
|
|
67
|
+
|
|
68
|
+
- **Dashboard → New task** creates the task and starts the daemon if none is running.
|
|
69
|
+
- **Terminal intake** reads the requirement from stdin (never an argument), at most 8192 bytes; id and title derive from the first line (`--task-id`/`--title` override).
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
echo "Add PDF report export" | npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop intake
|
|
73
|
+
echo "Add PDF report export" | node .agents/aidlc/scripts/loop-entry.mjs intake "" . # installed entry point
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- Intake refuses (creates nothing) while an **interactive** task is actionable; finish or pause it first.
|
|
77
|
+
|
|
78
|
+
Stopping (`Ctrl-C` or `SIGTERM`) is staged: first signal stops after the current turn, second cancels the in-flight agent turn, third exits immediately.
|
|
79
|
+
|
|
80
|
+
- A stopped run is recorded as `stopped` (the task is **not** paused) and resumes on the next `loop start`. A terminal `Ctrl-C` also reaches the agent child, so the turn usually ends on the first press; still `stopped`, not a transport failure.
|
|
81
|
+
- `aidlc-kit loop start` stays in the foreground for the whole shutdown (forwards `SIGTERM`, lets the terminal deliver `Ctrl-C`), so later presses reach the daemon.
|
|
82
|
+
|
|
83
|
+
## Watch status
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit loop status --task-id <task-id>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Prints `authority`, `record` (the loop run record), and `nextAction` (`classification`: `run_phase`, `await_user`, `blocked`, `complete`, …).
|
|
90
|
+
|
|
91
|
+
## Approve a gate or send feedback
|
|
92
|
+
|
|
93
|
+
Answer a gate on the trusted host terminal or the signed-in dashboard, never from the lead or a worker, never with piped input:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
node .agents/aidlc/scripts/loop-gate.mjs <task-id>
|
|
97
|
+
# type: approve -> approves this exact review and advances the phase
|
|
98
|
+
# type: <any other text> -> feedback: the task stays at this gate
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- Prints the exact review (task, phase, gate, artifact digests, and at `G2_codereview` the integration commit), then prompts `Type approve to approve this exact review, or type feedback to send guidance back to the loop:`.
|
|
102
|
+
- **`approve`** is the only answer that moves the task forward; if the review changes while you type, it fails closed.
|
|
103
|
+
- **Any other text is feedback**: recorded as evidence `Cancelled gate wait at <gate>: <feedback>`; the task returns to `active` at the same gate, and the next lead turn revises the review and re-presents the **same** gate.
|
|
104
|
+
- The dashboard detail page offers the same actions, **Send feedback (stay at gate)** and **✓ Approve** ([dashboard](#use-the-web-dashboard)).
|
|
105
|
+
|
|
106
|
+
## Resume after a gate or a pause
|
|
107
|
+
|
|
108
|
+
There is **no `loop resume`** in either mode; the daemon auto-resumes every task whose `nextAction` is `run_phase` (*actionable*).
|
|
109
|
+
|
|
110
|
+
- **After approving a gate**: nothing; the next poll runs the next lead turn.
|
|
111
|
+
- **After a pause** (agent transport failure, per-run turn limit): the task is `paused` (`nextAction` `blocked`) and skipped. Fix the cause, then press **resume** on the dashboard or run the command below; the next poll (default about 5 s) picks it up.
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
node .agents/aidlc/scripts/state.mjs task status <task-id> --status active # or: loop-entry.mjs resume-task <task-id> .
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- `aidlc-kit loop resume` and `loop-entry.mjs resume` fail closed with `loop resume is removed; the daemon auto-resumes actionable tasks — run 'loop start', and re-activate a paused task from the dashboard (resume) or with the task status command`.
|
|
118
|
+
|
|
119
|
+
## Follow the streaming log
|
|
120
|
+
|
|
121
|
+
Progress goes to **stderr** (stdout stays the final JSON):
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
━━ turn 1 · phase clarify · agent opencode ━━
|
|
125
|
+
› tool: grep
|
|
126
|
+
› tool: read
|
|
127
|
+
› command completed (exit 0)
|
|
128
|
+
<stream text from the lead>
|
|
129
|
+
━━ turn done ━━
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
A clarify or plan turn can take minutes without output. At a gate the daemon prints the **gate view** and moves on. Every event carries its `taskId`:
|
|
133
|
+
|
|
134
|
+
| Event | Meaning |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| `turn_start` / `turn_end` | Turn boundary, with phase and agent. |
|
|
137
|
+
| `agent_text` | Lead text, capped at 4096 characters per chunk. |
|
|
138
|
+
| `agent_tool` | Tool in use (`grep`, `read`, `glob`, `shell`, …). |
|
|
139
|
+
| `lifecycle_command` | Shell result and exit code. |
|
|
140
|
+
| `gate` | Gate view. |
|
|
141
|
+
| `daemon_start`, `daemon_poll`, `daemon_turn`, `loop_stopped` | Daemon lifecycle. |
|
|
142
|
+
| `daemon_poll_error` | The task list could not be read; the daemon keeps polling. |
|
|
143
|
+
| `daemon_turn_error` | A task run threw (or ended `blocked`/`reconcile`); retried with exponential backoff (poll interval doubled per failure, capped at 10 minutes). |
|
|
144
|
+
| `build_deferred` | A ready build item held for a later batch. `reason`: overlaps another item, busy path held by an active assignment, unresolved assignment, or `capacity` (one item per configured worker per batch). |
|
|
145
|
+
|
|
146
|
+
## Use the web dashboard
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
npx --package @felixdotgo/aidlc-kit@0.3.0 aidlc-kit ui . # loop.sh up starts the same dashboard
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Branded **Loop**, binds `127.0.0.1:4173` by default and prints `Open: http://127.0.0.1:4173` (or pass `--open`).
|
|
153
|
+
|
|
154
|
+
**Access**
|
|
155
|
+
|
|
156
|
+
- There is no login or session token: the dashboard is for a trusted local machine or internal network. Mutating actions (new task, resume, gate feedback, gate approve) work right away from the page.
|
|
157
|
+
- Another origin, a foreign `Host` header, or a request that does not look like the dashboard's own `fetch` gets `403` ([Dashboard access](./command-reference.md#dashboard-access)). Binding to a non-loopback address prints a warning that the dashboard has no authentication.
|
|
158
|
+
|
|
159
|
+
**Header and updates**
|
|
160
|
+
|
|
161
|
+
- Header: authority (`authority · local`), daemon state, and a bell listing tasks needing review. The daemon pill turns amber (**daemon · N errors**) while a turn or poll keeps failing; hover for messages.
|
|
162
|
+
- Pages poll about every 1.5 s and patch only what changed. An unreachable server shows a **reconnecting…** pill and polling backs off.
|
|
163
|
+
- A new gate updates the bell, the tab title (`(2) Loop`), and a **Review needed** toast; with **Settings → notifications** on, a browser notification too (permission is asked only then).
|
|
164
|
+
- Light/dark follows the system unless pinned in **Settings**. Shortcuts: <kbd>N</kbd> new task, <kbd>/</kbd> search, <kbd>Esc</kbd> close.
|
|
165
|
+
|
|
166
|
+
**Where things live**
|
|
167
|
+
|
|
168
|
+
| Where | What |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| Header bell | Tasks waiting at a gate (5 newest; **Load more**). A `blocked_on_user` card shows **review**, which opens the detail page. |
|
|
171
|
+
| Card | Title only (id on hover and in search). Click opens the side panel and adds `?task=<task-id>` to the URL (or the full page, per **Settings**); ctrl/cmd/middle-click opens the full page in a new tab, shift-click in this tab. |
|
|
172
|
+
| Side panel | Stepper (clarify → plan → build → wrap → done), artifacts, last 20 important log lines, a copy button for the id, **Open full page ↗**; at a gate, **Open review →**. |
|
|
173
|
+
| Detail page `/tasks/<task-id>` | The only place with gate approval and feedback; containers, full live log — the one place to follow everything a task does. |
|
|
174
|
+
| Settings (header ⚙) | Browser-only preferences: theme, live-update interval or pause, browser notifications for reviews, live log defaults, diff wrap / ignore whitespace, container log tail size, card click target. **Reset to defaults** restores them. |
|
|
175
|
+
| Containers (detail page) | Every worker container the loop ran for the task (local or fleet; same layout), newest first: worker, item, turn, `running` / `exited <code>` / `signal`, start time and duration, host when recorded elsewhere. **Log** opens the raw output of that assignment (all turns, stdout and stderr unredacted) with **Follow** while it runs; the tail size comes from Settings. `docker · unavailable` means the state comes from the index only. |
|
|
176
|
+
| Review panel (while `blocked_on_user`) | **Feedback** textarea + **Send feedback (stay at gate)**; **Approve** note + **✓ Approve** (popup; only **Confirm approve** sends). |
|
|
177
|
+
| Approve semantics | The note is audit provenance, never feedback. A moved gate is refused with `409`. After feedback a **feedback pending** pill shows until approval; failing structural checks replace the gate view. |
|
|
178
|
+
| New task (side panel) | Markdown editor. **Create task** runs loop intake and starts the daemon if none runs (stderr → `.agents/data/loop/daemon.log`); a toast shows the id or the intake error. |
|
|
179
|
+
| Search and filters | Browser-only; never call the API. The **done** column shows 8 recent tasks; **Show N more** expands it. |
|
|
180
|
+
| resume | On `paused` tasks; sets them back to `active`. |
|
|
181
|
+
| Live log (detail page) | Lines `time · actor · what happened`, grouped by turn. **Important** (default) hides bookkeeping, **All** shows everything, **Raw JSON** shows the events. |
|
|
182
|
+
| Changes `/tasks/<id>/changes` | Files and diff per work item from the commits workers recorded; otherwise the task range from the task's `baseCommit` to its `finalCommit` (or `HEAD` plus the working tree while open) — so a task driven from the terminal, or a finished task whose worker worktrees are gone, still shows its changes; last resort, the uncommitted working tree. **Wrap lines** and **Ignore whitespace** toggles. |
|
|
183
|
+
|
|
184
|
+
Live log files: the log replays the last 200 events of `.agents/data/tasks/<task-id>/runtime/events.jsonl` (1 MiB, one `.1` generation; a file an older version left in `.agents/data/loop/events/` is read until `loop migrate-data` moves it), then follows live; older tasks fall back to the global `.agents/data/loop/ui-events.jsonl` (rotated to `.jsonl.1` at 5 MB), written only when `AIDLC_LOOP_EVENT_LOG` points at it. Container output is separate: `.agents/data/tasks/<task-id>/runtime/workers/<assignment>.log` (5 MiB, one `.log.1` generation) next to `index.json`, never committed. **Docs** in the header opens these guides.
|
|
185
|
+
|
|
186
|
+
## Worker Docker image
|
|
187
|
+
|
|
188
|
+
The build phase runs workers in Docker containers whose image contains the provider CLI (`opencode`, `codex`, or `claude`):
|
|
189
|
+
|
|
190
|
+
- Dockerfiles ship with the package (`assets/aidlc/docker/Dockerfile.<provider>`); the supervisor **auto-builds** a missing image before preflight and records the name in `.agents/config.json` (`loop.workerImage`), so `AIDLC_WORKER_DOCKER_IMAGE` is not needed.
|
|
191
|
+
- Build ahead of time (default provider `opencode`; default tag `aidlc-worker-<provider>:local`):
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
npx @felixdotgo/aidlc-kit loop worker-image --provider opencode # or codex | claude
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
- Images named `aidlc-worker-*-test:local` contain only a fake CLI for tests. The real image is `node:24-bookworm-slim` (Debian/glibc, because `opencode` is a dynamically linked ELF) with the CLI from `npm install -g`.
|
|
198
|
+
- Each worker container is started with labels `aidlc.task`, `aidlc.item`, `aidlc.worker`, and `aidlc.assignment` (`docker ps --filter label=aidlc.task=<task-id>` lists a task's workers), and its stdout/stderr are teed unredacted into the task's `runtime/workers/` log while the live log keeps only summaries.
|
|
199
|
+
- The container runs non-root and `--read-only`, so the CLI must be on the system `PATH` (npm global → `/usr/local/bin`). `opencode` uses `@opencode/cli` (OpenCode 2), **not** `opencode-ai` (OpenCode 1).
|
|
200
|
+
- Worker credentials come from the environment, per model: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENCODE_API_KEY`. Preflight runs `docker run … --entrypoint <cli> --version`; a missing or invalid binary fails before any worker starts.
|
|
201
|
+
|
|
202
|
+
## Quick lead-only run
|
|
203
|
+
|
|
204
|
+
A single lead with no Docker or workers, using the installed loop runner directly:
|
|
205
|
+
|
|
206
|
+
```sh
|
|
207
|
+
export AIDLC_OPENCODE_MODEL=<provider/model>
|
|
208
|
+
|
|
209
|
+
node .agents/aidlc/scripts/loop.mjs run <task-id> --agent opencode --max-turns 12 --root .
|
|
210
|
+
node .agents/aidlc/scripts/loop.mjs status <task-id> --root .
|
|
211
|
+
node .agents/aidlc/scripts/loop.mjs resume <task-id> --root .
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The JSON output reports `status` (`gate`, `paused`, `blocked`, or `complete`) with `stopReason` and `nextAction`.
|
|
215
|
+
|
|
216
|
+
## Troubleshooting
|
|
217
|
+
|
|
218
|
+
- [Loop stops, pauses, or never starts](./troubleshooting.md#loop-stops-pauses-or-never-starts)
|
|
219
|
+
- [Dashboard live log or actions do nothing](./troubleshooting.md#dashboard-live-log-or-actions-do-nothing)
|
|
220
|
+
- [Loop leases, locks and claims](./troubleshooting.md#loop-leases-locks-and-claims) — "already running", unapprovable gate, stuck claims
|
|
221
|
+
- [Build items deferred](./troubleshooting.md#build-items-deferred-or-build-dispatch-failure-unresolved-assignment) — `build_deferred`, `build dispatch failure`
|
|
222
|
+
|
|
223
|
+
## Related
|
|
224
|
+
|
|
225
|
+
- [Loop setup runbook](./loop-runbook.md) — enabling and configuring the loop.
|
|
226
|
+
- [Configuration](./configuration.md#optional-loop-configuration) — `loop.*` fields.
|
|
227
|
+
- [Command reference](./command-reference.md#loop) — all loop flags and environment variables.
|
|
228
|
+
- [AI-DLC Coordination service](./coordination-service.md) — fleet (multi-machine) deployment.
|