Skip to content

Sync Boatstack from Intelligence Flow Labs @ c7d80b2f9948 - #91

Merged
operator-stack-publisher[bot] merged 1 commit into
mainfrom
sync/intelligence-flow-c7d80b2f9948
Jul 24, 2026
Merged

Sync Boatstack from Intelligence Flow Labs @ c7d80b2f9948#91
operator-stack-publisher[bot] merged 1 commit into
mainfrom
sync/intelligence-flow-c7d80b2f9948

Conversation

@operator-stack-publisher

Copy link
Copy Markdown
Contributor

What this sync releases

Plan activation promotes its managed artifacts through a transactional mutation boundary, with a proper undo

Activating a plan produces four managed artifacts that must be consistent with one another — the compiled tasks.json, test-matrix.json, and evidence.md, plus the plan.lock.json that binds them to the approved spec, source plan, and plan. Until now the compiled trio was written with three independent, non-atomic os.WriteFile calls and the lock with a fourth, separate write, so a crash or a failed verification mid-write could leave a compiled task graph without its evidence ledger, a partially rewritten graph, or a lock that pointed at a task graph that never landed. Consistency was only patched after the fact by hash and idempotency guards, and there was no single point that promoted the set all-or-nothing or that could reverse it.

activate-plan now assembles all four artifacts as one candidate MutationSet and routes it through a transactional mutation boundary. The bytes — including the lock, whose task-graph hash is bound from the in-memory compiled candidate rather than a disk read — are validated in isolation and promoted atomically: either every artifact lands as its exact validated bytes or none do. Each target carries a base precondition (its expected before-hash), so a stale candidate written against a file that changed underneath is rejected with the accepted state untouched. A supervisor authority token bound to the plan fingerprint rejects a candidate authorized against a state the supervisor has since advanced past. After the bytes are on disk a post-write verification re-reads and re-validates the promoted JSON, asserts the evidence ledger is non-empty, and re-checks the promoted lock against the plan, spec, and source plan; if any check fails, the boundary automatically rolls every file back to its captured before-bytes.

The boundary is closed under inversion, which is what makes undo correct rather than best-effort. Every successful promotion emits a durable receipt with per-file before/after hashes and inverse bytes — the receipt is the undo command. Undo re-applies that inverse as an ordinary mutation through the same boundary (an explicit absent/delete operation expresses "this file did not exist before", so the inverse of a create is a first-class MutationSet). Three properties fall out for free: undo is itself atomic and verified; undo records a new receipt whose own inverse is the original after-state, so redo is just undo of the undo receipt — no separate verb; and the base precondition is the conflict guard — if anything changed a file since it was written, undo refuses (ErrMutationConflict) instead of clobbering later work. Undo replay is idempotent: re-issuing the same undo replays its receipt rather than forking a new one.

Two bounded, agent-facing verbs expose this so operations stay smooth and never deadlock:

  • mutation-status --repo . [--mutation <id>] [--json] (read-only): list or inspect mutation receipts, so an agent can find the receipt to reverse — or, for redo, the undo receipt to reverse in turn.
  • undo --repo . --mutation <id> [--json]: reverse a managed artifact through the guarded inverse. Both verbs are allowlisted by the safety guard at any stage (like repair-state), still rejecting shell metacharacters and non-helper executables. undo is state-aware: before reversing a plan activation it refuses if a delivery gate receipt already exists, because removing the lock a live delivery depends on would strand delivery state. The primitive stays domain-agnostic; the guard lives in the verb layer.

This is the standing form of the recovery principle behind repair-state: a supervisor that removes an actuator must still expose a bounded actuator capable of reaching every valid state — including reversing its own last move. A rejected mutation never persists an identity, so a candidate recomputed against the current base and authority applies cleanly; refusal is fail-closed but never a deadlock. This boundary governs Boatstack's own generated managed artifacts only — the compiled plan and its lock — never coding-agent source-code editing, which stays outside the boundary.

Projection provenance

Generated from operatorstack/intelligence-flow@c7d80b2f99481f8065a5fc5f60ee4d41958f5efa.
Review provenance, tests, and examples before merging.

@operator-stack-publisher
operator-stack-publisher Bot merged commit a766961 into main Jul 24, 2026
4 checks passed
@operator-stack-publisher
operator-stack-publisher Bot deleted the sync/intelligence-flow-c7d80b2f9948 branch July 24, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants