feat(conductor): auto-apply policy gate for worker patches (#34)
- conductor-policy.json (tracked, strictly validated): enabled switch, path allowlist globs, gating suites - the autonomy decision lives in a declarative file the owner controls - scripts/conductor-apply.sh <runId> [--dry-run]: succeeded-run check -> clean target tree -> diff from worker workspace -> allowlist -> syntax gates (node/bash/json) -> apply -> policy suites -> attribution commit; ANY failure reverts the tree; push is never automatic - scripts/test-conductor.sh: 17 sandbox cases covering every gate incl. suite-failure auto-revert and disabled policy - policy defaults: scripts/docs/tasks/missions/adapters + README; all three suites gate Closes #34
This commit is contained in:
@@ -303,4 +303,38 @@ M5 tagged `workspace-capabilities-v1`, M6 tagged `sessions-v1`, M7 tagged `opera
|
||||
|
||||
Conductor loop proven end-to-end on the stack itself. `main` merged with M8; release 0.0.6 remains active (retry is host-side only, no image change).
|
||||
|
||||
---
|
||||
|
||||
## Phase 13: Mission-level capability policy (M9)
|
||||
|
||||
### Entry 13.1 — before
|
||||
|
||||
- Timestamp: 2026-09-03
|
||||
- Intended action: Missions may declare capabilities.tools as governing constraints (Gitea #30); merge semantics = least-privilege intersection (task narrows, never widens; empty intersection = tool-free run). Host-side only.
|
||||
- Reason: First mechanical restriction layer — the trust model becomes enforced, not instructed.
|
||||
- Expected result: all four merge cases asserted from run evidence; suites green.
|
||||
|
||||
### Entry 13.2 — after
|
||||
|
||||
- Observed: four merge cases verified deterministically via run-record stderr (mission-only, task-only, narrowed, emptied); invalid mission capabilities exit 2; task suite 41/41.
|
||||
- Failure or correction: selftest harness could not express ABSENT vs EMPTY fields via its printf helper — fixed with an ABSENT marker; two suite config-leak defects fixed (per-command env scoping). Product unaffected.
|
||||
|
||||
## Phase 14: Session forking (M11)
|
||||
|
||||
### Entry 14.1 — before
|
||||
|
||||
- Timestamp: 2026-09-03
|
||||
- Intended action: sessionForkFrom task field branches the source session's newest file (pi --fork) into the target session dir; ancestor untouched; RELEASE -> 0.0.7 with health-gated activation (Gitea #33).
|
||||
- Reason: Owner flagged conversation forking from a common ancestor as a desired property; pi JSONL trees make it native.
|
||||
- Expected result: forked child recalls ancestor context; ancestor file untouched; suites green; 0.0.7 active.
|
||||
|
||||
### Entry 14.2 — after
|
||||
|
||||
- Observed: mock plumbing asserts fork source + target delivery; validation rejects fork-without-target and self-fork (exit 2); ghost source exits 4; live fork: child recalled 'mosaico' from ancestor context while the ancestor session file remained untouched (file-level assertion); suites 58/24/14 + verify green; 0.0.7 packaged and activated via health gate.
|
||||
- Failure or correction: retryRun-style self-assignment bug in validation (compared null to target) — caught by negative test, fixed.
|
||||
|
||||
## Result (M11)
|
||||
|
||||
Session forking verified. `main` merged with M11, tagged `session-fork-v1`; release 0.0.7 active.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user