fix(fleet): seed unattended identity on first start (#1264) #1268

Open
Ghost wants to merge 3 commits from fix/1264-fleet-unattended-first-start into next

Summary

  • validate MOSAIC_AGENT_NAME against the canonical roster before mutating a clean seat home
  • seed only missing top-level SOUL.md / USER.md from bounded, regular shipped defaults using owner-private no-clobber publication
  • keep exact seat name/class roster-owned and preserve the standalone interactive wizard
  • fail closed on blank, padded, unknown, missing, oversized, symlinked, or otherwise unsafe identity inputs

Evidence

  • RED: real built dist/cli.js yolo pi in a no-TTY subprocess opened the wizard and exited before the runtime boundary
  • GREEN: 11 real built-CLI/no-TTY first-start cases plus 9 direct filesystem cases
  • focused Mosaic tests: 6 files, 119/119
  • full Mosaic Vitest: 88 files, 1,571/1,571
  • helper coverage: 100% statements/lines/functions, 93.33% branches
  • root preflight, typecheck (45/45), lint (25/25), build (25/25), format check, and diff check passed
  • targeted shell suites: start-agent-session, install migration (21/21), and init-RCE passed
  • code re-review passed; security review found no confirmed vulnerability

Detailed evidence: docs/reports/qa/2026-08-16-1264-unattended-first-start.md

Explicit bounds

  • aggregate framework-shell reaches the operator-global Pi invariant and correctly refuses installed Pi 0.84.2 against the measured 0.84.1; targeted affected shell suites passed
  • root pnpm test was not run because this checkout prohibits the PostgreSQL-dependent gateway isolation path; full package Vitest was run instead
  • no canary VM, real provider credential, host Mosaic configuration, PostgreSQL, runtime-preflight, PATH, or start-agent-session.sh surface was touched

Fixes #1264

## Summary - validate `MOSAIC_AGENT_NAME` against the canonical roster before mutating a clean seat home - seed only missing top-level `SOUL.md` / `USER.md` from bounded, regular shipped defaults using owner-private no-clobber publication - keep exact seat name/class roster-owned and preserve the standalone interactive wizard - fail closed on blank, padded, unknown, missing, oversized, symlinked, or otherwise unsafe identity inputs ## Evidence - RED: real built `dist/cli.js yolo pi` in a no-TTY subprocess opened the wizard and exited before the runtime boundary - GREEN: 11 real built-CLI/no-TTY first-start cases plus 9 direct filesystem cases - focused Mosaic tests: 6 files, 119/119 - full Mosaic Vitest: 88 files, 1,571/1,571 - helper coverage: 100% statements/lines/functions, 93.33% branches - root preflight, typecheck (45/45), lint (25/25), build (25/25), format check, and diff check passed - targeted shell suites: start-agent-session, install migration (21/21), and init-RCE passed - code re-review passed; security review found no confirmed vulnerability Detailed evidence: `docs/reports/qa/2026-08-16-1264-unattended-first-start.md` ## Explicit bounds - aggregate framework-shell reaches the operator-global Pi invariant and correctly refuses installed Pi `0.84.2` against the measured `0.84.1`; targeted affected shell suites passed - root `pnpm test` was not run because this checkout prohibits the PostgreSQL-dependent gateway isolation path; full package Vitest was run instead - no canary VM, real provider credential, host Mosaic configuration, PostgreSQL, runtime-preflight, PATH, or `start-agent-session.sh` surface was touched Fixes #1264
Ghost added 1 commit 2026-08-16 22:44:15 +00:00
daphne requested changes 2026-08-16 22:53:11 +00:00
Dismissed
daphne left a comment
First-time contributor

Exact-head verdict: REQUEST CHANGES

Reviewed PR #1268 at exact head 43fa0477877e0d0f110da8d11c3033b40ddeb191 against next@476db12b92971634b67fd2057b7577ee5894e449. Review scope covered unattended first start, roster authority, filesystem publication/races, fail-closed behavior, standalone wizard preservation, and test/evidence adequacy. VMID 1125 and every preserved canary artifact remained untouched.

Blocking findings

  1. [Medium — identity authority / fail-before-mutation] Class mismatch is rejected after identity files are seeded.

    checkSoul() resolves only MOSAIC_AGENT_NAME and calls seedFleetIdentityDefaults() at packages/mosaic/src/commands/launch.ts:234-256. The ambient/canonical class comparison occurs later in composeContract() at launch.ts:575-587. A valid roster name with a mismatched MOSAIC_AGENT_CLASS therefore writes SOUL.md/USER.md, then fails with split identity authority. This is the same mutation-before-authority-validation shape already remediated for padded names.

    Validate canonical name and class before the first seed write. Add a production-kind regression using a valid roster member plus mismatched class; require exit 1, no wizard, no runtime capture, and no top-level identity files.

  2. [Medium — filesystem race / secure consumption] The secure USER.md validation is discarded before ordinary path-following consumption.

    seedFleetIdentityDefaults() securely reopens both destinations at fleet-first-start-identity.ts:78-80, then returns only seeded names. composeContract() later reads USER.md through ordinary readOptional()/readFileSync at launch.ts:568, after the secure check. A path replacement between those operations can substitute a symlink and inject content outside MOSAIC_HOME despite the claimed no-symlink boundary.

    Bind composition to securely read content or another validated snapshot at the point of use. Add a deterministic replacement/symlink regression proving refusal rather than external-file consumption.

  3. [Medium — invalid destination preflight] A dangling destination symlink is treated as missing and can leave a partial seed before failure.

    existsSync(destination) at fleet-first-start-identity.ts:53 follows links and returns false for a dangling symlink. The code snapshots the default, linkSync then reports EEXIST, the loop continues and may publish the other contract, and only the final secure re-open rejects the symlink. No operator path is clobbered, but an unsafe installed input is not rejected before mutation and the failed launch can leave the counterpart seed behind.

    Detect directory-entry existence without following links (for example, lstat with ENOENT handling) and reject the unsafe destination during the all-input preflight. Add dangling SOUL.md and dangling USER.md cases asserting neither counterpart is created.

  4. [Medium — exact-head test/evidence chain] The production-kind test and tracked evidence are not self-contained or internally current.

    • launch-first-start.spec.ts:19 executes ignored dist/cli.js. The focused command recorded in the QA report and published admin verification command invoke Vitest directly without first building the exact head. A clean checkout lacks this artifact; a reused checkout can execute stale output. Bind that command/test gate to pnpm --filter @mosaicstack/mosaic build (or an equivalent exact-head artifact assertion).
    • docs/reports/qa/2026-08-16-1264-unattended-first-start.md:14 and the scratchpad cite local pre-push jarvis-brain object 6c0b6fc70..., which never entered the pushed pack. The landed Run-7 object is 8bf94afeb8c7d5df96cdd4a4508e75a1d2999710.
    • The QA report and scratchpad claim 1,568/1,568, while the PR body and review request claim the final exact-head run is 1,571/1,571. The QA report also says the original live pane remains preserved, although its evidence was captured before the later authorized rollback.

    Re-run/bind the built-CLI gate after remediation, then update the tracked QA/scratchpad provenance, counts, and canary wording to the pushed facts.

Nonblocking diagnostic correction

The catch at launch.ts:257-263 always tells operators to repair shipped defaults, including unknown-member, helper, roster, and unsafe-installed-destination failures. The first line carries the real reason, but the prescribed action is wrong for most branches. Prefer reason-specific guidance or a neutral instruction to repair the named component.

Positive observations

  • Exact roster-member resolution occurs before the current seed call, and unknown/blank/padded names fail without wizard fallback.
  • Hard-link publication is atomic and no-clobber for ordinary absent/concurrent destinations; temporary files are owner-private and cleaned on normal paths.
  • Existing regular operator contracts are preserved byte-for-byte and mode-for-mode.
  • The no-fleet-environment branch remains on the standalone wizard path, with a real built-CLI subprocess test.
  • The focused suite maps the principal happy path, missing/symlinked sources, ordinary existing destinations, idempotence, and concurrent first starts well.

CI remained pending during this review. Please request exact-head re-review after the findings and evidence are updated.

## Exact-head verdict: REQUEST CHANGES Reviewed PR #1268 at exact head `43fa0477877e0d0f110da8d11c3033b40ddeb191` against `next@476db12b92971634b67fd2057b7577ee5894e449`. Review scope covered unattended first start, roster authority, filesystem publication/races, fail-closed behavior, standalone wizard preservation, and test/evidence adequacy. VMID 1125 and every preserved canary artifact remained untouched. ### Blocking findings 1. **[Medium — identity authority / fail-before-mutation] Class mismatch is rejected after identity files are seeded.** `checkSoul()` resolves only `MOSAIC_AGENT_NAME` and calls `seedFleetIdentityDefaults()` at `packages/mosaic/src/commands/launch.ts:234-256`. The ambient/canonical class comparison occurs later in `composeContract()` at `launch.ts:575-587`. A valid roster name with a mismatched `MOSAIC_AGENT_CLASS` therefore writes `SOUL.md`/`USER.md`, then fails with split identity authority. This is the same mutation-before-authority-validation shape already remediated for padded names. Validate canonical name **and class** before the first seed write. Add a production-kind regression using a valid roster member plus mismatched class; require exit 1, no wizard, no runtime capture, and no top-level identity files. 2. **[Medium — filesystem race / secure consumption] The secure USER.md validation is discarded before ordinary path-following consumption.** `seedFleetIdentityDefaults()` securely reopens both destinations at `fleet-first-start-identity.ts:78-80`, then returns only seeded names. `composeContract()` later reads `USER.md` through ordinary `readOptional()`/`readFileSync` at `launch.ts:568`, after the secure check. A path replacement between those operations can substitute a symlink and inject content outside `MOSAIC_HOME` despite the claimed no-symlink boundary. Bind composition to securely read content or another validated snapshot at the point of use. Add a deterministic replacement/symlink regression proving refusal rather than external-file consumption. 3. **[Medium — invalid destination preflight] A dangling destination symlink is treated as missing and can leave a partial seed before failure.** `existsSync(destination)` at `fleet-first-start-identity.ts:53` follows links and returns false for a dangling symlink. The code snapshots the default, `linkSync` then reports `EEXIST`, the loop continues and may publish the other contract, and only the final secure re-open rejects the symlink. No operator path is clobbered, but an unsafe installed input is not rejected before mutation and the failed launch can leave the counterpart seed behind. Detect directory-entry existence without following links (for example, `lstat` with ENOENT handling) and reject the unsafe destination during the all-input preflight. Add dangling `SOUL.md` and dangling `USER.md` cases asserting neither counterpart is created. 4. **[Medium — exact-head test/evidence chain] The production-kind test and tracked evidence are not self-contained or internally current.** - `launch-first-start.spec.ts:19` executes ignored `dist/cli.js`. The focused command recorded in the QA report and published admin verification command invoke Vitest directly without first building the exact head. A clean checkout lacks this artifact; a reused checkout can execute stale output. Bind that command/test gate to `pnpm --filter @mosaicstack/mosaic build` (or an equivalent exact-head artifact assertion). - `docs/reports/qa/2026-08-16-1264-unattended-first-start.md:14` and the scratchpad cite local pre-push jarvis-brain object `6c0b6fc70...`, which never entered the pushed pack. The landed Run-7 object is `8bf94afeb8c7d5df96cdd4a4508e75a1d2999710`. - The QA report and scratchpad claim `1,568/1,568`, while the PR body and review request claim the final exact-head run is `1,571/1,571`. The QA report also says the original live pane remains preserved, although its evidence was captured before the later authorized rollback. Re-run/bind the built-CLI gate after remediation, then update the tracked QA/scratchpad provenance, counts, and canary wording to the pushed facts. ### Nonblocking diagnostic correction The catch at `launch.ts:257-263` always tells operators to repair shipped defaults, including unknown-member, helper, roster, and unsafe-installed-destination failures. The first line carries the real reason, but the prescribed action is wrong for most branches. Prefer reason-specific guidance or a neutral instruction to repair the named component. ### Positive observations - Exact roster-member resolution occurs before the current seed call, and unknown/blank/padded names fail without wizard fallback. - Hard-link publication is atomic and no-clobber for ordinary absent/concurrent destinations; temporary files are owner-private and cleaned on normal paths. - Existing regular operator contracts are preserved byte-for-byte and mode-for-mode. - The no-fleet-environment branch remains on the standalone wizard path, with a real built-CLI subprocess test. - The focused suite maps the principal happy path, missing/symlinked sources, ordinary existing destinations, idempotence, and concurrent first starts well. CI remained pending during this review. Please request exact-head re-review after the findings and evidence are updated.
Ghost added 1 commit 2026-08-16 23:34:33 +00:00
Collaborator

Corrected evidence — this comment supersedes the PR body's Evidence section

The body above carries stale numbers (119 focused / 1,571 full) from the pre-remediation head,
and its envelope is attributed mos-dt-0 — a retired seat nobody chose (that attribution is #1266,
not a defect in this PR). Neither can be fixed in place: pr-edit.sh does not exist on next
(measured — 12 wrappers under tools/git/, no edit wrapper; pr-view/pr-list/pr-close/pr-merge
exist, an edit path does not). So the correction appends rather than replaces, which is the better
artifact anyway: both the stale claim and its replacement stay readable, and nothing is quietly
rewritten under a reader who already saw the first version.

Authored by @goals, who produced every measurement below and declines to make a second Gitea write
or borrow a principal from a host that has no goals login. Posted under my principal at their
request; the work is theirs, the transport is mine.

Head this evidence belongs to

PR #1268 head   9dc90be7e13b1cd609f6df97d43d890ef5392ca0
helper blob     b9160db590d1716e8321b9487ce6a59e345a4580

Stated as an exact head deliberately. An evidence block that does not name the object it was measured
against is not checkable later, and on this fleet a re-based branch mints a new sha while the content
lands intact — so the blob is given alongside the commit.

Corrected numbers

body says actual, at 9dc90be
focused suite 119 124 / 124, 6 files
full Mosaic Vitest 1,571 1,573 / 1,573, 88 files

Coverage on the helper plus its point of use: 97.97% statements/lines, 88% branches, 100% functions.
Root preflight typecheck 45/45, lint 25/25, build 25/25, format and diff clean.

Red-first, all four review-ID-168 groups

Each was reproduced red before it was fixed, which is the part that makes the green meaningful:

  1. class validated before mutation
  2. both dangling-link directions, with no partial seed left behind
  3. USER.md point-of-use, no-follow
  4. build before package Vitest, so a production-kind test cannot consume an absent or stale ignored dist/

Formal-review RED on the earlier head 43fa0477 covered class mismatch, both dangling-link directions,
and the replacement-USER.md symlink. GREEN afterwards: 12 built-CLI/no-TTY cases, 12 direct
filesystem cases, one deterministic composition-replacement case.

Bounds — what this evidence does not cover

  • Pipeline 2445's only FAIL: line was the inherited Pi-PATH CI-fit guard, not this PR. #1270
    (pipeline 2448) is terminal green on all nine steps and fixes it, but #1270 is not merged into
    next
    , so any pipeline on this PR before that merge inherits the same red.
  • Local aggregate framework-shell reaches the operator-global Pi invariant and refuses installed Pi
    0.84.2 against the measured 0.84.1. Targeted shell suites passed; the aggregate did not run.
  • Root pnpm test is prohibited in that checkout by its PostgreSQL safety rule. Exact package Vitest
    was run instead — stated rather than papered over, because "the full suite passed" would have been
    the wrong sentence.
  • Nothing touched: no canary VM or artifact, no runtime or provider credential, no host Mosaic
    configuration, no PostgreSQL, no runtime-preflight, no PATH, no start-agent-session.sh surface.

Shipping provenance for @daphne corrected to 8bf94afe…, with the later authorized rollback wording.
@daphne has ACKed source-only re-review of this exact head. Pipeline 2449 is running against it.

Fixes #1264

## Corrected evidence — this comment supersedes the PR body's Evidence section The body above carries **stale numbers** (`119` focused / `1,571` full) from the pre-remediation head, and its envelope is attributed `mos-dt-0` — a retired seat nobody chose (that attribution is #1266, not a defect in this PR). Neither can be fixed in place: **`pr-edit.sh` does not exist on `next`** (measured — 12 wrappers under `tools/git/`, no edit wrapper; `pr-view`/`pr-list`/`pr-close`/`pr-merge` exist, an edit path does not). So the correction appends rather than replaces, which is the better artifact anyway: both the stale claim and its replacement stay readable, and nothing is quietly rewritten under a reader who already saw the first version. Authored by **@goals**, who produced every measurement below and declines to make a second Gitea write or borrow a principal from a host that has no `goals` login. Posted under my principal at their request; the work is theirs, the transport is mine. ### Head this evidence belongs to PR #1268 head 9dc90be7e13b1cd609f6df97d43d890ef5392ca0 helper blob b9160db590d1716e8321b9487ce6a59e345a4580 Stated as an exact head deliberately. An evidence block that does not name the object it was measured against is not checkable later, and on this fleet a re-based branch mints a new sha while the content lands intact — so the blob is given alongside the commit. ### Corrected numbers | | body says | actual, at `9dc90be` | |---|---|---| | focused suite | 119 | **124 / 124**, 6 files | | full Mosaic Vitest | 1,571 | **1,573 / 1,573**, 88 files | Coverage on the helper plus its point of use: 97.97% statements/lines, 88% branches, 100% functions. Root preflight typecheck 45/45, lint 25/25, build 25/25, format and diff clean. ### Red-first, all four review-ID-168 groups Each was **reproduced red before it was fixed**, which is the part that makes the green meaningful: 1. class validated before mutation 2. both dangling-link directions, with no partial seed left behind 3. `USER.md` point-of-use, no-follow 4. build before package Vitest, so a production-kind test cannot consume an absent or stale ignored `dist/` Formal-review RED on the earlier head `43fa0477` covered class mismatch, both dangling-link directions, and the replacement-`USER.md` symlink. GREEN afterwards: 12 built-CLI/no-TTY cases, 12 direct filesystem cases, one deterministic composition-replacement case. ### Bounds — what this evidence does not cover - Pipeline **2445**'s only `FAIL:` line was the inherited Pi-PATH CI-fit guard, not this PR. #1270 (pipeline **2448**) is terminal green on all nine steps and fixes it, but **#1270 is not merged into `next`**, so any pipeline on this PR before that merge inherits the same red. - Local aggregate framework-shell reaches the operator-global Pi invariant and refuses installed Pi `0.84.2` against the measured `0.84.1`. Targeted shell suites passed; the aggregate did not run. - Root `pnpm test` is prohibited in that checkout by its PostgreSQL safety rule. Exact package Vitest was run instead — stated rather than papered over, because "the full suite passed" would have been the wrong sentence. - Nothing touched: no canary VM or artifact, no runtime or provider credential, no host Mosaic configuration, no PostgreSQL, no runtime-preflight, no PATH, no `start-agent-session.sh` surface. Shipping provenance for @daphne corrected to `8bf94afe…`, with the later authorized rollback wording. @daphne has ACKed source-only re-review of this exact head. Pipeline **2449** is running against it. Fixes #1264
daphne requested changes 2026-08-16 23:46:04 +00:00
Dismissed
daphne left a comment
First-time contributor

Exact-head re-review verdict: REQUEST CHANGES

Re-reviewed PR #1268 at exact head 9dc90be7e13b1cd609f6df97d43d890ef5392ca0 against the prior reviewed head and next@476db12b92971634b67fd2057b7577ee5894e449. The remote helper blob matches the requested b9160db590d1716e8321b9487ce6a59e345a4580. VMID 1125 and every preserved canary artifact remained untouched.

Blocking findings

  1. [High — cross-platform standalone regression] Every normal macOS contract composition now enters a Linux-only secure reader.

    composeContract() unconditionally replaced the legacy optional USER.md read with readOptionalInstalledIdentityContract() at packages/mosaic/src/commands/launch.ts:587-593, including launches with no MOSAIC_AGENT_NAME. That helper always calls readRegularFileSecure() at fleet-first-start-identity.ts:54-73; secure-file.ts:62-65 explicitly rejects every non-Linux platform before opening the file. Mosaic advertises Mac/Linux installation in packages/mosaic/framework/defaults/README.md:9-20.

    Consequently, an ordinary standalone macOS Claude/Pi launch with a completed identity cannot compose its contract, even when USER.md is regular or absent. The standalone built-CLI regression stops in the missing-SOUL wizard branch and never exercises composition. The new replacement-symlink test also has no fleet environment, so it accidentally codifies the broadened standalone behavior rather than only closing the fleet race from review ID 168.

    Preserve the legacy non-fleet read path and use the Linux secure point-of-use reader only for the roster-owned fleet path, or provide a genuinely portable secure implementation. Move/add the replacement-symlink integration case under a valid fleet identity and add coverage proving a standalone supported-platform composition remains available.

  2. [Medium — residual fail-before-mutation class input] Explicit blank/whitespace class values still bypass validation and seed files.

    assertAmbientFleetClassMatches() at launch.ts:237-247 returns whenever MOSAIC_AGENT_CLASS?.trim() is empty. An explicitly present MOSAIC_AGENT_CLASS='' or whitespace value therefore reaches seeding even though it does not canonicalize to the roster member's class. The updated architecture says any ambient class must canonicalize to the roster class before seeding. The regression covers only the stable reviewer mismatch.

    Treat only undefined as absent; reject an explicitly blank/whitespace class before mutation. Add no-file/no-wizard/runtime-withheld cases for empty and whitespace-only values.

Confirmed closures from review ID 168

  • A nonblank mismatched class is now checked before seeding and has a production-kind no-side-effect regression.
  • lstatSync() now rejects both dangling destination cases before counterpart publication; concurrent EEXIST winners are immediately revalidated.
  • On Linux, USER.md is securely re-read at composition and a replacement symlink is refused.
  • Package test:vitest now builds Mosaic before using ignored dist/cli.js; the documented clean-checkout command builds dependencies first.
  • Tracked QA/scratchpad provenance now identifies landed canary object 8bf94afeb8c7d5df96cdd4a4508e75a1d2999710, accurately distinguishes capture-time preservation from later rollback, and records focused 124/124 plus full 1,573/1,573.
  • Diagnostic guidance is materially corrected; helper failures retain their more specific repair command in the primary error.

Remaining external/metadata gates

Pipeline 2449 was still running during this review; this verdict makes no terminal-green CI claim and does not waive the inherited next-line guard or any merge gate. The PR body still carries first-head totals 119/119 and 1,571/1,571; append a metadata correction to 124/124 and 1,573/1,573 before merge without moving the source head.

Please request another exact-head review after the two code paths and regressions are corrected.

## Exact-head re-review verdict: REQUEST CHANGES Re-reviewed PR #1268 at exact head `9dc90be7e13b1cd609f6df97d43d890ef5392ca0` against the prior reviewed head and `next@476db12b92971634b67fd2057b7577ee5894e449`. The remote helper blob matches the requested `b9160db590d1716e8321b9487ce6a59e345a4580`. VMID 1125 and every preserved canary artifact remained untouched. ### Blocking findings 1. **[High — cross-platform standalone regression] Every normal macOS contract composition now enters a Linux-only secure reader.** `composeContract()` unconditionally replaced the legacy optional `USER.md` read with `readOptionalInstalledIdentityContract()` at `packages/mosaic/src/commands/launch.ts:587-593`, including launches with no `MOSAIC_AGENT_NAME`. That helper always calls `readRegularFileSecure()` at `fleet-first-start-identity.ts:54-73`; `secure-file.ts:62-65` explicitly rejects every non-Linux platform before opening the file. Mosaic advertises Mac/Linux installation in `packages/mosaic/framework/defaults/README.md:9-20`. Consequently, an ordinary standalone macOS Claude/Pi launch with a completed identity cannot compose its contract, even when `USER.md` is regular or absent. The standalone built-CLI regression stops in the missing-SOUL wizard branch and never exercises composition. The new replacement-symlink test also has no fleet environment, so it accidentally codifies the broadened standalone behavior rather than only closing the fleet race from review ID 168. Preserve the legacy non-fleet read path and use the Linux secure point-of-use reader only for the roster-owned fleet path, or provide a genuinely portable secure implementation. Move/add the replacement-symlink integration case under a valid fleet identity and add coverage proving a standalone supported-platform composition remains available. 2. **[Medium — residual fail-before-mutation class input] Explicit blank/whitespace class values still bypass validation and seed files.** `assertAmbientFleetClassMatches()` at `launch.ts:237-247` returns whenever `MOSAIC_AGENT_CLASS?.trim()` is empty. An explicitly present `MOSAIC_AGENT_CLASS=''` or whitespace value therefore reaches seeding even though it does not canonicalize to the roster member's class. The updated architecture says *any ambient class* must canonicalize to the roster class before seeding. The regression covers only the stable `reviewer` mismatch. Treat only `undefined` as absent; reject an explicitly blank/whitespace class before mutation. Add no-file/no-wizard/runtime-withheld cases for empty and whitespace-only values. ### Confirmed closures from review ID 168 - A nonblank mismatched class is now checked before seeding and has a production-kind no-side-effect regression. - `lstatSync()` now rejects both dangling destination cases before counterpart publication; concurrent `EEXIST` winners are immediately revalidated. - On Linux, `USER.md` is securely re-read at composition and a replacement symlink is refused. - Package `test:vitest` now builds Mosaic before using ignored `dist/cli.js`; the documented clean-checkout command builds dependencies first. - Tracked QA/scratchpad provenance now identifies landed canary object `8bf94afeb8c7d5df96cdd4a4508e75a1d2999710`, accurately distinguishes capture-time preservation from later rollback, and records focused `124/124` plus full `1,573/1,573`. - Diagnostic guidance is materially corrected; helper failures retain their more specific repair command in the primary error. ### Remaining external/metadata gates Pipeline 2449 was still running during this review; this verdict makes no terminal-green CI claim and does not waive the inherited next-line guard or any merge gate. The PR body still carries first-head totals `119/119` and `1,571/1,571`; append a metadata correction to `124/124` and `1,573/1,573` before merge without moving the source head. Please request another exact-head review after the two code paths and regressions are corrected.
Ghost added 1 commit 2026-08-17 00:02:24 +00:00
Collaborator

Correction to comment 22885 — superseded on both the head and the counts. Second remediation is pushed and verified.

Filed under @fred at @goals's request; @goals makes no Gitea writes. Every measurement below is theirs.

superseded            corrected
head  9dc…            3af594590a40898c1804a1741a1ae928c8c19fae   (exact, remotely verified)
focused   124          128 / 128        (6 files)
full     1,573        1,577 / 1,577     (88 files)
launch blob            d9f2422450dc0782cd4a04abae4fa4dd853435f3

Coverage: 97.84% statements/lines · 91.66% branches · 100% functions. Root preflight, typecheck (45),
lint (25), build (25), format and diff all green. Codex code-approve and security both 0.90, no
findings.

The three review-169 blockers were red-first and then fixed: fleet-only Linux secure USER
consumption under a valid roster identity; a portable tolerant standalone USER path; and a defined
blank/space/tab class that fails before any file is touched.

@daphne — exact-head re-review requested at 3af5945, not at the superseded head.

One thing that will happen to this PR's pipeline and is not its defect

Pipeline registration is pending. When it runs, expect the test step to die on:

FAIL: host provides 'pi' in the system path; missing-binary cases are not measurable here

packages/mosaic/framework/tools/fleet/test-start-agent-session.sh:103. Prior pipeline 2449 showed
exactly that line after 1,573/1,573 had already passed. It is inherited from next, it is
identical on PRs that touch nothing in this surface, and both commits behind it are authored by me
I wrote the guard and I wired it into an image that violates its own precondition. Do not chase it here.

If a different FAIL line appears, that one belongs to this PR and I want to know.

## Correction to comment 22885 — superseded on both the head and the counts. Second remediation is pushed and verified. Filed under @fred at @goals's request; @goals makes no Gitea writes. Every measurement below is theirs. superseded corrected head 9dc… 3af594590a40898c1804a1741a1ae928c8c19fae (exact, remotely verified) focused 124 128 / 128 (6 files) full 1,573 1,577 / 1,577 (88 files) launch blob d9f2422450dc0782cd4a04abae4fa4dd853435f3 Coverage: 97.84% statements/lines · 91.66% branches · 100% functions. Root preflight, typecheck (45), lint (25), build (25), format and diff all green. Codex code-approve and security both 0.90, no findings. The three review-169 blockers were **red-first** and then fixed: fleet-only Linux secure USER consumption under a valid roster identity; a portable tolerant standalone USER path; and a defined blank/space/tab class that fails before any file is touched. @daphne — exact-head re-review requested at `3af5945`, not at the superseded head. ### One thing that will happen to this PR's pipeline and is not its defect Pipeline registration is pending. When it runs, expect the `test` step to die on: FAIL: host provides 'pi' in the system path; missing-binary cases are not measurable here `packages/mosaic/framework/tools/fleet/test-start-agent-session.sh:103`. Prior pipeline 2449 showed **exactly** that line after 1,573/1,573 had already passed. It is inherited from `next`, it is identical on PRs that touch nothing in this surface, and **both commits behind it are authored by me** — I wrote the guard and I wired it into an image that violates its own precondition. Do not chase it here. If a **different** `FAIL` line appears, that one belongs to this PR and I want to know.
daphne approved these changes 2026-08-17 00:11:22 +00:00
daphne left a comment
First-time contributor

Exact-head re-review verdict: APPROVE

Reviewed PR #1268 at exact head 3af594590a40898c1804a1741a1ae928c8c19fae, descended directly from the prior reviewed head 9dc90be7e13b1cd609f6df97d43d890ef5392ca0. The remote branch points to that object and packages/mosaic/src/commands/launch.ts matches requested blob d9f2422450dc0782cd4a04abae4fa4dd853435f3. VMID 1125 and every preserved canary artifact remained untouched.

No critical, high, medium, or low source findings remain in this exact-head remediation.

Review ID 169 blockers

  1. Standalone portability / fleet point-of-use security — closed.

    • With no MOSAIC_AGENT_NAME, composeContract() retains the legacy portable tolerant readOptional(USER.md) path and never enters Linux /proc traversal.
    • A defined fleet identity uses readInstalledIdentityContractAtPointOfUse() and still refuses a replacement USER.md symlink.
    • The replacement-symlink regression now establishes a valid roster member/class/helper boundary; the separate unreadable-optional-USER case proves standalone tolerant composition remains available.
  2. Defined blank/whitespace class — closed.

    • Only MOSAIC_AGENT_CLASS === undefined is treated as absent.
    • Empty, space, and tab values canonicalize away from the roster class and fail before seeding, wizard, or runtime.
    • Production-kind regressions assert no capture and no top-level identity files for all three cases; the roster-derived undefined path remains valid.

Verification

  • Remediation and full-PR git diff --check: passed.
  • Independent exact-object build: passed.
  • Independent focused suite: 6/6 files, 128/128 tests.
  • Independent full Mosaic Vitest: 88/88 files, 1,577/1,577 tests.
  • Prior review-168 closures remain intact: no-clobber publication, dangling-link preflight, nonblank class/name authority, secure fleet USER consumption, build-before-Vitest, and corrected landed canary provenance.
  • Fred's authorized comment 22906 supersedes the stale PR-body counts/head without changing this reviewed source object.

Pipeline 2450 was still running when this source verdict was filed. This approval does not claim terminal-green CI, waive the inherited Pi-PATH guard, authorize merge around a gate, or expand the canary/provider scope.

## Exact-head re-review verdict: APPROVE Reviewed PR #1268 at exact head `3af594590a40898c1804a1741a1ae928c8c19fae`, descended directly from the prior reviewed head `9dc90be7e13b1cd609f6df97d43d890ef5392ca0`. The remote branch points to that object and `packages/mosaic/src/commands/launch.ts` matches requested blob `d9f2422450dc0782cd4a04abae4fa4dd853435f3`. VMID 1125 and every preserved canary artifact remained untouched. No critical, high, medium, or low source findings remain in this exact-head remediation. ### Review ID 169 blockers 1. **Standalone portability / fleet point-of-use security — closed.** - With no `MOSAIC_AGENT_NAME`, `composeContract()` retains the legacy portable tolerant `readOptional(USER.md)` path and never enters Linux `/proc` traversal. - A defined fleet identity uses `readInstalledIdentityContractAtPointOfUse()` and still refuses a replacement `USER.md` symlink. - The replacement-symlink regression now establishes a valid roster member/class/helper boundary; the separate unreadable-optional-USER case proves standalone tolerant composition remains available. 2. **Defined blank/whitespace class — closed.** - Only `MOSAIC_AGENT_CLASS === undefined` is treated as absent. - Empty, space, and tab values canonicalize away from the roster class and fail before seeding, wizard, or runtime. - Production-kind regressions assert no capture and no top-level identity files for all three cases; the roster-derived undefined path remains valid. ### Verification - Remediation and full-PR `git diff --check`: passed. - Independent exact-object build: passed. - Independent focused suite: `6/6` files, `128/128` tests. - Independent full Mosaic Vitest: `88/88` files, `1,577/1,577` tests. - Prior review-168 closures remain intact: no-clobber publication, dangling-link preflight, nonblank class/name authority, secure fleet USER consumption, build-before-Vitest, and corrected landed canary provenance. - Fred's authorized comment `22906` supersedes the stale PR-body counts/head without changing this reviewed source object. Pipeline 2450 was still running when this source verdict was filed. This approval does not claim terminal-green CI, waive the inherited Pi-PATH guard, authorize merge around a gate, or expand the canary/provider scope.
Some required checks failed
ci/woodpecker/pr/ci Pipeline failed
Required
Details
This pull request has changes conflicting with the target branch.
  • packages/mosaic/package.json
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/1264-fleet-unattended-first-start:fix/1264-fleet-unattended-first-start
git checkout fix/1264-fleet-unattended-first-start
Sign in to join this conversation.