Files
jason.woltje 068d868a99 lead: commit rocko's untracked evidence (4471 files: queue-124 queue-129 queue-171 queue-178 queue-280 queue-31 queue-84 queue-85 queue-94)
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
2026-11-02 15:05:15 -06:00

11 KiB

Row 85 — One pinned stack copy (#1579)

Rocko, gpt-6.1-sol. Base in base.txt (79e126be0). Reviewers Darkwing and Filbert; Sage requests review as jarvis. Candidate is uncommitted in the detached mosaic-stack-rocko-85 worktree. Mos released the build after Jason's re-test and Sage granted round 2's slot after Darkwing's row 103 gate. No live steps are executed.

Implementation

stack-copy.sh owns shared copies under XDG_DATA_HOME/mosaic-stack/copies. Copy requires ancestry of both local and origin/refactor, archives to a sibling temp directory, guards both package manifests, runs exact locked npm ci in that directory, removes file/directory write permission and renames atomically. Existing copies are not rebuilt. Failure/race paths remove their temp tree. webui-service.sh copy delegates; both services use the shared directory. Old Console-only copies and Q81 worktrees are retained.

Bus render/install take --copy and --pm, retaining the Claude pin and the checkout render without those flags. Install checks every loaded bus state, including with --no-reload; any non-inactive/non-failed state refuses. Failed/missing unit lookup paths refuse. Template and all instance ExecStart/WorkingDirectory drop-ins refuse by filename, while environment only drop-ins stay allowed. Status reads effective WorkingDirectory, ExecStart and DropInPaths, reports copy/checkout, PM and refactor drift.

Wrapper replaces only a regular Q81-marked wrapper, preserves its exact mosaic-old lease probe and marker on line 2, and uses a sibling temp rename. --bin is the fixture override. Check reads effective systemd roots and executables plus the wrapper exec: absent data or different trees fail; no proof path is added. The human verifier is untouched.

Import and runtime closure

out/import-closure.json records relative imports, URL child entrypoints and the source-directory closure of the wrapper entrypoints, host and Console. The archive covers bus/business/cli/conversation/discord/harness/seat/tasks/ webui source, queue source (scripts/mosaic dispatches it), adapters, roles, RELEASE, package.json/lock, both service READMEs, mosaic and mosaic-config. Runtime data outside src adds bus/schema.sql, tasks/fields.json and requirements.json; on-demand Discord helper/extension directories also ship. npm ci supplies node_modules and its installed lock record.

The real-install fixture checks checkEnginePin against both package locks, starts a fake-config bus host from the copy until bus host up, serves a Console healthz 200 from it, and runs the copy's scripts/mosaic talk against the production startBroker runtime loaded from the copy. A test-only module mock wraps verifyHuman using its existing readProcess seam only to stub agent ancestry while retaining the real child pid/start/argv/nonce; different-copy and checkout entry paths refuse. No code bypass, actual credential or live bus is involved.

Tests and mutation evidence

stack-copy.test tests pushed reachability, required archive paths, read-only publication/existing fast path, wrapper/foreign/symlink/lease, alignment and executable mismatch, both overriding drop-in fields, unknown metadata, busy installs and uninstall with --no-reload, effective status and the real pinned integration. Existing pinned-copy/service tests move to shared paths and assert effective WorkingDirectory. host.test's install fixture now stubs systemctl rather than consulting the live bus. No host.mjs edit. The CLI README change stays inside Bus host; row 103's other README sections are excluded. A second landing re-gates on its new base under decision 127, even without path drift.

The first mutant pass uncovered overlapping test guards (manifest absence already failed archive; foreign wrapper also lacked the lease; both unit executables mismatched). Tests now isolate each condition, and assert no npm rerun for an existing copy. A post-extraction missing-manifest fault proves the explicit temp manifest guard before npm can walk up. Final mutation/gate counts and receipts will follow below.

Protected live plan — STOP before this boundary

The one operator sequence lives in docs/TOOLS.md, Pinned stack update. After review, gate and landing, Sage notifies Mos (decisions 109/123). Mos approves each individual live step: no PM turn in flight; prepare the pushed copy; stop Console then bus; remove only overriding drop-ins, including initial pm.conf, and reload systemd; install bus --copy/--pm with the existing Claude pin, install Console with its current flags; switch the Q81 wrapper; start bus then Console; read alignment/status/ healthz/launches evidence. Jason's ordinary mosaic talk must print sent and a reply before #225 closes. The first rollback restores the saved mixed checkout/pm.conf, Console unit and Q81 wrapper. Later rollback uses the prior shared full id and the same Mos-gated sequence. No copy pruning, Q81 worktree removal or PM relaunch is authorized by this build. Candidate completion authorizes none of these live actions.

Reproduce

Detached worktree at base.txt, apply build.patch, link canonical pinned node_modules for the package suites; candidate-manifest.sha256 has repo-root paths. Run all bus/cli/webui *.test.mjs and gate.py with an absolute output directory. Set DOCKER_HOST=unix:///nonexistent.sock for every command. mutants.py takes a separate output directory and must not overlap other runs on this tree. Fixture npm ci is real; no unversioned dependency install.

Round 2 changes from round 1

Sage's round 2 assignment and Filbert's full #1579 comment 28243 (queue rev 984) govern this revision. Reopened in-progress at rev 989. Rebased from 0d71b9ddd onto 79e126be0 before any round 2 test; intervening changes touch only append-only logs. No candidate code committed.

B1: scan every directory returned by systemd-analyze --user unit-paths for [email protected] and [email protected].d/*.conf. This avoids systemd 261's rejected template show and discovers overrides for instances absent from list-units. Busy-instance detection still uses list-units; discovery/read failures refuse before writes. The conservative scan refuses either overriding field even if another lookup directory would shadow it: the operator gets the filename to resolve explicitly. Tests fake a rejected template show and an unlisted instance in a second lookup directory. Separate mutants reintroduce template show and remove instance discovery. Existing fixtures stub systemd-analyze too.

N1: TOOLS records the saved pre-first-update units/drop-ins, wrapper bytes and mode, pins/flags and effective paths. Its first rollback restores the checkout bus with its original pm.conf, original Console checkout or old mosaic-console copy and Q81 wrapper. The shared-copy check should refuse that mixed setup. Later rollback can use a prior shared copy id.

N2: the proof fixture calls the real pinned startBroker, so runtime.mjs supplies cliPath rather than the test constructing it. A child running Node's experimental test module mocks wraps only verifyHuman's readProcess ancestry seam; production runtime and human verifier remain unchanged. N3 needs no change. N4's steps 2-6 use an ASCII hyphen.

No real systemd probe, install, enable, daemon-reload, live source edit or live process action was performed. All full suites, mutants and final packet verification completed successfully.

Round 2 full gate

DOCKER_HOST=unix:///nonexistent.sock for every suite and mutant. Full suite receipt: out/full/gate-results.json (all exits 0).

Node package Passed Failed / skipped / cancelled
bus 127 0 / 0 / 0
business 67 0 / 0 / 0
cli 155 0 / 0 / 0
control-board 124 0 / 0 / 0
conversation 182 0 / 0 / 0
discord 178 0 / 0 / 0
harness 70 0 / 0 / 0
ledger 78 0 / 0 / 0
mosaic 69 0 / 0 / 0
queue 150 0 / 0 / 0
runs 43 0 / 0 / 0
seat 109 0 / 0 / 0
tasks 92 0 / 0 / 0
webui 108 0 / 0 / 0

Ledger runs directly via its test paths; package.json is not required.

Shell suite Passed Failure / coverage notes
test-auth.sh 15 0
test-conductor.sh 17 0
test-config.sh 24 0
test-discord.sh 66 0; also Discord node 178
test-extension-package.sh 18 0
test-foundation.sh 44 0; also foundation node 80
test-queue.sh 27 0; skips canonical-root verify/render checks
test-release.sh 4 0; skips Docker state-machine cases
test-task.sh 26 0; skips 72 Docker-gated checks

test-task's 26 cover schema/mission validation, unchanged task files, prune/receipts, onboarding and no headless agent identity. Its four skipped blocks contain 51 adapter/mission/retry/skills/roles/seat/policy/user-injection checks, 8 workspace/capability checks, 11 live task/session-fork checks and 2 live recall checks: 72 skipped, accounting for the difference from a Docker-capable 98. Exact case names and source ranges: out/task-coverage.md. This candidate has no Docker-capable execution claim.

No live systemd probe or write.

Round 2 mutants

Mutant Exit Result
ignore-pushed-ref 1 killed
skip-npm 1 killed
skip-manifest-guard 1 killed
missing-bus-schema 1 killed
missing-adapters 1 killed
missing-queue 1 killed
writable-copy-dirs 1 killed
writable-copy-files 1 killed
replace-existing 1 killed
accept-foreign-wrapper 1 killed
accept-wrapper-symlink 1 killed
lose-lease 1 killed
wrong-wrapper-tree 1 killed
ignore-effective-exec 1 killed
ignore-pm 1 killed
skip-install-guard 1 killed
ignore-dropin 1 killed
ignore-empty-metadata 1 killed
template-show-regression 1 killed
miss-unlisted-instance 1 killed
runtime-wrong-proof-entry 1 killed
status-hides-pm 1 killed
console-skips-working-dir 1 killed

23/23 killed, no survivors or timeouts. Each source file restored in finally; post-run manifest verification passes 11/11. Runtime-path mutation is test fault injection only and is absent from build.patch. Full gate ran 21:12:31-21:16:17 UTC; mutants finished 21:18:24 UTC. Process-clear receipt out/process-clear.txt reports busy [], exit 0; slot returned to Sage at 21:18:30 UTC. Both runners exited 0; no fixture process or network remains.

Manifest SHA256: bd7ea899c7cacef43b415b8e9ecb164e1f36718ffbe64347881a2c5653170c98. Patch applies to canonical HEAD and diff --check passes. The base update changed only logs; no candidate path drift. Pending Darkwing/Filbert review and Sage's gate, then Mos's individually approved live steps. No source commit or protected action is authorized by candidate completion.

Queue round 2 in-review rev 1009; expected tokenless request failed rev 1010. Sage posts as jarvis. Receipt out/queue-in-review.txt.