Commit Graph
11 Commits
Author SHA1 Message Date
terra a12eeb4786 fleet: share Claude credentials by directory env, not a seat symlink
Claude Code saves credentials by writing a sibling temp file and rename()-ing
it over the target. rename(2) replaces a symlink rather than following it, so
the managed link W-F1/W-F2 planted at <seat>/.claude/.credentials.json is
destroyed by the first token refresh and the seat silently forks its
credentials. The in-place fallback arm opens with O_NOFOLLOW and would refuse
the link anyway. Evidence, quoting the 2.1.232 binary:
docs/reports/harness/claude-credential-write-path-2026-08-14.md (jarvis-brain).

CLAUDE_SECURESTORAGE_CONFIG_DIR resolves the credential directory
independently of CLAUDE_CONFIG_DIR, so the temp file and the rename both land
inside the bundle. That is the property the design wanted -- share the
credential, never the transcripts -- with no symlink and no privileges.

- new fleet/credential-sharing.ts owns the harness -> credential-file and
  harness -> credential-directory-variable maps, so scaffold and launch cannot
  disagree about the mechanism. It also removes the duplicate credential-file
  name table the two already carried.
- launch composes CLAUDE_SECURESTORAGE_CONFIG_DIR from the resolved bundle
  directory and plans no credential link for Claude. The value is always the
  absolute bundle path: Claude reads an empty value as ~/.claude, which is the
  operator's own account.
- scaffold stops emitting the credential symlink and its manifest entry for
  Claude, and tolerates one left by an earlier scaffold rather than reporting
  it as a foreign file or rewriting it.
- FIRST_AUTH_REFUSAL still fires when a real file occupies the seat path.
- Harnesses absent from the map (pi, codex, opencode) keep managed links; the
  containment specs now exercise them on pi.

Answers promotion gate #1 negatively for the frozen mechanism and positively
for the replacement. E3.3 (two seats refreshing one bundle at once) is still
open.
2026-08-14 18:20:54 -05:00
terra 326a1a58b5 fix(fleet): harden managed launch composition
AMD1213-C: repair stale array consumer, fail closed on foreign link provenance, validate manifests before mutation, and exercise the fleet MCP preflight call path.
2026-08-13 15:37:32 -05:00
terra 2755f86f7b fix(fleet): seed seat MCP preflight config
AMD1213-B5: derive Claude seat MCP configuration from the active installed runtime base and inspect the isolated seat during fleet launch.
2026-08-13 14:38:25 -05:00
terra fe2cf19461 fix(fleet): preserve managed link provenance
AMD1213-B3: record Mosaic-owned links and refuse foreign or retargeted symlink mutations. Out-of-scope review follow-up: settings output/snapshot apply-time TOCTOU remains reported, not patched.
2026-08-13 14:38:25 -05:00
terra 4fde3f622d fix(fleet): contain credential trust roots
AMD1213-B4: reject symlinked auth ancestry and group/world-readable credential artifacts before composition can write.
2026-08-13 14:38:25 -05:00
terra 9de9ffa56b fix(lease): restore uniform settings array replacement
AMD1213-B1: preserve the gated Claude hook composition explicitly in the lease overlay while restoring last-layer-wins arrays and null tombstones.
2026-08-13 14:38:19 -05:00
Jason WoltjeandClaude Fable 5 5e15431027 fix(fleet): tolerate harness metadata files in the managed install root
ci/woodpecker/pr/ci Pipeline was canceled
Claude Code writes installed_plugins.json and other metadata files into
the seat's plugins directory during a session, so refusing every real
entry made composition fail on each seat's second launch. Only a real
directory is an unmanaged entry the pruner would orphan; plain files are
harness state and pass through untouched. Found by the in-box hour-gate
relaunch of the probe seat.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dtdjx4Gxude9fwyLezCrhh
2026-08-13 11:59:31 -05:00
Jason WoltjeandClaude Fable 5 c16256d48c fix(fleet): compose system settings from the installed flattened home layout
The installed ~/.config/mosaic home flattens the repo's
packages/mosaic/framework/ prefix: the real file is
<home>/runtime/<harness>/settings.json, exactly as launch.ts already
resolves it everywhere. The fleet launch composition leaked the repo
layout (framework/runtime/...) into the system layer path, so a real
installed home failed with COMPOSITION_FAILED while the temp-fixture
specs (which mirrored the same wrong prefix) stayed green. Found by the
in-box hour-gate dry-run against the installed mos-dev-stage home.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dtdjx4Gxude9fwyLezCrhh
2026-08-13 11:52:00 -05:00
Jason WoltjeandClaude Fable 5 92e790ae9d fix(fleet): additive hook-event merge and gated-composition acceptance reads
Integration adjudication (fred, W-F1): the general arrays-replace merge rule
conflicts with the gap-7 base/overlay split — base and lease overlay share
the PreToolUse and Stop events, so replace semantics would silently drop the
base QA hooks from every gated seat. Ruling: hook event arrays directly
under the top-level hooks key concatenate (base first); all other arrays
keep replace semantics; null tombstones still delete an event.

- mutator-gate acceptance now asserts lease wiring against the COMPOSED
  gated settings (base + lease-overlay via the launcher's own merge),
  matching the post-split contract.
- fleet subcommand canary gains the intended new 'agent' surface from T3.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dtdjx4Gxude9fwyLezCrhh
2026-08-13 11:44:58 -05:00
Jason WoltjeandClaude Fable 5 0fdcfa0ff4 fix(fleet): unify user data-home seam and add actionable unscaffolded-agent error
Integration reconciliation of T2/T3 seams on feat/wf-fleet-mvp:
- fleet launch now resolves the user root through defaultFleetDataHome()
  (MOSAIC_DATA_HOME), the same seam fleet agent new uses, instead of a
  divergent MOSAIC_USER_HOME variable.
- Launching an unscaffolded name raises AGENT_NOT_SCAFFOLDED with the
  actionable message pointing at 'mosaic fleet agent new <name>' (acceptance
  carried over from the T3 card after the roster-v2 reconciliation moved it
  onto the launch path).

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dtdjx4Gxude9fwyLezCrhh
2026-08-13 11:39:44 -05:00
Jason Woltje 378c227cbb feat(fleet): compose and launch profile-backed seats 2026-08-13 11:30:53 -05:00