isolate-worker-control-plane-filesystem

Broker worker graph access and hide raw .wg

Metadata

Statusdone
Agent identity6841f97a7a8e6cbc213051ce0ffb3c85c92c80cb61fd699428ab3fed6cb6ba94
Created2026-08-01T15:37:47.817666184+00:00
Started2026-08-02T06:27:31.495298145+00:00
Completed2026-08-03T09:42:52.235364373+00:00
Tokens38166396 in / 49717 out

Description

Workers must not require or receive raw filesystem access to the project .wg control plane. The landed fix-candidate-wg-control-plane-destruction prevents .wg from entering candidates and removes the helper symlink, but new workers still receive an absolute WG_DIR; under the same Unix uid they can inspect or mutate graph/config/chat/session files directly. Replace this with a scoped daemon capability channel.

Worker processes receive only an authenticated attempt capability plus a daemon IPC endpoint. All worker-facing WG operations (show scoped context, messages, checkpoints, wait/done/fail/finish handoff, dependency artifact reads) go through typed IPC validated against task id, generation, attempt, fence, lease, and allowed operation. In worker context, filesystem graph fallback is forbidden even if a path is guessed. The daemon remains the sole graph/control writer. Raw graph, other tasks' private sessions/messages, global config/secrets, finalization leases, and service controls are not exposed. Capability replay after owner release or generation advance is rejected.

On platforms supporting hard isolation, launch required-isolation workers in a mount namespace/container/sandbox where the canonical .wg and project .git control stores are absent/inaccessible while the source worktree and scoped IPC socket are available. Detect whether this guarantee is actually enforced; never claim filesystem isolation from environment-variable omission alone. Define an explicit degraded compatibility mode for platforms without sandboxing, with a loud status/policy decision, while candidate/tree/promotion guards remain mandatory everywhere. Do not break attended chat/operator authority.

Move durable graph storage toward an XDG/state-root keyed by canonical graph identity so source checkout paths never overlap control storage; a project-local .wg may at most be an operator-owned locator/mountpoint that Git protection treats as sacred. Provide an idempotent, backup-first migration retaining exact graph/chat/session bytes and graph identity, with rollback. Coordinate the capability/event schema with formalize-lifecycle-finish-lean4 and formalize-daemon-planner-replay.

Defense in depth remains mandatory: server/CI tree scanning, candidate tree/index/diff rejection (including force-added, nested, case/NFKC/backslash variants), exact-path projection, live identity receipts, and external snapshots. Do not rely on .gitignore, hooks, prompt instructions, or agent goodwill.

Validation

  • Candidate worker has no .wg entry, no WG_DIR filesystem path, and cannot open canonical control files or project Git control storage under enforced isolation; ordinary scoped WG commands succeed through IPC.
  • Attempt capability permits only its declared task/generation/fence operations; cross-task reads, graph enumeration, config/chat/session reads, service control, stale/replayed capabilities, and direct terminalization are refused and audited.
  • Malicious worker attempts git add -f .wg, path guessing, symlink/hardlink/bind traversal, /proc cwd/fd discovery, socket reuse, and sibling-worktree access; no control bytes are readable/mutable and candidate/promotion stays clean.
  • Kill/restart daemon and worker at request/response boundaries; idempotent request IDs reconcile without duplicate completion or lost WIP.
  • Backup-first external-state migration and rollback preserve byte digests and graph identity; source Git operations cannot address the external control root.
  • Explicit tests distinguish enforced isolation from degraded mode; status never overclaims.
  • cargo fmt --check, capability/IPC/sandbox/migration tests, candidate-binary Linux smoke, cargo check, cargo clippy.

Depends on

Required by

Log