taskforce-loop-engineering 0.9.1 → 0.12.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.
@@ -0,0 +1,444 @@
1
+ # Taskforce Loop Engineering Architecture
2
+
3
+ ## P3 derived operator plane
4
+
5
+ `lib/operator-dashboard.mjs` is a one-way projection boundary above durable Loop artifacts. It reads P0 gate, P1 reservation, P2 control-plane, queue and project files and emits projection schema v1. It never calls their mutation functions and never serves raw artifacts. Live HTTP and static export share the same projection function, so the UI cannot become a source of truth.
6
+
7
+ Loop engineering wraps repeated agent work in a small, inspectable cycle:
8
+
9
+ ```text
10
+ Trigger -> Load state -> Sense -> Choose -> Act/Check -> Verify -> Record -> Stop or schedule next run
11
+
12
+ ## Parked waits and recovery
13
+
14
+ Human-Gate Lifecycle v2 stores both human-input and external-condition waits in
15
+ the existing `waiting/` queue directory. A v2 task has a `parked` envelope with
16
+ its wait kind, policy, reminder/escalation counters, authorization snapshot,
17
+ recovery proof hash, and exactly-once execution boundary. `queue-wait-tick`
18
+ writes one evidence artifact per notification sequence before another process
19
+ can advance that sequence; repeated or restarted ticks are throttled or observe
20
+ the existing evidence. A timeout parks and escalates—it is not task failure and
21
+ does not authorize action retry.
22
+
23
+ Recovery is a separate transition. `queue-wait-resume` requires an explicit
24
+ verified signal, hashes the signal into durable state, preserves authorization
25
+ and execution metadata, then atomically writes the task back to `inbox/` before
26
+ removing the waiting copy. Repeating resume after a crash returns
27
+ `already_resumed`, keeping the action boundary exactly once.
28
+ ```
29
+
30
+ This package implements the conservative foundation of that idea for OpenClaw
31
+ and Codex-style agents:
32
+
33
+ - deterministic CLI runner, no hidden model call
34
+ - JSON loop specs
35
+ - local state and append-only run artifacts
36
+ - command, file, and structured JSON value checks
37
+ - circuit breaker for repeated failures
38
+ - generic queue runner for explicit task handoffs
39
+ - assisted code queues that isolate edits in git worktrees
40
+ - cron wrapper that stays silent on success and surfaces non-zero exits
41
+ - bundled skill that teaches agents when to use the loop workflow
42
+
43
+ Structured `json-value` checks use RFC 6901 pointers and preserve expected and
44
+ actual values in run evidence. The read-only `repair-plan` command turns failed
45
+ checks into review findings; it deliberately has no apply mode.
46
+
47
+ ## Levels
48
+
49
+ - `L1`: report-only. May run read-only checks and write local run artifacts.
50
+ - `L2`: assisted action. May prepare local changes in isolated worktrees,
51
+ run verification, and leave artifacts for human review.
52
+ - `L3`: unattended-capable. Intended for future explicit allowlists,
53
+ verification budgets, human gates, and proven run history.
54
+
55
+ The loop-spec runner remains designed around `L1`. The queue runner supports a
56
+ bounded `L2` mode through `worktree.enabled`: it creates local worktrees and
57
+ records evidence, but it does not push, merge, delete worktrees, or perform
58
+ external writes.
59
+
60
+ ## Dev / Acceptance Split
61
+
62
+ The next queue architecture for non-trivial tasks is a two-team loop:
63
+
64
+ ```text
65
+ Task intake
66
+ -> task contract
67
+ -> acceptance plan + development plan
68
+ -> development checkpoint
69
+ -> acceptance review
70
+ -> development revision
71
+ -> final judge
72
+ -> report / gate / apply
73
+ ```
74
+
75
+ Development owns implementation and local evidence. Acceptance owns proof:
76
+ functional checks, regression checks, edge cases, negative tests, manual review,
77
+ and automation suggestions. The final judge is separate from both and verifies
78
+ that the result still matches the original task contract and risk gates.
79
+
80
+ The important artifact names are:
81
+
82
+ ```text
83
+ task_contract.json
84
+ acceptance_plan.json
85
+ dev_plan.json
86
+ checkpoint_review.json
87
+ final_judgement.json
88
+ ```
89
+
90
+ This model should fit on top of the current queue runner rather than replace
91
+ it. The queue still owns leases, preflight, active/done/failed state, and run
92
+ artifacts; the task subdirectory owns multi-round collaboration evidence.
93
+
94
+ `v0.4` starts with deterministic planning artifacts. `run-queue` writes
95
+ `runtime/loops/<queue>/tasks/<task_id>/task_contract.json`,
96
+ `acceptance_plan.json`, `dev_plan.json`, `checkpoints/`, and `reviews/` before
97
+ preflight and dispatch, then writes `final_judgement.json` after acceptance
98
+ review and `revision_request.json` when the final judgement needs another
99
+ development pass. It exposes the planning directories to the dispatcher as
100
+ `LOOP_TASK_CONTRACT_FILE`, `LOOP_ACCEPTANCE_PLAN_FILE`, `LOOP_DEV_PLAN_FILE`,
101
+ `LOOP_CHECKPOINTS_DIR`, and `LOOP_REVIEWS_DIR`, then records the contract path,
102
+ inferred risk level, human-gate flag, acceptance plan path, check counts, dev
103
+ plan path, planned checkpoint count, produced checkpoint files, and acceptance
104
+ review files, final judgement outcome, and revision request summary in the run
105
+ artifact. A completed dispatch whose acceptance review still needs changes is
106
+ marked `needs_revision` instead of completed.
107
+
108
+ `queue-revision-next` turns a failed `needs_revision` task into a fresh queued
109
+ revision task using `revision_request.json`. It preserves the failed source
110
+ task and run artifacts, then embeds the revision goals and next checkpoint id
111
+ in the new task body.
112
+
113
+ `revisionPolicy` is checked at this handoff point so persistence does not become
114
+ mechanical repetition. The default policy allows up to 3 revision rounds and
115
+ blocks another next-round enqueue when two consecutive attempts have the same
116
+ revision-goal signature. Revision task bodies include anti-loop instructions
117
+ requiring the next agent to change diagnosis, tactic, evidence, or verification;
118
+ a human can still override the guard with `queue-revision-next --force`.
119
+
120
+ `queue-lineage` is the read-only attempt graph view. It can start from any task
121
+ in the chain and returns the root task id, current path, revision edges, known
122
+ attempts, checkpoint/review summaries, final judgement outcomes, and revision
123
+ request status. Every queue run artifact also embeds the same lineage summary
124
+ after the task is moved to its final state.
125
+
126
+ `queue-lineage-bundle` renders that attempt graph into a Markdown human review
127
+ bundle and JSON sidecar under `runtime/loops/<queue>/lineage-bundles/`. The
128
+ bundle is intended for handoff: it summarizes what changed in each round, why
129
+ acceptance failed, how the next round was requested, and whether the latest
130
+ round is ready for human review.
131
+
132
+ `queue-human-decision` is the explicit human gate. It records `approve`,
133
+ `request_changes`, or `reject` in
134
+ `runtime/loops/<queue>/tasks/<task_id>/human_review_decision.json`. When the
135
+ decision is `request_changes`, it also writes `human_revision_request.json`
136
+ with the human feedback converted into revision goals. `queue-revision-next`
137
+ can use that human request to create the next round, so mid-project feedback is
138
+ tracked as first-class lineage rather than lost in chat. The dispatcher also
139
+ receives `LOOP_HUMAN_REVIEW_DECISION_FILE` and
140
+ `LOOP_HUMAN_REVISION_REQUEST_FILE`, so long-running development agents can
141
+ poll for human feedback while the task is still active.
142
+
143
+ ## Project Intake Layer
144
+
145
+ `project-intake` sits above the queue runner. Queue task intake turns one
146
+ already-scoped task into a task contract, acceptance plan, and development plan.
147
+ Project intake turns an unscoped project brief into the first queue-ready shape:
148
+
149
+ ```text
150
+ human brief
151
+ -> project spec
152
+ -> conservative action policy
153
+ -> queue config
154
+ -> initial backlog
155
+ -> existing queue runner / scheduler
156
+ ```
157
+
158
+ Project specs live under:
159
+
160
+ ```text
161
+ configs/loops/projects/<project>.json
162
+ ```
163
+
164
+ Project artifacts live under:
165
+
166
+ ```text
167
+ runtime/loops/projects/<project>/intake/
168
+ runtime/loops/projects/<project>/plans/
169
+ runtime/loops/projects/<project>/backlog/
170
+ runtime/loops/projects/<project>/status/
171
+ runtime/loops/projects/<project>/reports/
172
+ ```
173
+
174
+ Conversation-facing integrations use a deterministic provenance layer:
175
+
176
+ ```text
177
+ source message
178
+ -> route-message (status | execute | direct)
179
+ -> status: summarize only
180
+ -> execute: enqueue with source metadata and model_assessed risk
181
+ -> queue terminal state
182
+ -> queue-terminal-notify
183
+ -> source conversation
184
+
185
+ checkpoint marked blocked / needs_human_input
186
+ -> queue-human-input-notify
187
+
188
+ The OpenClaw installer generates a channel-neutral notifier. It uses the
189
+ recorded task source with `openclaw message send` after each wrapper tick, so a
190
+ later terminal state or human gate can return to the originating conversation.
191
+ Notification ledgers keep retries idempotent, and missing channel/target data
192
+ fails closed rather than guessing a recipient.
193
+ -> waiting_for_human gate + source-bound prompt
194
+ -> correlated `LOOP <gate-id> <input>` reply
195
+ -> queue-human-input-resolve
196
+ -> response ledger + blocked task requeue
197
+ ```
198
+
199
+ The router owns intent and provenance, not topic-level safety classification.
200
+ Concrete action assessment belongs to the planner/executor and their applicable
201
+ authorization policy. Terminal delivery is idempotent per task/status and can
202
+ be recovered by rescanning the queue.
203
+
204
+ ## Goal-directed execution
205
+
206
+ A queue dispatcher should treat an attempt failure as evidence, not as proof
207
+ that the task goal failed. Goal-oriented controllers use this state machine:
208
+
209
+ ```text
210
+ goal -> plan -> attempt -> verify/diagnose
211
+ ^ |
212
+ |-- replan <---|
213
+ ```
214
+
215
+ The diagnoser emits one of `goal_achieved`, `retry_same_strategy`,
216
+ `change_strategy`, `investigate`, `waiting_for_human`, or `goal_unreachable`.
217
+ Only achieved, proven unreachable, or a concrete human-input gate closes the
218
+ online exploration loop. Budget exhaustion becomes `exploration_exhausted`,
219
+ which remains actionable rather than being collapsed into a generic failure.
220
+ Every changed strategy carries a normalized fingerprint so repeated plans can
221
+ trip a bounded breaker.
222
+
223
+ The intake layer is deterministic and conservative. It classifies the brief
224
+ into a project type, chooses a template, writes deliverables, acceptance
225
+ criteria, risk gates, checks, assumptions, and a first backlog. It only stops
226
+ for blocking questions; non-blocking uncertainty becomes explicit assumptions
227
+ so the project can start with safe defaults. It does not enqueue or execute
228
+ work by itself.
229
+
230
+ `project-plan` is the solidification step. It writes the project config, creates
231
+ or updates the queue config, writes the initial backlog artifact, and refreshes
232
+ the human-readable project plan. Code-oriented projects use code worktree
233
+ queues. Research, content, operations, QA, knowledge-base, infra-audit, and
234
+ assistant workflows use standard artifact queues.
235
+
236
+ `project-status` gives a read-only project-level view across queues. It
237
+ aggregates queue counts, the initial backlog artifact, the latest intake
238
+ artifact, and simple attention reasons. It intentionally delegates detailed
239
+ execution state to existing queue commands such as `queue-status`,
240
+ `code-task-status`, `code-task-dashboard`, and `summarize`.
241
+
242
+ ## Queue Runner
243
+
244
+ `v0.2.0` added a durable queue for explicit loop-managed task handoffs:
245
+
246
+ ```bash
247
+ loop-engineering enqueue \
248
+ --queue agent-tasks \
249
+ --title "Check target app logs" \
250
+ --task "Inspect the latest logs and summarize blockers."
251
+ ```
252
+
253
+ ```bash
254
+ loop-engineering run-queue \
255
+ --queue agent-tasks \
256
+ --preflight-config configs/loops/workspace-health.json \
257
+ --dispatcher "node scripts/dispatch-task.mjs" \
258
+ --timeout-ms 1800000
259
+ ```
260
+
261
+ `run-queue-drain` is available for explicit batch and daemon workflows. It
262
+ repeatedly invokes the single-task runner until the inbox is empty or the
263
+ bounded `--max-tasks` limit is reached. Conversation-facing integrations use a
264
+ different rule: a new explicit loop request supersedes the active task. The
265
+ router writes `supersede_request.json`, links the replacement with
266
+ `supersedesTaskId`, and the runner stops the old dispatcher process group or
267
+ stops at the next planning/preflight checkpoint. The old task reaches the
268
+ auditable `superseded` state before the replacement acquires the queue lock.
269
+ An explicit continuation such as `继续当前 loop,补充要求:…` follows a separate
270
+ amendment path. It does not enqueue or cancel anything. The router appends a
271
+ versioned amendment artifact, updates all three planning artifacts, and exposes
272
+ the live amendment file to the existing dispatcher session. Checkpoints record
273
+ the applied amendment version so acceptance can prove the supplement was used.
274
+
275
+ The conversation adapter also supplies a live progress notifier. Queue progress
276
+ events are filtered into ordered milestones and returned to the task's recorded
277
+ source. A five-minute dispatch heartbeat prevents silent long runs, while a
278
+ checkpoint watcher immediately surfaces new worker checkpoints. Per-task
279
+ notification ledgers make milestone delivery idempotent and auditable.
280
+
281
+ The dispatcher is deliberately external to the package. It receives task data
282
+ through environment variables such as `LOOP_TASK_BODY`, `LOOP_TASK_FILE`, and
283
+ `LOOP_RUN_ID`, so each workspace can decide how to hand off work without baking
284
+ private machine paths or credentials into public templates.
285
+
286
+ Queue command execution uses an isolated process group. When a dispatcher,
287
+ preflight, or verification command times out, the runner sends SIGTERM and then
288
+ SIGKILL to the whole process group so child processes do not survive the failed
289
+ run. This matters for device and instrumentation work where a shell wrapper may
290
+ spawn long-lived `adb`, `frida`, `tcpdump`, or proxy processes.
291
+
292
+ Dispatcher retry is also failure-aware. The queue `retry` config can list
293
+ `requiresHumanActionPatterns`; matching output marks the run
294
+ `needs_human_input` and stops retry. Defaults cover common device authorization,
295
+ permission, and explicit human-approval blockers, including
296
+ `INSTALL_FAILED_USER_RESTRICTED`. These states are treated as blocked human
297
+ gates rather than development failures, so `queue-revision-next` does not turn a
298
+ phone permission prompt into repeated automated attempts.
299
+
300
+ Recoverable model-runtime failures use a separate path. Transcript-compaction
301
+ timeouts, command timeouts, selected transport failures, and rate limits are
302
+ classified as `runtime_interrupted`; they do not create a development revision
303
+ request or invalidate accepted checkpoints. The same task returns to `inbox/`
304
+ with an incremented session generation, so the workspace dispatcher creates a
305
+ fresh worker session and resumes from the durable contract, amendments,
306
+ checkpoints, and reviews. `retry.runtimeRecoveryMaxAttempts` bounds automatic
307
+ recovery before the task becomes `runtime_blocked`. Long project sessions also
308
+ rotate proactively after `retry.sessionMaxTicks` successful continuation ticks
309
+ (default 10), preventing transcript growth from becoming project state.
310
+
311
+ ## Code Worktree Queue
312
+
313
+ `v0.3.0` adds assisted code queues:
314
+
315
+ ```bash
316
+ loop-engineering code-queue-init --queue code-tasks
317
+ loop-engineering enqueue --queue code-tasks --title "Fix parser" --task "Patch the parser and run tests."
318
+ loop-engineering run-queue --config configs/loops/queues/code-tasks.json
319
+ ```
320
+
321
+ When `worktree.enabled` is true, the runner:
322
+
323
+ 1. Runs the optional preflight loop in the main workspace.
324
+ 2. Creates `git worktree add -b <branch> <path> HEAD`.
325
+ 3. Runs the dispatcher with cwd set to the worktree.
326
+ 4. Runs configured `verifyCommands`.
327
+ 5. Records branch, worktree path, verification results, git status, diff
328
+ summaries, and untracked files in the run artifact.
329
+
330
+ This keeps code-changing work reviewable without giving the loop authority to
331
+ ship changes.
332
+
333
+ `v0.3.1` adds read-only worktree artifact inspection:
334
+
335
+ ```bash
336
+ loop-engineering code-worktree-list --queue code-tasks
337
+ loop-engineering code-worktree-inspect --queue code-tasks --task-id <id>
338
+ ```
339
+
340
+ These commands summarize the recorded branch, path, dirty state, verification
341
+ status, diff summaries, and untracked files. They do not remove worktrees or
342
+ change git state.
343
+
344
+ `v0.3.2` adds read-only patch review:
345
+
346
+ ```bash
347
+ loop-engineering code-worktree-diff --queue code-tasks --task-id <id>
348
+ loop-engineering code-worktree-diff --queue code-tasks --run-id <id> --json
349
+ ```
350
+
351
+ The command resolves the recorded worktree path from the run artifact, keeps it
352
+ inside the workspace root, and prints `git diff --stat HEAD`, `git diff
353
+ --name-status HEAD`, `git diff --binary HEAD`, and untracked file names. It
354
+ does not checkout, stage, commit, push, merge, delete, or modify queue state.
355
+
356
+ `v0.3.3` adds durable patch export artifacts:
357
+
358
+ ```bash
359
+ loop-engineering code-worktree-export --queue code-tasks --task-id <id>
360
+ loop-engineering code-worktree-export --queue code-tasks --run-id <id> --output review.patch --json
361
+ ```
362
+
363
+ The command writes a patch file plus JSON manifest for the recorded worktree.
364
+ By default the files go under `runtime/loops/<queue>/patches/`, and existing
365
+ exports are not overwritten unless `--force` is set. This gives humans and
366
+ follow-up tools a stable review artifact while still avoiding checkout, stage,
367
+ commit, push, merge, deletion, or queue-state changes.
368
+
369
+ ## Artifacts
370
+
371
+ Loop specs store state and runs under the target workspace:
372
+
373
+ ```text
374
+ runtime/loops/<loop_id>/state.json
375
+ runtime/loops/<loop_id>/runs/*.json
376
+ ```
377
+
378
+ Queue runs use:
379
+
380
+ ```text
381
+ runtime/loops/<queue>/inbox/
382
+ runtime/loops/<queue>/active/
383
+ runtime/loops/<queue>/done/
384
+ runtime/loops/<queue>/failed/
385
+ runtime/loops/<queue>/canceled/
386
+ runtime/loops/<queue>/runs/
387
+ runtime/loops/<queue>/worktrees/
388
+ ```
389
+
390
+ Run artifacts are meant to be compact evidence, not raw logs. Long-term memory
391
+ or external summaries should keep only distilled facts, such as recurring
392
+ failure signatures, accepted human gates, or a loop's current health status.
393
+
394
+ ## Cron Pattern
395
+
396
+ Install the package globally, then run one tick from cron or a scheduler:
397
+
398
+ ```bash
399
+ LOOP_WORKDIR=/path/to/workspace \
400
+ run-loop-cron.sh configs/loops/workspace-health.json
401
+ ```
402
+
403
+ Set `LOOP_ALERT_COMMAND` to a command that accepts one message argument if your
404
+ environment should send an alert when the runner exits non-zero.
405
+
406
+ ## Adaptive Queue Scheduler
407
+
408
+ `queue-scheduler-tick` adds a durable cadence layer for queue runners without
409
+ turning the package into a resident daemon:
410
+
411
+ ```bash
412
+ loop-engineering queue-scheduler-tick --config configs/loops/queues/agent-tasks.json
413
+ ```
414
+
415
+ The command treats 10 minutes as the bootstrap interval, then records
416
+ `runtime/loops/<queue>/scheduler/state.json` with the latest queue status,
417
+ outcome group, current interval, reasons, and `nextRunAt`. External schedulers
418
+ can wake it frequently; the tick itself decides whether the queue is due.
419
+
420
+ Cadence changes are outcome-driven:
421
+
422
+ - successful work with more queued tasks speeds up toward `minInterval`
423
+ - empty queues back off toward `maxInterval`
424
+ - failures back off
425
+ - human gates back off harder than ordinary failures
426
+ - long runs force the next interval above the observed duration
427
+
428
+ Queue config can set strategy bounds such as `initialInterval`, `minInterval`,
429
+ `maxInterval`, factors, and jitter. These are guardrails, not a fixed interval;
430
+ the persisted scheduler state owns the live cadence.
431
+ # Action Reservation Contract
432
+
433
+ Side-effect adapters use a shared durable state machine:
434
+
435
+ `reserved -> claimed -> settled` or `reserved/claimed -> released`.
436
+
437
+ A claim whose lease expires transitions to `unknown`; it cannot be claimed
438
+ again until authoritative reconciliation reports `accepted` or `not_accepted`.
439
+ Atomic per-key mutation, monotonic fencing tokens, immutable request and
440
+ authorization fingerprints, and terminal evidence make replay across restart,
441
+ revision, resume, and concurrent workers logically exactly once. Physical
442
+ exactly-once behavior still requires the upstream provider to honor the same
443
+ idempotency key or expose a read-only outcome lookup; absent that, the action
444
+ stays unknown rather than risking a duplicate.
@@ -0,0 +1,31 @@
1
+ # Multi-Agent Control Plane (P2)
2
+
3
+ P2 stores typed todos, registered agents, leases, handoffs, and ownership history in `runtime/loops/control-plane/state.json`. Every mutation is serialized by an atomic filesystem mutex and committed with rename. `audit.jsonl` records each ownership transition.
4
+
5
+ ## Todo contract
6
+
7
+ Every todo has a stable id, dependencies, deterministic priority, risk and authority class, required capabilities, an acceptance contract, evidence requirements, a quota/cost envelope, lineage/context, authorization, idempotency keys, and an explicit state. See `templates/todo.schema.json`.
8
+
9
+ Eligibility is deterministic: descending priority, then creation time, then id. A todo is claimable only when dependencies are complete, the agent has every capability and the authority grant, quota is sufficient, the P0 human gate is runnable, and every P1 action outcome is safe. An unknown or stale in-flight action requires reconciliation before reassignment.
10
+
11
+ Claims carry a monotonically increasing fencing token. Renew/release require the active owner, current token, and live lease. Expired claims are recovered as runnable only when no parked gate or unresolved action can cause duplicate effects.
12
+
13
+ Handoff packets durably preserve lineage, context, evidence, authorization, idempotency keys, and the source fencing token. The target rechecks eligibility on acceptance and receives a new fencing token. Rejection restores the source claim while its lease is live.
14
+
15
+ ## CLI
16
+
17
+ ```text
18
+ agent-register --agent-json agent.json
19
+ todo-create --todo-json todo.json
20
+ todo-list [--state runnable]
21
+ todo-inspect --todo-id ID
22
+ todo-claim --agent-id AGENT [--todo-id ID] [--lease-ms N]
23
+ todo-renew --todo-id ID --agent-id AGENT --fencing-token N [--lease-ms N]
24
+ todo-release --todo-id ID --agent-id AGENT --fencing-token N [--completed] [--evidence TEXT]
25
+ todo-handoff --todo-id ID --agent-id AGENT --target-agent-id AGENT --fencing-token N [--handoff-id ID]
26
+ todo-accept|todo-reject --handoff-id ID --agent-id AGENT
27
+ todo-recover [--now EPOCH_MS]
28
+ todo-import-legacy
29
+ ```
30
+
31
+ `--todo-json` and `--agent-json` accept either an inline JSON object or a file path. All commands accept `--root` and emit JSON.
@@ -0,0 +1,27 @@
1
+ # Operator Dashboard and projection API
2
+
3
+ P3 provides a local-first, read-only view over durable Loop Engineering artifacts. It does not maintain a database, lock queue state, or write beneath `runtime/loops`. Every live request rebuilds a normalized projection; static export writes only to the explicitly selected output directory.
4
+
5
+ ## Commands
6
+
7
+ ```sh
8
+ loop-engineering dashboard-inspect --root /path/to/workspace --json
9
+ loop-engineering dashboard-inspect --state waiting_for_human --query approval --root /path/to/workspace --json
10
+ loop-engineering dashboard-health --max-age-seconds 3600 --root /path/to/workspace --json
11
+ loop-engineering dashboard-export --output-dir /tmp/loop-dashboard --root /path/to/workspace --json
12
+ loop-engineering dashboard-serve --root /path/to/workspace
13
+ ```
14
+
15
+ `dashboard-serve` binds to `127.0.0.1` and an ephemeral port by default. A wider bind is rejected unless `--allow-non-loopback` is explicit. The server has no authentication and is intended for trusted local use. The CLI never starts it during checks or installation.
16
+
17
+ Endpoints are `GET /api/v1/overview`, `/api/v1/health`, `/api/v1/todos`, `/api/v1/todos/:id`, and `/api/v1/actions`. Overview and todo lists support `q` and `state` filters. Private raw files are not served.
18
+
19
+ ## Projection and security rules
20
+
21
+ The schema is versioned as `1.0.0` in `templates/operator-projection.schema.json`. P0 parked human/external gates, reminders/escalations and next wake metadata are normalized alongside P1 reservations/reconciliation and P2 typed todos, owners, fencing leases and handoffs. Existing queue/project artifacts are projected as version 1 inputs when no source version exists.
22
+
23
+ Operator states remain distinct: `runnable`, `active`, `parked`, `waiting_for_human`, `waiting_for_external_condition`, `timed_out_or_escalated`, `reconciliation_required`, `blocked`, `completed`, and `failed`. Unknown action outcomes and expired active leases become `reconciliation_required`; the dashboard never repairs them.
24
+
25
+ Malformed artifacts produce degraded health instead of crashing the overview. `freshness_seconds` derives from the newest projected timestamp. Reads retry once to tolerate atomic replacement and warn when the runtime directory changes during a projection.
26
+
27
+ Secret/token/password/credential/API/private-key/provider fields are recursively replaced with `[REDACTED]`. Evidence links are safe workspace-relative paths; no arbitrary file reader exists. HTML uses DOM `textContent`, API responses are JSON, path traversal is rejected, and restrictive response headers are enabled.
@@ -0,0 +1,35 @@
1
+ # Taskforce Loop Engineering 0.12 release acceptance
2
+
3
+ Status: local release candidate accepted on 2026-08-13. Publication and deployment are explicitly out of scope for this acceptance.
4
+
5
+ ## Terminal outcome
6
+
7
+ Version 0.12 provides one coherent local package containing:
8
+
9
+ - P0 Human-Gate Lifecycle v2 with parked waits, throttled reminders and escalations, verified recovery, and restart-safe authorization preservation.
10
+ - P1 Action Idempotency and Reservation Contract with immutable request fingerprints, authorization settlement, fenced claims, and unknown-outcome reconciliation.
11
+ - P2 Multi-Agent Control Plane with typed todos, capability and authority matching, dependency/quota scheduling, fenced leases, handoff, and orphan recovery.
12
+ - P3 read-only Operator Dashboard with normalized P0/P1/P2 projections, loopback serving, static export, redaction, and traversal/XSS protections.
13
+
14
+ ## Acceptance ledger
15
+
16
+ | Item | Status | Evidence |
17
+ | --- | --- | --- |
18
+ | P0 implementation and crash/recovery behavior | accepted | `scripts/human-gate-lifecycle-v2-self-test.mjs` |
19
+ | P1 reservation, concurrency, fencing, crash recovery, and reconciliation | accepted | `scripts/action-reservation-self-test.mjs` |
20
+ | P2 ownership, scheduling, lease, handoff, and P0/P1 safety | accepted | `scripts/todo-control-plane-self-test.mjs` |
21
+ | P3 projection, security, restart, and large-queue behavior | accepted | `scripts/operator-dashboard-self-test.mjs` |
22
+ | OpenClaw and Hermes installer compatibility | accepted | `scripts/openclaw-install-self-test.mjs`, `scripts/hermes-install-self-test.mjs` |
23
+ | Full package regression suite | accepted | `npm run check` on 2026-08-13 |
24
+ | Package contents and clean registry-style installation | accepted | `npm pack --dry-run` plus installation from the generated 0.12.0 tarball |
25
+ | Documentation and migration boundary | accepted | `README.md`, `CHANGELOG.md`, `MIGRATING.md`, and `docs/` |
26
+
27
+ ## Completion boundary
28
+
29
+ The local release candidate is complete when every ledger item above is accepted and there are no code or documentation failures. A milestone alone cannot satisfy this contract.
30
+
31
+ Git commit, tag, GitHub release, npm/ClawHub publication, and installation into a production agent are separate externally visible release actions. They require an explicit release decision and are not implied by local acceptance.
32
+
33
+ Unmet local items: none.
34
+
35
+ External release gates: publish/tag/push/deploy decision.