carlos / platform Public

isolated-exec-layout

Plan 4 of #126: the box side of the layout move. It moves an activator-managed instance between the flat layout (uid carlos, shared /data) and the nested one (its own directory behind a mount namespace) and back, recoverably. Nothing on this branch makes a row nested without a recorded nested intent, and only plan 5's verb writes one, so merging changes nothing on any box.

What it adds

  • internal/layout: a per-host plan, a durable journal (O_EXCL, fsynced, replaced atomically), and preflight. Directories are created through openat2 fds with no symlink followed, and their mode and group come by inheritance and are checked.
  • The pass: - quiesces under a fence it shares with the #175 move worker; - completes a crashed move, then converges the host before releasing it; - is gated on the isolation probe; - defers awake hosts.
  • The agent recovers at startup, after the unit sweep and before the activator starts, and runs a single-flight leg on each serial move. SyncExec, litestream and moves stay out of a journaled host. The intent is read from control/layout.json, which the fleet store door now serves.
  • Status and console: - a per-box layout report on the private box snapshot; - GET /api/cli/status/layout (operator only); - a Layout fact on the instance page; - carlos status --layout.
  • Downgrade guards: system apply of a pre-layout release, carlos route --hibernate=false, carlos add and the reconciler all refuse a nested or journaled row.

How it was built

  • 25 amendments from a drift audit against main (docs/superpowers/plans/2026-09-25-isolated-exec-4-layout-amendments.md) take precedence over the 2026-09-12 plan.
  • Each task had a spec and quality review, with Opus on the security and concurrency tasks, then a whole-branch Fable review and one fix wave.
  • The final review's Critical (EnsureDirs stripping setgid, because carlos is not in carlos-sockets) was fixed and checked on dev as carlos against the real /data and /run/carlos.
  • CI passed on be185920.

Open before merge

  1. internal/console/apistatuslayout.go:64 still has an unreviewed error string with an em dash. The --layout flag's one-line summary also awaits copy review.
  2. After any agent restart, status reports layout mode none until the next serial bump. The fix is small: publish the intent asynchronously once the pass is armed.

Accepted residuals (spec §1.3/§3.3): during the transition, a same-uid flat tenant can release a nested neighbour flat by deleting or forging journals. It could already write the registry and read /data/.instances, so this gains it nothing.

Human

#126 plan 4: the box side of layout migrate/revert (journal, CAS, fence, recovery, status field, downgrade guards). Nothing mints a nested row without a recorded intent.

Commits 38
Files changed 56 +7771 −48
Discussions 0 0 open
Tasks 7/8 done

Discussions

  • No discussions on this branch yet.

Tasks 7/8 done

  • Task 1: SetInstancePaths, Unfence, the intent object Done
  • Task 2: the plan and the journal Done
  • Task 3: preflight, directories, and the pass Done
  • Task 4: agent wiring and the fenced consumers Done
  • Task 5: status, console page, carlos status --layout Started

Activity