taskforce-loop-engineering 0.13.0 → 0.15.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/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.15.0 - 2026-08-20
6
+
7
+ - Reconcile project-scoped human gates against the authoritative project contract and acceptance ledger, superseding stale or optional deferred gates without replay.
8
+ - Strengthen doctor and project status checks for structured gate context, acceptance-ledger drift, execution-ledger reconciliation, and project completion.
9
+ - Make active-task supersession project-aware across active and waiting tasks, and add end-to-end regression coverage for durable gate materialization.
10
+
11
+ ## 0.14.0 - 2026-08-14
12
+
13
+ - Add the platform-neutral runtime adapter SDK v1 with OpenClaw, Hermes, Codex CLI, and Claude Code factories, shared conformance tests, fail-closed effects, redacted telemetry, migration guidance, and a credential-free demo.
14
+
5
15
  ## 0.13.0 - 2026-08-14
6
16
 
7
17
  - Add versioned OpenClaw, Hermes, and custom runtime adapter contracts with a shared conformance suite.
package/README.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Taskforce Loop Engineering
2
2
 
3
+ [![production trust](https://github.com/ambitioncn/taskforce-loop-engineering/actions/workflows/production-trust.yml/badge.svg)](https://github.com/ambitioncn/taskforce-loop-engineering/actions/workflows/production-trust.yml)
4
+
5
+ ## Platform-neutral adapter SDK
6
+
7
+ OpenClaw, Hermes, Codex CLI, and Claude Code share the versioned runtime
8
+ contract in `lib/runtime-adapter-sdk.mjs`. Start without credentials or network
9
+ access with `npm run demo:adapter`, then verify every runtime using
10
+ `npm run check:adapters`. See [docs/runtime-adapter-sdk.md](docs/runtime-adapter-sdk.md)
11
+ for the contract, compatibility matrix, migration, and extension guide.
12
+
3
13
  ## 0.13 production trust
4
14
 
5
15
  The local production-trust contract, runtime adapter v1, durable journal,
@@ -7,7 +17,11 @@ multi-worker canary, non-destructive Ironman upgrade planner, safe demo and
7
17
  unified acceptance are documented in
8
18
  [docs/production-trust-contract.md](docs/production-trust-contract.md). Run
9
19
  `npm run check:production-trust`; external publishing and deployment remain
10
- separately authorized actions.
20
+ separately authorized actions. The command writes integrity-sealed evidence and
21
+ a redacted public summary to `.production-evidence/`. The default canary is
22
+ offline and fixture-only: it performs no model call or external side effect.
23
+ Copy `templates/github-production-trust.yml` into `.github/workflows/` only
24
+ when publication is separately approved.
11
25
 
12
26
  ## Read-only operator dashboard (P3)
13
27
 
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 1,
3
+ "project": "P2 platform-neutral runtime adapter SDK",
4
+ "terminal_acceptance": [
5
+ "versioned platform-neutral contract",
6
+ "OpenClaw Hermes Codex CLI and Claude Code reproducible paths",
7
+ "unified capability session run step effect gate continuation telemetry and errors",
8
+ "compatibility matrix conformance migration and extension docs",
9
+ "credential-free demo and read-only dashboard path",
10
+ "redaction fail-closed 0.13 P0 P1 regression package and clean-install evidence"
11
+ ],
12
+ "backlog": [
13
+ {"id":"P2-1","status":"done","evidence":"lib/runtime-adapter-sdk.mjs"},
14
+ {"id":"P2-2","status":"done","evidence":"scripts/runtime-adapter-conformance.mjs"},
15
+ {"id":"P2-3","status":"done","evidence":"docs/runtime-adapter-sdk.md"},
16
+ {"id":"P2-4","status":"done","evidence":"examples/adapter-sdk-demo.mjs"},
17
+ {"id":"P2-5","status":"done","evidence":"npm run check; npm pack --pack-destination; clean npm install and packaged conformance"}
18
+ ]
19
+ }
@@ -1,13 +1,18 @@
1
1
  {
2
- "version": 1,
3
- "project": "0.13-production-trust",
2
+ "version": 3,
3
+ "project": "p1-production-trust-evidence",
4
4
  "terminal_contract": "production-trust-contract.md",
5
+ "milestone_completion_is_project_completion": false,
5
6
  "items": [
6
- {"id":"PT-1","outcome":"versioned runtime adapter contract","evidence":["lib/runtime-adapter-v1.mjs","scripts/runtime-adapter-contract-self-test.mjs"],"required":true},
7
- {"id":"PT-2","outcome":"durable journal, replay, migration, backup/restore","evidence":["lib/durable-journal.mjs","scripts/durable-journal-self-test.mjs"],"required":true},
8
- {"id":"PT-3","outcome":"multi-agent soak/canary report","evidence":["scripts/production-soak.mjs"],"required":true},
9
- {"id":"PT-4","outcome":"non-destructive customized-layout upgrade plan","evidence":["lib/upgrade-planner.mjs","scripts/upgrade-planner-self-test.mjs"],"required":true},
10
- {"id":"PT-5","outcome":"safe public demo and operations guide","evidence":["examples/safe-canary.mjs","docs/production-operations.md"],"required":true},
11
- {"id":"PT-6","outcome":"unified local release acceptance","evidence":["scripts/production-acceptance.mjs"],"required":true}
7
+ {"id":"P1-1","outcome":"schema-versioned evidence, public summary, integrity and redaction","evidence":["lib/production-evidence.mjs","templates/production-evidence.schema.json","scripts/production-evidence-self-test.mjs"],"required":true},
8
+ {"id":"P1-2","outcome":"ledger-backed multi-agent soak and kill/restart chaos","evidence":["scripts/production-soak.mjs","lib/execution-ledger.mjs"],"required":true},
9
+ {"id":"P1-3","outcome":"claim lease handoff parked gate and stale-fence rejection","evidence":["scripts/production-soak.mjs",".production-evidence/evidence.json"],"required":true},
10
+ {"id":"P1-4","outcome":"unknown outcome crash boundaries and accepted-before-settle reconciliation","evidence":["scripts/production-soak.mjs","lib/execution-ledger.mjs"],"required":true},
11
+ {"id":"P1-5","outcome":"step replay resume divergence and zero duplicate effects","evidence":["scripts/production-soak.mjs","scripts/execution-ledger-self-test.mjs"],"required":true},
12
+ {"id":"P1-6","outcome":"baseline trend threshold attribution recovery cost and error metrics","evidence":["lib/production-evidence.mjs","scripts/production-evidence-self-test.mjs"],"required":true},
13
+ {"id":"P1-7","outcome":"OpenClaw Hermes and custom adapter compatibility matrix","evidence":["lib/runtime-adapter-v1.mjs","scripts/production-soak.mjs"],"required":true},
14
+ {"id":"P1-8","outcome":"GitHub CI candidate badge doctor and dashboard projection","evidence":["templates/github-production-trust.yml","README.md","lib/core.mjs","lib/operator-dashboard.mjs"],"required":true},
15
+ {"id":"P1-9","outcome":"offline determinism privacy and tamper negative tests","evidence":["scripts/production-evidence-self-test.mjs","scripts/production-soak.mjs"],"required":true},
16
+ {"id":"P1-10","outcome":"full regression package content and clean-install acceptance","evidence":["package.json","scripts/production-acceptance.mjs"],"required":true}
12
17
  ]
13
18
  }
@@ -1,54 +1,53 @@
1
- # Production Trust Contract (0.13)
2
-
3
- Status: local release candidate. This contract is terminal only when every
4
- required item in `production-trust-backlog.json` is accepted by recorded local
5
- evidence. Publishing and production deployment are deliberately outside it.
6
-
7
- ## Required outcomes
8
-
9
- 1. Runtime adapters implement contract v1 and pass the same conformance suite.
10
- OpenClaw and Hermes are supported integrations; the custom adapter is the
11
- reference extension point.
12
- 2. State mutations use a checksummed append-only journal with atomic snapshot
13
- checkpoints, replay, migration from version-1 JSON state, backup and restore.
14
- A committed external P1 side effect is never inferred from local intent:
15
- ambiguous attempts remain `unknown` until reconciled with upstream evidence.
16
- 3. The deterministic multi-worker canary covers heartbeat, claim, lease expiry,
17
- fenced handoff, crash/restart replay, concurrent claims, quota, parked gates,
18
- and unknown-outcome reconciliation and emits an auditable JSON report.
19
- 4. Upgrade planning detects unmanaged or locally modified Ironman layouts and
20
- produces a non-destructive plan. Customized dispatcher/config files are
21
- preserved; application requires a separate explicit confirmation and has a
22
- backup-based rollback plan.
23
- 5. The public demo is credential-free, loopback/local-only, makes no paid call
24
- or external write, and labels support boundaries.
25
- 6. Release acceptance includes threat model, reliability/performance thresholds,
26
- full regression, package dry-run, and clean-install verification.
27
-
28
- ## Release thresholds
29
-
30
- - Adapter conformance: all three fixtures pass; incompatible major versions fail.
31
- - Journal: torn tail is ignored, checksum corruption fails closed, snapshot and
32
- replay agree, backup restore agrees, migration is idempotent.
33
- - Canary: all scenarios pass, duplicate settled side effects = 0, stale fencing
34
- tokens accepted = 0, unreconciled unknown outcomes = 0.
35
- - Regression: `npm run check` and `npm run check:production-trust` pass.
36
- - Packaging: `npm pack --dry-run` contains all contract, runtime and demo assets.
37
-
38
- ## Threat model and trust boundaries
39
-
40
- Untrusted inputs include adapter responses, task JSON, journal tails, installer
41
- layouts, and human-gate text. Controls are schema validation, bounded strings,
42
- checksums, atomic rename, fencing tokens, canonical idempotency keys, path
43
- containment, fail-closed version negotiation, and explicit confirmation gates.
44
- The package does not claim Byzantine-worker protection, distributed consensus,
45
- or exactly-once behavior from an upstream service lacking idempotency/reconcile
46
- APIs. Host compromise, stolen credentials, and malicious runtime binaries remain
47
- operator responsibilities.
48
-
49
- ## Support levels
50
-
51
- - OpenClaw: supported, contract-tested adapter and managed installer.
52
- - Hermes: supported, contract-tested adapter and managed installer.
53
- - Custom runtime: contract/example support; lifecycle is operator-owned.
54
- - Distributed database/HA: not provided by the local journal backend.
1
+ # P1 Production-Trust Evidence Terminal Contract
2
+
3
+ Status: local release candidate. Project completion requires every required P1
4
+ backlog item to have repeatable evidence; a scenario or milestone alone is not
5
+ project completion. Push, publication, deployment, production credentials,
6
+ real paid calls, production process control, and external effects are excluded.
7
+
8
+ ## Terminal outcome
9
+
10
+ P1 turns the P0 schema-v2 execution ledger and effect protocol into a sustainable
11
+ production-trust evidence system. CI/canary runs emit schema-versioned,
12
+ integrity-sealed evidence plus a secret-redacted public summary. Baselines,
13
+ trends, explicit thresholds, failure attribution, runtime compatibility, cost,
14
+ error rate, and recovery time remain independently reviewable.
15
+
16
+ ## Required acceptance
17
+
18
+ 1. The deterministic multi-agent canary exercises long soak, exclusive claim,
19
+ lease expiry, kill/restart handoff, stale fencing, parked gate, crash before
20
+ and after submit, accepted-before-local-settle, reconciliation, checkpoint
21
+ resume, reusable replay, and replay divergence through the P0 ledger/effect
22
+ protocol. It does not maintain a second execution state store.
23
+ 2. Duplicate settled effects and accepted stale fences are exactly zero;
24
+ unreconciled unknown outcomes are zero at terminal acceptance. Recovery time,
25
+ error rate, model calls, and paid-call cost meet recorded thresholds.
26
+ 3. OpenClaw, Hermes, and custom runtime-adapter fixtures pass contract v1 using
27
+ simulated I/O. The boundary is explicit: fixtures prove adapter compatibility,
28
+ not availability of a real gateway or provider.
29
+ 4. Evidence schema v1 supports baselines and metric deltas, threshold failures
30
+ with attribution, SHA-256 tamper detection, credential-shaped field redaction,
31
+ and a minimized public summary. Offline reruns require no network or secret.
32
+ 5. GitHub CI template/artifact upload and badge markup are release candidates;
33
+ no workflow is published in this local task. Doctor and dashboard project the
34
+ latest evidence state without mutating it.
35
+ 6. Full regression, package dry-run, package content inspection, and clean local
36
+ install pass. The packaged candidate includes schema, CI template, library,
37
+ canary, tests, docs, and backlog.
38
+
39
+ ## Real/simulated boundary and deferred canary
40
+
41
+ `production-soak.mjs` is the authoritative offline CI canary. The separate
42
+ `live-runtime-soak.mjs` may perform runtime probes and is not invoked by release
43
+ acceptance. A real long-duration OpenClaw/Hermes run, production credentials,
44
+ paid inference, or external side effect needs a separate human authorization and
45
+ must produce a successor evidence artifact clearly labeled `real_runtime`.
46
+
47
+ ## Trust limits
48
+
49
+ SHA-256 detects later artifact changes but is not an external timestamp or
50
+ signature. Local filesystem leases provide single-host coordination, not
51
+ distributed consensus or Byzantine-worker protection. Exactly-once effects still
52
+ depend on an upstream idempotency/reconciliation API. Unknown outcomes lacking
53
+ authoritative evidence fail closed and remain reconciliation debt.
@@ -0,0 +1,50 @@
1
+ # Runtime Adapter SDK v1
2
+
3
+ `lib/runtime-adapter-sdk.mjs` is the platform-neutral contract. Contract id is
4
+ `loop.runtime-adapter`, semantic version `1.0.0`; consumers must reject unknown
5
+ major versions. The SDK normalizes capabilities, session/run identity, step
6
+ ledger events, authorized effects, human gates, heartbeat/continuation,
7
+ redacted evidence/telemetry, and stable `AdapterError` codes.
8
+
9
+ ## Ten-minute, credential-free path
10
+
11
+ From this package, run `npm run demo:adapter`, `npm run check:adapters`, then
12
+ `npm run check`. All four paths use the same in-memory transport and make no
13
+ network calls. The existing dashboard remains a read-only projection; the demo
14
+ prints the command for opening it against a local workspace.
15
+
16
+ ## Runtime paths
17
+
18
+ | Runtime | Factory | Integration transport |
19
+ | --- | --- | --- |
20
+ | OpenClaw | `createOpenClawAdapter` | map invoke to trusted session/task tools |
21
+ | Hermes | `createHermesAdapter` | map invoke to Hermes run lifecycle |
22
+ | Codex CLI | `createCodexCliAdapter` | map invoke to local Codex exec/resume |
23
+ | Claude Code | `createClaudeCodeAdapter` | map invoke to local Claude session/resume |
24
+
25
+ Each transport implements `invoke(operation, payload)`. Operations are
26
+ `run.start`, `run.heartbeat`, and `run.continue`. Side effects never pass through
27
+ that generic transport: call `prepareEffect` first, persist its idempotency key
28
+ in the P0/P1 ledger, obtain explicit authorization, then submit through the
29
+ product-specific effect adapter. Missing authorization fails closed.
30
+
31
+ ## Compatibility and migration
32
+
33
+ | Surface | Status |
34
+ | --- | --- |
35
+ | package 0.13 / P0 / P1 ledgers | compatible; unchanged |
36
+ | `runtime-adapter-v1.mjs` OpenClaw/Hermes/custom fixtures | retained |
37
+ | SDK v1 four-runtime contract | additive and preferred |
38
+ | future SDK major | rejected until explicitly supported |
39
+
40
+ Migrate by replacing fixture imports with a `create*Adapter(transport)` factory,
41
+ creating a session then run, recording every step, and routing effects through
42
+ `prepareEffect`. Convert caught errors using `AdapterError.toJSON()`; never log
43
+ raw credentials. To extend, add a runtime to `RUNTIMES`, a thin factory, and run
44
+ the exported conformance function with an offline transport before connecting a
45
+ real runtime.
46
+
47
+ Error codes are `INVALID_INPUT`, `UNSUPPORTED_CONTRACT`,
48
+ `UNSUPPORTED_VERSION`, `UNSUPPORTED_RUNTIME`, `INVALID_ADAPTER`,
49
+ `INVALID_STEP_STATE`, `EFFECT_KEY_REQUIRED`, `EFFECT_NOT_AUTHORIZED`,
50
+ `INVALID_GATE_DECISION`, and retryable `TRANSPORT_FAILURE`.
@@ -0,0 +1,9 @@
1
+ import { createMemoryTransport, createOpenClawAdapter } from '../lib/runtime-adapter-sdk.mjs';
2
+
3
+ const adapter = createOpenClawAdapter(createMemoryTransport());
4
+ const session = await adapter.createSession({ key: 'ten-minute-demo' });
5
+ const run = await adapter.startRun({ sessionId: session.sessionId, requestId: 'demo', input: { prompt: 'credential-free' } });
6
+ await adapter.recordStep({ runId: run.runId, stepId: 'hello', evidence: [{ kind: 'local-demo' }] });
7
+ const heartbeat = await adapter.heartbeat({ runId: run.runId });
8
+ await adapter.continueRun({ runId: run.runId, continuationToken: heartbeat.continuationToken });
9
+ console.log(JSON.stringify({ session, run, heartbeat, dashboard: 'run `loop-engineering dashboard --root .` for the existing read-only projection', telemetry: adapter.telemetry }, null, 2));
@@ -0,0 +1,35 @@
1
+ {
2
+ "queue": "code-tasks",
3
+ "description": "L2 assisted code task queue. Each task runs in an isolated git worktree and records verification plus diff summaries. It never pushes, merges, or deletes worktrees.",
4
+ "dispatcher": "node scripts/dispatch-code-task.mjs",
5
+ "preflightConfig": "configs/loops/workspace-health.json",
6
+ "timeoutMs": 1800000,
7
+ "leaseMs": 1860000,
8
+ "staleActiveMs": 3600000,
9
+ "retry": {
10
+ "maxAttempts": 1,
11
+ "retryDelayMs": 0,
12
+ "retryExitCodes": [
13
+ 1
14
+ ],
15
+ "requiresHumanActionPatterns": [
16
+ "INSTALL_FAILED_USER_RESTRICTED",
17
+ "device unauthorized",
18
+ "no devices/emulators found",
19
+ "Permission denied",
20
+ "Operation not permitted",
21
+ "requires human",
22
+ "需要人工",
23
+ "权限未开"
24
+ ]
25
+ },
26
+ "worktree": {
27
+ "enabled": true,
28
+ "baseDir": "runtime/loops/code-tasks/worktrees",
29
+ "branchPrefix": "loop/code-tasks",
30
+ "verifyCommands": [
31
+ "npm test"
32
+ ],
33
+ "keepOnSuccess": true
34
+ }
35
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "queue": "agent-tasks",
3
+ "description": "Generic queue runner config. Keep dispatcher local to the target workspace.",
4
+ "dispatcher": "node scripts/dispatch-task.mjs",
5
+ "preflightConfig": "configs/loops/workspace-health.json",
6
+ "timeoutMs": 1800000,
7
+ "leaseMs": 1860000,
8
+ "staleActiveMs": 3600000,
9
+ "scheduler": {
10
+ "initialInterval": "10m",
11
+ "minInterval": "1m",
12
+ "maxInterval": "4h",
13
+ "speedupFactor": 0.5,
14
+ "backoffFactor": 2,
15
+ "idleBackoffFactor": 2,
16
+ "humanGateBackoffFactor": 3,
17
+ "longRunHeadroomFactor": 1.25,
18
+ "jitter": "30s"
19
+ },
20
+ "retry": {
21
+ "maxAttempts": 1,
22
+ "retryDelayMs": 0,
23
+ "retryExitCodes": [
24
+ 1
25
+ ],
26
+ "requiresHumanActionPatterns": [
27
+ "INSTALL_FAILED_USER_RESTRICTED",
28
+ "device unauthorized",
29
+ "no devices/emulators found",
30
+ "Permission denied",
31
+ "Operation not permitted",
32
+ "requires human",
33
+ "需要人工",
34
+ "权限未开"
35
+ ]
36
+ }
37
+ }
@@ -0,0 +1,5 @@
1
+ import { customAdapterExample } from '../lib/runtime-adapter-v1.mjs';
2
+ const audit = [];
3
+ const io = { invoke: async (binary, args) => (audit.push({ binary, args, externalWrite: false, paid: false }), { accepted: true }), now: () => new Date().toISOString(), lookup: async () => ({ status: 'not_accepted' }) };
4
+ await customAdapterExample.dispatch({ prompt: 'credential-free local canary', worker: 'demo' }, io);
5
+ console.log(JSON.stringify({ support: 'example-contract-only', credentialsUsed: false, externalWrites: false, paidCalls: false, audit }, null, 2));
@@ -0,0 +1,35 @@
1
+ {
2
+ "id": "workspace-health",
3
+ "goal": "Keep this workspace loop-ready and detect obvious drift.",
4
+ "level": "L1",
5
+ "mode": "report-only",
6
+ "maxRuntimeMs": 120000,
7
+ "description": "A safe first loop: local read-only checks plus durable run ledger.",
8
+ "humanGates": [
9
+ "source edits",
10
+ "external messages",
11
+ "destructive commands",
12
+ "production config changes"
13
+ ],
14
+ "breaker": {
15
+ "maxConsecutiveFailures": 3,
16
+ "sameFailureThreshold": 2
17
+ },
18
+ "checks": [
19
+ {
20
+ "id": "git-status",
21
+ "type": "command",
22
+ "cmd": "git status --short",
23
+ "expectExitCode": 0,
24
+ "timeoutMs": 10000,
25
+ "allowNonEmptyOutput": true
26
+ },
27
+ {
28
+ "id": "loop-config-dir",
29
+ "type": "files",
30
+ "paths": [
31
+ "configs/loops"
32
+ ]
33
+ }
34
+ ]
35
+ }
@@ -1,6 +1,7 @@
1
1
  import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { createHash, randomUUID } from 'node:crypto';
4
+ import { migrateActionReservation } from './execution-ledger.mjs';
4
5
 
5
6
  const ACTION_KINDS = new Set(['paid_api', 'notification', 'deployment', 'process_control', 'publication', 'external_message', 'gated_mutation']);
6
7
  const TERMINAL_STATES = new Set(['settled', 'released']);
@@ -194,3 +195,9 @@ export async function migrateLegacyActionArtifact(root, legacy) {
194
195
  const scope = legacy.authorization_scope ?? legacy.authorization?.scope ?? 'legacy:unscoped';
195
196
  return reserveAction(root, { idempotencyKey: key, kind: legacy.kind ?? 'gated_mutation', request, authorizationScope: scope });
196
197
  }
198
+
199
+ export async function projectActionToEffectProtocol(root, idempotencyKey) {
200
+ const reservation = await inspectAction(root, idempotencyKey);
201
+ if (!reservation) throw new Error('Action reservation not found.');
202
+ return migrateActionReservation(root, reservation);
203
+ }