From c4bba5d2a3936897035c0e8fc8c3e14ca96b73af Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 24 Oct 2026 23:24:07 -0500 Subject: [PATCH 1/2] row334: render P1 proxy system unit in Case 2 installs --- BUILD-LOG.md | 4 + agents/rockerduck/work/queue-334/BUILD.md | 102 ++ agents/rockerduck/work/queue-334/imports.txt | 69 ++ .../rockerduck/work/queue-334/red-install.log | 68 ++ .../rockerduck/work/queue-334/red-results.txt | 52 ++ agents/rockerduck/work/queue-334/red-unit.log | 873 ++++++++++++++++++ docs/SESSIONS.md | 3 + packages/cli/tests/case2-install.test.mjs | 7 + packages/cli/tests/case2-unit.test.mjs | 172 +++- scripts/case2-install.sh | 2 +- scripts/case2-unit.sh | 87 +- 11 files changed, 1414 insertions(+), 25 deletions(-) create mode 100644 agents/rockerduck/work/queue-334/BUILD.md create mode 100644 agents/rockerduck/work/queue-334/imports.txt create mode 100644 agents/rockerduck/work/queue-334/red-install.log create mode 100644 agents/rockerduck/work/queue-334/red-results.txt create mode 100644 agents/rockerduck/work/queue-334/red-unit.log diff --git a/BUILD-LOG.md b/BUILD-LOG.md index b912071b1..49da7d66f 100644 --- a/BUILD-LOG.md +++ b/BUILD-LOG.md @@ -5816,3 +5816,7 @@ Before: agents can read the library; supporting-path and push-credential depende 2026-10-26 | Sage | mos1884/#662 scope after330/331landing | ReadQ222/Q261/Q263 and659/660/662; posted bounded human-only factory settings/triage/defaulttwo-roundmandate/trackedno-exemptionflake scope with10acceptance criteria, task662comment1338 exactwholebody/author13GETverified. No implementation/review/gate launched.660c1335notready(review/merge, noVM); gatefacts1329/1334 retained; target integration/fullrunner confirmation follows readiness, no localfallback. Landedproduct/evidence unchanged;657/658backlog. 2026-10-26 | Sage | Mos1909/1915/1917 real postlanding reviews | Boyd/Dewey/Filbert/Gladstone real authored candidate52ba verdictfiles independently byte/hash-verified, allAPPROVE scoped; Dewey656broaderPARTIAL retained. Formal330R1/331R4 requests failedpre-send/no comments or approvals; no borrowed/copied/mintedkeys. LegacyhelperGETname jason.woltje is NOT ownJarvis, ownslotabsent; rows tracking-open/#436, files cited via normalqueue. NewFilbertNEW-330-01 filedtask665 exactreadback, notlandingreopen/gate. Repair646-648/652-656 remainOPEN untilactualcomments;1917 conditionalbacklog routing retained. #662scope1338posted;660PR405REVISE/notready. Product1968inputs unchanged; no source/helper/test/gate edits/runs; peerjournal prefixes preserved. + +2026-10-25 — Rockerduck row334 (#1832), before: Case 2 renders bus/Console only. Plan: reuse P1 proxy template/runner under --proxy, enforce three-unit re-install checks and proxy→bus→Console starts, cover refusals and both named mutants. Tests held for Sage CLEAR; design in agents/rockerduck/work/queue-334/BUILD.md. + +2026-10-25 — Rockerduck row334 (#1832), RED evidence: whole case2-unit.test.mjs against baseline has 48 pass/33 expected new fail; whole case2-install.test.mjs has 27 pass/1 expected new fail. All 74 older tests pass. Implementations restored. Sage sage-4390 authorizes seat-branch candidate commit/push before GREEN; GREEN/mutants held until separate CLEAR after row331. Per-failure evidence: agents/rockerduck/work/queue-334/red-results.txt. diff --git a/agents/rockerduck/work/queue-334/BUILD.md b/agents/rockerduck/work/queue-334/BUILD.md new file mode 100644 index 000000000..c1483a5c0 --- /dev/null +++ b/agents/rockerduck/work/queue-334/BUILD.md @@ -0,0 +1,102 @@ +# Row 334 — Case 2 proxy unit (#1832) + +## Design at 78b69e1e6 (2026-10-25) + +Scope: mos-1616 ruling 1, P1 item 7 only. No template, runner, PIN, +user-unit path, config/secret access, or live unit changes. + +Current references: case2-unit.sh template seams 44-45, defaults 54-57, +render 435, check_unit 489, render checks 548-551, re-install 553-573, +active-state capture 576-580, writes/start/report 583-610. +case2-install.sh Next: 231. P1 instance.sh PROXY_UNIT 86; +bus-service.sh dependency insertion 93. P1 template ExecStart 13; +run.mjs validates config 11-13 and calls startVerifiedProxy 14; +runner.mjs refuses proxy-not-configured 8, verifyInstall 9; +settings.mjs verifyInstall 23-30 refuses proxy-install-invalid for a hash +mismatch. run.mjs catches that and exits 3. P1 item 7 is rows doc 86-90; +row209 entry check 2 remains 32-36. + +Add bare --proxy and CASE2_PROXY_TEMPLATE. Render P1's unmodified template +with copy, PATH, node and deleted CONFIG_ENV; add User/Group plus bus's four +hardening lines, no capabilities or EnvironmentFile. check_unit proxy uses +exact node + copy/packages/model-proxy/src/run.mjs, NoNewPrivileges=yes, +and every common refusal. Restrict CLAUDE_ENV expectation and capabilities +to their existing bus/webui kinds. Insert bus Wants/After immediately after +Description exactly as P1 does, only with --proxy. No-proxy output remains +byte identical. + +Re-install checks all selected units against render modulo copy id and +compares every installed copy id. Existing proxy without --proxy refuses +before writes, including a dangling symlink. No deletion. Enable all +selected units, then start proxy, bus, Console. Capture/report already-running +proxy with the others and name all three in restart-together guidance. +Change only case2-install.sh's closing Next: to tell root to add --proxy +when the config has a proxy section. + +Tests first, unrun until Sage CLEAR: byte-identical non-proxy renders; +proxy content and exact dependencies; each common/proxy check_unit refusal +by message; rendered ExecStart wrong-PIN refusal proxy-install-invalid rc 3; +three-unit re-install and mixed copies including proxy-only mismatch; +installed proxy without flag preserves files; start order and failures; +already-running report; install Next: guidance. Named mutants: remove bus +After=; direct binary ExecStart bypassing run.mjs. Whole-file run list will +be derived from static imports before any run; case1-accept stays off. + +P2 is not present on this base (row331 still in progress); inspect landed +P2 refusal code before final handoff. No flag/config false-positive check: +P1 startVerifiedProxy refuses proxy-not-configured, run.mjs exits 3. + +## Slot / session + +No tests run. CLEAR pending from Sage. Canonical queue start initially +refused: lock held by magica-331-start since 03:57:01.839Z. Same operation +will be retried after a minute; no lock manipulation. + +Correction to line references above: row209 entry check 2 is 29-33; +run.mjs config validation 8-10, runner call 11, refusal exit status 18. +case2-unit.sh is byte-identical to brief base 58b2bbb3a (sha256 +4ca8769134d83ee391bcc73af5bd042b9e2b161cac22821d29fcca710a9afad4). +P1 paths named above have no diff between 86cb5c221 and 78b69e1e6. +Own-worktree root npm ci --ignore-scripts --no-audit --no-fund: rc 0, +128 packages. No tests invoked. + +Sage sage-4346 accepts design, authorizes writing RED tests then code while +holding all runs until CLEAR. Tests were written first, then implementation; +no RED run has occurred. Installed proxy without --proxy explicitly refuses +and preserves bytes; dangling symlink also refuses, never deletes. P2 code +remains pending until row331 lands. Both wrong-flag P1 runner paths covered. + +Import-manifest correction: expanded traversal to include multiline import +and export-from edges (the business/library barrel modules). Closure is +53 local modules; only the same two test entrypoints occur. The run list +is unchanged; this is source inspection, no tests executed. + +Queue start completed: rockerduck-334-start rev4079, row334 +briefed→in-progress. git diff --check passed. Implementation, tests and +import manifest prepared; no tests, commits or pushes performed. Verification +awaits Sage's CLEAR; no live host/instance access occurred. + +## RED run authorized by sage-4387, 2026-10-25 04:21Z + +Whole files, sequential, with each corresponding script temporarily restored +from 78b69e1e6 and its implementation restored by EXIT trap afterwards: +- case2-unit.test.mjs: rc1, 81 tests, 48 pass, 33 fail, 0 skips; + TMPDIR=/mnt/storage/scratch/tmp/QD3vp5, nice=19, 77995.928687 ms. + All 47 old tests pass; new no-proxy byte equality passes. 32 new failures + encounter baseline unsupported --proxy usage rc4; dangling installed proxy + symlink case gets rc0 rather than refusal because baseline ignores it. +- case2-install.test.mjs: rc1, 28 tests, 27 pass, 1 fail, 0 skips; + TMPDIR=/mnt/storage/scratch/tmp/YAGfKJ, nice=19, 10016.247032 ms. + All old tests pass. New Next: guidance assertion fails because baseline + lacks add --proxy when the config has a proxy section. + +Every failure and cause is listed in red-results.txt; full plain-text +outputs in red-unit.log and red-install.log. Absolute node/test paths used. +Implementation restored, git diff --check clean. No old-test red, rerun, +assertion change, GREEN or mutant run. P2 check still pending row331. +Slot returned to Sage; GREEN and mutants await separate CLEAR. + +Sage sage-4390 accepts clean RED and explicitly authorizes committing and +pushing this candidate to rockerduck/row334 before GREEN. No force push. +GREEN and mutants remain held for a separate CLEAR after row331 lands; +then rebase onto landed P2 and check its missing-flag refusal code. diff --git a/agents/rockerduck/work/queue-334/imports.txt b/agents/rockerduck/work/queue-334/imports.txt new file mode 100644 index 000000000..78ef5a280 --- /dev/null +++ b/agents/rockerduck/work/queue-334/imports.txt @@ -0,0 +1,69 @@ +# Row334 whole-file run list (UNRUN; awaiting CLEAR) + +Entrypoints are the brief-owned tests, which spawn the changed shell scripts. +Their import graph is recorded below; no imported module is itself a test entrypoint. +case1-accept.test.mjs is excluded (mos-1612). + +packages/cli/tests/case2-unit.test.mjs -> packages/business/tests/helpers.mjs, packages/seat/src/sandbox.mjs, packages/cli/tests/helpers.mjs, packages/cli/tests/case-sudo-fixture.mjs +packages/business/tests/helpers.mjs -> (builtins/external only) +packages/seat/src/sandbox.mjs -> packages/business/src/vocabulary.mjs +packages/business/src/vocabulary.mjs -> (builtins/external only) +packages/cli/tests/helpers.mjs -> packages/bus/src/broker.mjs, packages/bus/src/store.mjs, packages/business/tests/helpers.mjs, packages/harness/tests/helpers.mjs, packages/plugins/tests/helpers.mjs, packages/cli/src/transport.mjs +packages/bus/src/broker.mjs -> packages/bus/src/address.mjs, packages/processing-control/src/state.mjs, packages/plugins/src/kinds.mjs, packages/tasks/src/requirements.mjs, packages/bus/src/landing.mjs, packages/business/src/vocabulary.mjs +packages/bus/src/address.mjs -> (builtins/external only) +packages/processing-control/src/state.mjs -> (builtins/external only) +packages/plugins/src/kinds.mjs -> (builtins/external only) +packages/tasks/src/requirements.mjs -> (builtins/external only) +packages/bus/src/landing.mjs -> (builtins/external only) +packages/bus/src/store.mjs -> (builtins/external only) +packages/harness/tests/helpers.mjs -> packages/business/src/index.mjs, packages/business/tests/helpers.mjs, packages/plugins/src/loader.mjs +packages/business/src/index.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/role.mjs, packages/business/src/vars.mjs, packages/business/src/credentials.mjs, packages/business/src/business.mjs, packages/business/src/access.mjs, packages/business/src/project.mjs, packages/business/src/resolve.mjs, packages/business/src/library-seats.mjs +packages/business/src/errors.mjs -> (builtins/external only) +packages/business/src/role.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs +packages/business/src/util.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs +packages/business/src/vars.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs, packages/plugins/src/kinds.mjs +packages/business/src/credentials.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs +packages/business/src/business.mjs -> packages/business/src/errors.mjs, packages/business/src/launch.mjs, packages/business/src/vars.mjs, packages/business/src/credentials.mjs, packages/business/src/role.mjs, packages/business/src/vocabulary.mjs, packages/plugins/src/kinds.mjs, packages/library/src/mapping.mjs, packages/business/src/util.mjs +packages/business/src/launch.mjs -> packages/business/src/util.mjs, packages/business/src/errors.mjs +packages/library/src/mapping.mjs -> packages/library/src/problems.mjs +packages/library/src/problems.mjs -> (builtins/external only) +packages/business/src/access.mjs -> packages/business/src/errors.mjs, packages/business/src/business.mjs, packages/business/src/util.mjs, packages/business/src/vocabulary.mjs +packages/business/src/project.mjs -> packages/business/src/errors.mjs, packages/business/src/vars.mjs, packages/business/src/util.mjs +packages/business/src/resolve.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/vars.mjs, packages/business/src/util.mjs, packages/business/src/project.mjs +packages/business/src/library-seats.mjs -> packages/business/src/errors.mjs, packages/business/src/business.mjs, packages/business/src/vocabulary.mjs +packages/plugins/src/loader.mjs -> packages/plugins/src/kinds.mjs +packages/plugins/tests/helpers.mjs -> (builtins/external only) +packages/cli/src/transport.mjs -> packages/cli/src/errors.mjs +packages/cli/src/errors.mjs -> (builtins/external only) +packages/cli/tests/case-sudo-fixture.mjs -> (builtins/external only) +packages/cli/tests/case2-install.test.mjs -> packages/business/tests/helpers.mjs, packages/library/tests/helpers.mjs, packages/library/src/index.mjs, packages/seat/src/checkout.mjs, packages/project/src/git.mjs, packages/cli/tests/helpers.mjs +packages/library/tests/helpers.mjs -> packages/library/src/mapping.mjs +packages/library/src/index.mjs -> packages/library/src/problems.mjs, packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/supporting.mjs, packages/library/src/links.mjs, packages/library/src/reader.mjs, packages/library/src/render.mjs, packages/library/src/survey.mjs, packages/library/src/mirror.mjs, packages/library/src/sync.mjs, packages/library/src/index-build.mjs, packages/library/src/query.mjs, packages/library/src/limits.mjs, packages/library/src/guard.mjs +packages/library/src/scope.mjs -> (builtins/external only) +packages/library/src/supporting.mjs -> packages/library/src/problems.mjs, packages/library/src/scope.mjs +packages/library/src/links.mjs -> (builtins/external only) +packages/library/src/reader.mjs -> packages/project/src/git.mjs, packages/library/src/scope.mjs, packages/library/src/links.mjs, packages/library/src/problems.mjs +packages/project/src/git.mjs -> packages/seat/src/checkout.mjs, packages/project/src/paths.mjs, packages/processing-control/src/effects.mjs +packages/seat/src/checkout.mjs -> packages/processing-control/src/effects.mjs +packages/processing-control/src/effects.mjs -> packages/processing-control/src/state.mjs, packages/processing-control/src/runtimes.mjs +packages/processing-control/src/runtimes.mjs -> packages/processing-control/src/state.mjs +packages/project/src/paths.mjs -> (builtins/external only) +packages/library/src/render.mjs -> (builtins/external only) +packages/library/src/survey.mjs -> packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/links.mjs, packages/library/src/reader.mjs, packages/library/src/problems.mjs +packages/library/src/mirror.mjs -> packages/project/src/paths.mjs, packages/project/src/git.mjs, packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/problems.mjs, packages/library/src/reader.mjs +packages/library/src/sync.mjs -> packages/seat/src/checkout.mjs, packages/project/src/git.mjs, packages/library/src/mapping.mjs, packages/library/src/problems.mjs, packages/library/src/reader.mjs, packages/library/src/mirror.mjs +packages/library/src/index-build.mjs -> packages/library/src/reader.mjs, packages/library/src/problems.mjs +packages/library/src/query.mjs -> packages/library/src/problems.mjs, packages/library/src/mapping.mjs, packages/library/src/index-build.mjs, packages/library/src/reader.mjs +packages/library/src/limits.mjs -> (builtins/external only) +packages/library/src/guard.mjs -> packages/project/src/git.mjs, packages/library/src/scope.mjs, packages/library/src/reader.mjs, packages/library/src/problems.mjs, packages/library/src/mirror.mjs, packages/library/src/limits.mjs, packages/library/src/reply-protocol.mjs +packages/library/src/reply-protocol.mjs -> (builtins/external only) + +Whole-file commands after CLEAR (one fresh shell-mktemp TMPDIR each; nice=19): +node --test packages/cli/tests/case2-unit.test.mjs +node --test packages/cli/tests/case2-install.test.mjs + +Before these: new row334 tests only on saved 78b69e1e6 scripts for RED, +then restored implementation. After GREEN: named mutants individually, +each with its directly relevant row334 test. No scripts/test-*.sh builder run planned. + +Includes multiline imports and export-from module edges: 53 local modules. diff --git a/agents/rockerduck/work/queue-334/red-install.log b/agents/rockerduck/work/queue-334/red-install.log new file mode 100644 index 000000000..e0978ab71 --- /dev/null +++ b/agents/rockerduck/work/queue-334/red-install.log @@ -0,0 +1,68 @@ +TMPDIR=/mnt/storage/scratch/tmp/YAGfKJ nice=19 +✔ the library install writes the business file, personas and slot dir, makes the copy and starts nothing (386.113555ms) +✔ a library re-run passes and leaves every file as it was (496.225906ms) +✔ a re-run refuses business-file-differs and leaves the file unchanged (376.395513ms) +✔ a re-run refuses persona-differs when an installed persona isn't the staged one, and writes nothing (398.216221ms) +✔ the factory install writes no library mapping, persona or slot dir (247.905208ms) +✔ the factory install refuses a library project and bus.tester off, before anything is written (105.176208ms) +✔ the library install refuses bus.tester on and a persona var in the input (104.503599ms) +✔ the install refuses root, a business id mismatch, another --home and a config dir with group bits (80.144703ms) +✔ the library install needs --personas (7.831929ms) +✔ a validate refusal removes the business file this run wrote (311.701322ms) +✔ N4: a validate refusal on a re-run leaves the matching business file in place, byte for byte (537.848604ms) +✔ a clean library host passes the precheck with no mirror yet (509.009214ms) +✔ the library precheck refuses a persona file at 0644 (506.697677ms) +✔ the library precheck refuses a persona whose digest isn't persona.sha256 (495.113108ms) +✔ the library precheck refuses a persona dir with group bits (481.900638ms) +✔ the library precheck refuses a business file at 0644 (462.626038ms) +✔ the library precheck refuses a changes.jsonl at 0644 (687.490332ms) +✔ the library precheck refuses a Discord binding (499.568905ms) +✔ --library-status refuses library-mirror-missing before the bus has made the mirror (377.717622ms) +✔ --library-status refuses library-never-synced on a fresh mirror (410.956236ms) +✔ --library-status names a recorded lastError before the null lastFetch it leaves (N3) (417.888767ms) +✔ --library-status prints each R-problem's path as an escaped JSON string, then the count, and passes (481.141014ms) +✔ --library-status takes no --profile (6.246241ms) +✔ Vikunja 614: install preserves the explicit notifier decision bytes and mode and creates none when absent (560.431267ms) +✔ row 322 F8: library personas install from the copy with no clone node_modules (183.399079ms) +✔ row 322 F9: importer refusal keeps the error line rather than the Node banner (118.731885ms) +✔ C2-21: library install supplies chief identity and books publish for its real read grant (330.48101ms) +✖ row334 install Next tells root to select proxy only when configured (302.965779ms) +ℹ tests 28 +ℹ suites 0 +ℹ pass 27 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 10016.247032 + +✖ failing tests: + +test at packages/cli/tests/case2-install.test.mjs:495:1 +✖ row334 install Next tells root to select proxy only when configured (302.965779ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /Next: root runs case2-unit.sh[^\n]+add --proxy when the config has a proxy section/. Input: + + 'case2-install: config /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/config.json\n' + + 'case2-install: copy /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.local/share/mosaic-stack/copies/cccccccccccccccccccccccccccccccccccccccc\n' + + 'case2-install: personas installed under /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/personas/acme\n' + + 'case2-install: business file /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/businesses/acme.json written\n' + + 'case2-install: slot dir /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/secrets/acme\n' + + 'case2-install: business acme validates\n' + + 'case2-install: done. Next: root runs case2-unit.sh --copy cccccccccccccccccccccccccccccccccccccccc --business acme (design 10 step 2c), then 2d and 3.\n' + + 'case2-install: Then Jason places the library token in /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/secrets/acme (step 4), and runs case2-precheck.sh --business acme --library-status (step 4a).\n' + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-install.test.mjs:498:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'case2-install: config /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/config.json\ncase2-install: copy /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.local/share/mosaic-stack/copies/cccccccccccccccccccccccccccccccccccccccc\ncase2-install: personas installed under /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/personas/acme\ncase2-install: business file /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/businesses/acme.json written\ncase2-install: slot dir /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/secrets/acme\ncase2-install: business acme validates\ncase2-install: done. Next: root runs case2-unit.sh --copy cccccccccccccccccccccccccccccccccccccccc --business acme (design 10 step 2c), then 2d and 3.\ncase2-install: Then Jason places the library token in /mnt/storage/scratch/tmp/YAGfKJ/case2-install-lXA9Qd/home/.config/mosaic-dev/secrets/acme (step 4), and runs case2-precheck.sh --business acme --library-status (step 4a).\n', + expected: /Next: root runs case2-unit.sh[^\n]+add --proxy when the config has a proxy section/, + operator: 'match', + diff: 'simple' + } diff --git a/agents/rockerduck/work/queue-334/red-results.txt b/agents/rockerduck/work/queue-334/red-results.txt new file mode 100644 index 000000000..179151086 --- /dev/null +++ b/agents/rockerduck/work/queue-334/red-results.txt @@ -0,0 +1,52 @@ +# RED results — sage-4387 (2026-10-25) + +Baseline scripts: 78b69e1e6. Current row334 tests. Whole files, sequential. +Both implementation scripts restored via EXIT traps after their run. +No GREEN or mutant run. No old-test failure. No assertion changed. + +case2-unit.test.mjs: exit 1; 81 tests, 48 pass, 33 fail, 0 skip. +47 existing tests plus new byte-identical no-proxy test pass. +TMPDIR=/mnt/storage/scratch/tmp/QD3vp5; nice=19; duration 77995.928687 ms. + +Every unit failure and its observed reason: +- row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses continuation by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses not-setting by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses RestrictNamespaces by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses PrivateUsers by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses SystemCallFilter by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses PermissionsStartOnly by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses EnvironmentFile by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses AmbientCapabilities by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses CapabilityBoundingSet by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses privileged by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses direct-binary by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses nnp by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses cwd by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses environment by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses install by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses user by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses group by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses ProtectSystem by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses ReadWritePaths by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses ProtectHome by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses PrivateTmp by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy refuses token by message before writing: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy template missing or symlink refuses: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 reinstall repins all three and refuses a proxy copy mismatch: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 installed proxy without --proxy refuses and preserves all bytes: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 dangling proxy symlink without flag refuses without deleting: baseline ignores installed proxy symlink without flag, returns 0 instead of refusal 1. +- row334 active proxy reports old copy and all three must restart together: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 failed mosaic-proxy.service start leaves later units unstarted: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 failed mosaic-bus@acme.service start leaves later units unstarted: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 installed proxy enforces hardening order and remaining common refusals: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. +- row334 proxy installed path rejects symlink and non-regular file: baseline does not parse --proxy: usage exit 4, before the proxy-specific assertion/setup can be reached. + +case2-install.test.mjs: exit 1; 28 tests, 27 pass, 1 fail, 0 skip. +TMPDIR=/mnt/storage/scratch/tmp/YAGfKJ; nice=19; duration 10016.247032 ms. +- row334 install Next tells root to select proxy only when configured: baseline Next: lacks add --proxy when the config has a proxy section. + +Commands used absolute /usr/bin/node --test and absolute test-file paths. +Full plain-text outputs: red-unit.log and red-install.log beside this file. +P2 refusal-code check remains pending row331. Slot returned to Sage. diff --git a/agents/rockerduck/work/queue-334/red-unit.log b/agents/rockerduck/work/queue-334/red-unit.log new file mode 100644 index 000000000..de2a7c3cc --- /dev/null +++ b/agents/rockerduck/work/queue-334/red-unit.log @@ -0,0 +1,873 @@ +TMPDIR=/mnt/storage/scratch/tmp/QD3vp5 nice=19 +✔ row253 factory socket uses actual config and target-uid query without widening hardening (351.144059ms) +✔ row253 installer refuses unsafe location and query facts before unit writes (3621.94316ms) +✔ row253 query timeout kills its process group and leaves no running child (7054.318085ms) +✔ row253 protected homes refuse before any filesystem access (9.291102ms) +✔ row253 C4 sleep query has exact inner reason and cleans all members (10796.380077ms) +✔ row253 C4 signals query has exact inner reason and cleans all members (10819.227773ms) +✔ row253 C4 member query has exact inner reason and cleans all members (10897.328548ms) +✔ row253 C4 overflow is output-limit in both sudo modes (554.12811ms) +✔ row253 C4 stalled supervisor uses the outer reason and explicit residual cleanup (14201.797743ms) +✔ row253 C4 inline supervisor is byte-identical in both host scripts (0.888234ms) +✔ row253 C4 cleanup budget starts after inventory pass one (46.615614ms) +✔ row253 query reaps its group even when a child closes stdout before the query returns (152.118314ms) +✔ row253 config parser is strict (11.560624ms) +✔ a clean library render writes both units 0644 with the fixed lines, and enables both then starts the bus then the Console (120.676804ms) +✔ PATH starts with the --node directory, for a node outside the default list and for /usr/bin/node (131.630623ms) +✔ a failed bus start refuses with the Console not started (123.177864ms) +✔ the script never links a unit file (0.18683ms) +✔ factory renders --pm once and one MOSAIC_CLAUDE_BIN line, and without them both tokens render empty (746.075081ms) +✔ a re-install over running units says they are still on the old copy and must restart together, never that it started them (494.63679ms) +✔ a re-install to another copy re-renders both units, and an edited installed unit refuses (1175.719345ms) +✔ a template with a namespace, user or system call restriction refuses (335.625113ms) +✔ the bus template's EnvironmentFile line must be there and point at the session env, and the Console template must have none (214.600182ms) +✔ a template holding an unknown token, PermissionsStartOnly or a privileged Exec prefix refuses (151.081813ms) +✔ a symlink at either unit path refuses (203.555513ms) +✔ a --node that is relative, not root-owned or under refuses (27.297759ms) +✔ a re-install with a different --node or different serve flags refuses (599.873393ms) +✔ an installed pair whose units name different copies refuses (328.321083ms) +✔ a copy id that is short, uppercase, holds / or .., or names no directory refuses (46.028703ms) +✔ library refuses a privileged-floor miss, a bad proof pair and every flag outside its set (344.833107ms) +✔ library refuses a proof file not owned by 's uid (18.013172ms) +✔ factory refuses duplicate socket, a missing --port or --business, and each proxy flag (209.757808ms) +✔ row253 factory refuses retired TCP and a value after the socket marker (59.218628ms) +✔ factory refuses a --claude that is relative, not root-owned or under , and a re-install with another --pm or --claude (1686.680735ms) +✔ the precheck passes on a good host and prints free memory, without the key (226.963557ms) +✔ the precheck refuses each failed host check (1765.731095ms) +✔ the precheck refuses a user missing from passwd, a business file that does not load, and a symlinked run root (927.260864ms) +✔ a bwrap that fails refuses and prints the sysctl and where bwrap is (200.731617ms) +✔ an unprivileged port floor at or below the Console's port refuses, and so does a missing Console unit (1055.360802ms) +✔ bus.tester: library refuses it on, factory needs it on, and factory refuses a library business (927.574539ms) +✔ the claude check runs only for a claude-code instance, and refuses a claude that appends or answers wrong (1694.074713ms) +✔ the claude check runs the bus unit's MOSAIC_CLAUDE_BIN over claude on PATH (498.707509ms) +✔ the session env file refuses when missing, open to others, a symlink, empty, or emptied by a later line (1155.959127ms) +✔ inside a session's sandbox a bind below 1024 fails with EACCES, and a bind on a free high port succeeds (106.466066ms) +✔ Vikunja 614 factory: scoped @anthropic-ai Claude path renders and passes installed read-back (1024.721235ms) +✔ Vikunja 614 factory: plain paths still refuse every named unsafe character (117.946806ms) +✔ Vikunja 614 precheck: explicit null and named notifier decisions pass (384.090317ms) +✔ Vikunja 614 precheck: notifier config refuses missing, public, malformed and extra-key decisions (1596.303308ms) +✔ row334 no-proxy renders stay byte-identical to the pre-row renderer (316.417263ms) +✖ row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order (6.436602ms) +✖ row334 proxy refuses continuation by message before writing (6.291734ms) +✖ row334 proxy refuses not-setting by message before writing (5.588449ms) +✖ row334 proxy refuses RestrictNamespaces by message before writing (5.71389ms) +✖ row334 proxy refuses PrivateUsers by message before writing (5.34285ms) +✖ row334 proxy refuses SystemCallFilter by message before writing (5.400994ms) +✖ row334 proxy refuses PermissionsStartOnly by message before writing (5.443023ms) +✖ row334 proxy refuses EnvironmentFile by message before writing (5.052075ms) +✖ row334 proxy refuses AmbientCapabilities by message before writing (5.027453ms) +✖ row334 proxy refuses CapabilityBoundingSet by message before writing (5.604853ms) +✖ row334 proxy refuses privileged by message before writing (5.176325ms) +✖ row334 proxy refuses direct-binary by message before writing (5.301058ms) +✖ row334 proxy refuses nnp by message before writing (4.978268ms) +✖ row334 proxy refuses cwd by message before writing (4.903056ms) +✖ row334 proxy refuses environment by message before writing (4.928207ms) +✖ row334 proxy refuses install by message before writing (4.935225ms) +✖ row334 proxy refuses user by message before writing (4.996881ms) +✖ row334 proxy refuses group by message before writing (4.740792ms) +✖ row334 proxy refuses ProtectSystem by message before writing (7.412574ms) +✖ row334 proxy refuses ReadWritePaths by message before writing (5.039647ms) +✖ row334 proxy refuses ProtectHome by message before writing (4.948113ms) +✖ row334 proxy refuses PrivateTmp by message before writing (5.049564ms) +✖ row334 proxy refuses token by message before writing (5.291145ms) +✖ row334 proxy template missing or symlink refuses (4.77612ms) +✖ row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status (5.907949ms) +✖ row334 reinstall repins all three and refuses a proxy copy mismatch (5.706372ms) +✖ row334 installed proxy without --proxy refuses and preserves all bytes (4.919106ms) +✖ row334 dangling proxy symlink without flag refuses without deleting (127.81539ms) +✖ row334 active proxy reports old copy and all three must restart together (5.181396ms) +✖ row334 failed mosaic-proxy.service start leaves later units unstarted (4.827066ms) +✖ row334 failed mosaic-bus@acme.service start leaves later units unstarted (4.558348ms) +✖ row334 installed proxy enforces hardening order and remaining common refusals (5.170683ms) +✖ row334 proxy installed path rejects symlink and non-regular file (4.685001ms) +ℹ tests 81 +ℹ suites 0 +ℹ pass 48 +ℹ fail 33 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 77995.928687 + +✖ failing tests: + +test at packages/cli/tests/case2-unit.test.mjs:966:1 +✖ row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order (6.436602ms) + AssertionError [ERR_ASSERTION]: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:969:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses continuation by message before writing (6.291734ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses not-setting by message before writing (5.588449ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses RestrictNamespaces by message before writing (5.71389ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses PrivateUsers by message before writing (5.34285ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses SystemCallFilter by message before writing (5.400994ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses PermissionsStartOnly by message before writing (5.443023ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses EnvironmentFile by message before writing (5.052075ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses AmbientCapabilities by message before writing (5.027453ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses CapabilityBoundingSet by message before writing (5.604853ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses privileged by message before writing (5.176325ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses direct-binary by message before writing (5.301058ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses nnp by message before writing (4.978268ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses cwd by message before writing (4.903056ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses environment by message before writing (4.928207ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses install by message before writing (4.935225ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses user by message before writing (4.996881ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses group by message before writing (4.740792ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses ProtectSystem by message before writing (7.412574ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses ReadWritePaths by message before writing (5.039647ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses ProtectHome by message before writing (4.948113ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses PrivateTmp by message before writing (5.049564ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1004:52 +✖ row334 proxy refuses token by message before writing (5.291145ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1007:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1012:1 +✖ row334 proxy template missing or symlink refuses (4.77612ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1014:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1019:1 +✖ row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status (5.907949ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1021:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1044:1 +✖ row334 reinstall repins all three and refuses a proxy copy mismatch (5.706372ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1046:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1055:1 +✖ row334 installed proxy without --proxy refuses and preserves all bytes (4.919106ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1057:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1065:1 +✖ row334 dangling proxy symlink without flag refuses without deleting (127.81539ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 0: case2-unit: wrote /mnt/storage/scratch/tmp/QD3vp5/case2-unit-h4V4Zn/units/mosaic-bus@.service and /mnt/storage/scratch/tmp/QD3vp5/case2-unit-h4V4Zn/units/mosaic-webui.service from copy aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; enabled and started mosaic-bus@acme.service, then mosaic-webui.service + + + 0 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1068:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 0, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1072:1 +✖ row334 active proxy reports old copy and all three must restart together (5.181396ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1074:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1080:73 +✖ row334 failed mosaic-proxy.service start leaves later units unstarted (4.827066ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1082:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1080:73 +✖ row334 failed mosaic-bus@acme.service start leaves later units unstarted (4.558348ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1082:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1088:1 +✖ row334 installed proxy enforces hardening order and remaining common refusals (5.170683ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + 4 !== 0 + + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1090:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 4, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } + +test at packages/cli/tests/case2-unit.test.mjs:1103:1 +✖ row334 proxy installed path rejects symlink and non-regular file (4.685001ms) + AssertionError [ERR_ASSERTION]: expected a refusal, got 4: usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS + + + 4 !== 1 + + at refuses (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:292:10) + at TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:1106:3) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 4, + expected: 1, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/docs/SESSIONS.md b/docs/SESSIONS.md index 70d32e024..4961089a1 100644 --- a/docs/SESSIONS.md +++ b/docs/SESSIONS.md @@ -1879,3 +1879,6 @@ are never rewritten or removed; corrections are new entries. 2026-10-26 | Sage | mos1884/#662 scope after330/331landing | ReadQ222/Q261/Q263 and659/660/662; posted bounded human-only factory settings/triage/defaulttwo-roundmandate/trackedno-exemptionflake scope with10acceptance criteria, task662comment1338 exactwholebody/author13GETverified. No implementation/review/gate launched.660c1335notready(review/merge, noVM); gatefacts1329/1334 retained; target integration/fullrunner confirmation follows readiness, no localfallback. Landedproduct/evidence unchanged;657/658backlog. 2026-10-26 | Sage | Mos1909/1915/1917 real postlanding reviews | Boyd/Dewey/Filbert/Gladstone real authored candidate52ba verdictfiles independently byte/hash-verified, allAPPROVE scoped; Dewey656broaderPARTIAL retained. Formal330R1/331R4 requests failedpre-send/no comments or approvals; no borrowed/copied/mintedkeys. LegacyhelperGETname jason.woltje is NOT ownJarvis, ownslotabsent; rows tracking-open/#436, files cited via normalqueue. NewFilbertNEW-330-01 filedtask665 exactreadback, notlandingreopen/gate. Repair646-648/652-656 remainOPEN untilactualcomments;1917 conditionalbacklog routing retained. #662scope1338posted;660PR405REVISE/notready. Product1968inputs unchanged; no source/helper/test/gate edits/runs; peerjournal prefixes preserved. +2026-10-25 — rockerduck — row334 (#1832), Case 2 proxy system unit — design/read phase; tests held for Sage CLEAR; queue start lock diagnosed. +2026-10-25 — rockerduck — row334 (#1832), Case 2 proxy system unit — queue start rev4079; tests then implementation written, design accepted by Sage; verification held for CLEAR, P2 refusal-code check pending row331. +2026-10-25 — rockerduck — row334 RED-only slot sage-4387 — both whole files against pre-change scripts: 74 older tests pass, 34 new expected failures; implementations restored, slot returned; GREEN/mutants held. diff --git a/packages/cli/tests/case2-install.test.mjs b/packages/cli/tests/case2-install.test.mjs index 7574856b0..41c823557 100644 --- a/packages/cli/tests/case2-install.test.mjs +++ b/packages/cli/tests/case2-install.test.mjs @@ -490,3 +490,10 @@ test('C2-21: library install supplies chief identity and books publish for its r assert.ok(doc.roles.chief.identity?.gitea?.user); assert.notEqual(doc.roles.chief.identity?.gitea?.user, 'writer'); }); + + +test('row334 install Next tells root to select proxy only when configured', t => { + const x = world(t), r = install(x); + assert.equal(r.code, 0, r.out); + assert.match(r.out, /Next: root runs case2-unit.sh[^\n]+add --proxy when the config has a proxy section/); +}); diff --git a/packages/cli/tests/case2-unit.test.mjs b/packages/cli/tests/case2-unit.test.mjs index ea234e3ad..3037e0986 100644 --- a/packages/cli/tests/case2-unit.test.mjs +++ b/packages/cli/tests/case2-unit.test.mjs @@ -7,10 +7,10 @@ import { test } from "node:test"; import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; import { createServer } from "node:net"; -import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs"; +import { chmodSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -import { businessDoc, writeJson } from "../../business/tests/helpers.mjs"; +import { businessDoc, systemConfig, writeJson } from "../../business/tests/helpers.mjs"; import { binds, prepareRun, sandboxArgv, sandboxProblem } from "../../seat/src/sandbox.mjs"; import { tmp } from "./helpers.mjs"; import { CASE_SUDO_SESSION, recordedLivePids, killRecordedPids, fixtureGuard, cleanupFixture, pollFixtureGone, blockingQuerySource } from "./case-sudo-fixture.mjs"; @@ -940,3 +940,171 @@ test("Vikunja 614 precheck: notifier config refuses missing, public, malformed a assert.match(r.out, /REFUSED notifier config:/, `${fault}: ${r.out}`); } }); + + +// Row334: render only into the scratch hub; fake systemctl never touches the host. +const PROXY_TEMPLATE = join(REPO, 'packages/cli/systemd/mosaic-proxy.service.in'); +const proxyFile = h => join(h.units, 'mosaic-proxy.service'); +const proxyUnit = (h, options = {}) => unit(h, { ...options, extra: ['--proxy', ...(options.extra ?? [])] }); + +test('row334 no-proxy renders stay byte-identical to the pre-row renderer', t => { + const h = hub(t); + // Immutable committed baseline, executed only with the same scratch seams. + const baseline = spawnSync('git', ['show', '78b69e1e6:scripts/case2-unit.sh'], { cwd: REPO, encoding: 'utf8' }); + assert.equal(baseline.status, 0, baseline.stderr); + const old = script(join(h.root, 'baseline/scripts/case2-unit.sh'), baseline.stdout); + const args = ['--user', 'mosaic', '--home', h.home, '--business', 'acme', '--copy', COPY_A, '--node', USR_NODE, '--', ...libraryFlags(h)]; + const r = spawnSync(old, args, { encoding: 'utf8', env: { PATH: `${h.bin}:${process.env.PATH}`, CASE2_UNIT_DIR: h.units, + CASE2_SYSTEMCTL: join(h.bin, 'systemctl'), CASE2_GETENT: join(h.bin, 'getent'), CASE2_BUS_TEMPLATE: BUS_TEMPLATE, CASE2_WEBUI_TEMPLATE: WEBUI_TEMPLATE } }); + assert.equal(r.status, 0, r.stderr); + const before = [read(busFile(h)), read(webuiFile(h))]; + assert.equal(unit(h).code, 0); + assert.deepEqual([read(busFile(h)), read(webuiFile(h))], before); + assert.equal(existsSync(proxyFile(h)), false); +}); + +test('row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order', t => { + const h = hub(t); + const r = proxyUnit(h, { profile: 'factory', flags: ['--port', '443', '--business', 'acme'], extra: ['--claude', TRUE_BIN] }); + assert.equal(r.code, 0, r.err); + const proxy = read(proxyFile(h)); + const expected = read(PROXY_TEMPLATE).replaceAll('@REPO@', copyDir(h)).replaceAll('@PATH@', '/usr/bin:/usr/local/bin:/bin') + .replaceAll('@NODE@', USR_NODE).replace(/^@CONFIG_ENV@\n/m, '').replace('WantedBy=default.target', 'WantedBy=multi-user.target') + .replace('TimeoutStopSec=60', `TimeoutStopSec=60\nUser=mosaic\nGroup=mosaic\n${HARDENING(h).join('\n')}`); + assert.equal(proxy, expected); + assert.equal(statSync(proxyFile(h)).mode & 0o777, 0o644); + assert.match(read(busFile(h)), /Description=[^\n]+\nWants=mosaic-proxy.service\nAfter=mosaic-proxy.service\n/); + assert.deepEqual(lines(proxy, 'ExecStart'), [`${USR_NODE} ${copyDir(h)}/packages/model-proxy/src/run.mjs`]); + assert.doesNotMatch(proxy, /EnvironmentFile=|Capabilities=|CapabilityBoundingSet=|MOSAIC_CLAUDE_BIN/); + assert.doesNotMatch(read(webuiFile(h)), /Wants=|After=/); + assert.deepEqual(read(h.log).trim().split('\n'), [ + 'is-active --quiet mosaic-proxy.service', 'is-active --quiet mosaic-bus@acme.service', 'is-active --quiet mosaic-webui.service', + 'daemon-reload', 'enable mosaic-proxy.service mosaic-bus@acme.service mosaic-webui.service', + 'start mosaic-proxy.service', 'start mosaic-bus@acme.service', 'start mosaic-webui.service', + ]); +}); + +const proxyRefusals = [ + ['continuation', s => s.replace('Type=simple', 'Type=simple' + String.fromCharCode(92)), /a line continues onto the next/], + ['not-setting', s => s.replace('Type=simple', 'not a setting'), /neither a section/], + ...['RestrictNamespaces', 'PrivateUsers', 'SystemCallFilter', 'PermissionsStartOnly', 'EnvironmentFile', 'AmbientCapabilities', 'CapabilityBoundingSet'].map(k => + [k, s => s.replace('Type=simple', `Type=simple\n${k}=yes`), new RegExp(`refusing ${k}=`)]), + ['privileged', s => s.replace('ExecStart=', 'ExecStart=+'), /Exec line that runs with full privileges/], + ['direct-binary', s => s.replace('packages/model-proxy/src/run.mjs', 'opt/cli-proxy-api'), /ExecStart= must be exactly once/], + ['nnp', s => s.replace('NoNewPrivileges=yes', 'NoNewPrivileges=no'), /NoNewPrivileges= must be exactly once/], + ['cwd', s => s.replace('WorkingDirectory=@REPO@', 'WorkingDirectory=/elsewhere'), /WorkingDirectory= must be exactly once/], + ['environment', s => s.replace('Environment=PATH=@PATH@', 'Environment=PATH=/elsewhere'), /Environment= lines must be exactly/], + ['install', s => s.replace('WantedBy=default.target', 'WantedBy=other.target'), /WantedBy= must be exactly once/], + ['user', s => s.replace('Type=simple', 'Type=simple\nUser=other'), /User= must be exactly once/], + ['group', s => s.replace('Type=simple', 'Type=simple\nGroup=other'), /Group= must be exactly once/], + ...['ProtectSystem', 'ReadWritePaths', 'ProtectHome', 'PrivateTmp'].map(k => + [k, s => s.replace('Type=simple', `Type=simple\n${k}=other`), new RegExp(`${k}= must be exactly once`)]), + ['token', s => s.replace('Type=simple', 'Type=simple\nX-Note=@UNKNOWN@'), /a token is left after the render/], +]; +for (const [name, edit, message] of proxyRefusals) test(`row334 proxy refuses ${name} by message before writing`, t => { + const h = hub(t); + const file = template(h, PROXY_TEMPLATE, `${name}.in`, edit); + refuses(proxyUnit(h, { env: { CASE2_PROXY_TEMPLATE: file } }), message); + assert.deepEqual(readdirSync(h.units), []); + assert.equal(existsSync(h.log), false); +}); + +test('row334 proxy template missing or symlink refuses', t => { + const h = hub(t), missing = join(h.root, 'missing.in'); + refuses(proxyUnit(h, { env: { CASE2_PROXY_TEMPLATE: missing } }), /template missing or not a regular file/); + symlinkSync(PROXY_TEMPLATE, missing); + refuses(proxyUnit(h, { env: { CASE2_PROXY_TEMPLATE: missing } }), /template missing or not a regular file/); +}); + +test('row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status', t => { + const h = hub(t); + assert.equal(proxyUnit(h).code, 0); + const copy = copyDir(h); + cpSync(join(REPO, 'packages/model-proxy'), join(copy, 'packages/model-proxy'), { recursive: true }); + cpSync(join(REPO, 'scripts/mosaic-config.mjs'), join(copy, 'scripts/mosaic-config.mjs')); + const config = systemConfig(join(h.root, 'runner')); + const doc = JSON.parse(read(config)); + mkdirSync(doc.dataRoot, { recursive: true, mode: 0o700 }); + const pin = JSON.parse(read(join(REPO, 'packages/model-proxy/PIN'))); + const binary = join(doc.dataRoot, 'opt/cliproxyapi', pin.version, 'cli-proxy-api'); + script(binary, `echo unexpected-spawn > '${h.root}/spawned'`); + writeJson(join(dirname(config), 'proxy.json'), { port: 18541, binary }); + const argv = lines(read(proxyFile(h)), 'ExecStart')[0].split(' '); + const run = () => spawnSync(argv[0], argv.slice(1), { encoding: 'utf8', env: { PATH: '/usr/bin:/bin', HOME: h.home, MOSAIC_CONFIG: config } }); + const bad = run(); + assert.equal(bad.status, 3, bad.stderr); + assert.equal(bad.stderr, 'proxy-install-invalid\n'); + assert.equal(existsSync(join(h.root, 'spawned')), false); + rmSync(join(dirname(config), 'proxy.json')); + const absent = run(); + assert.equal(absent.status, 3, absent.stderr); + assert.equal(absent.stderr, 'proxy-not-configured\n'); +}); + +test('row334 reinstall repins all three and refuses a proxy copy mismatch', t => { + const h = hub(t); + assert.equal(proxyUnit(h).code, 0); + assert.equal(proxyUnit(h, { copy: COPY_B }).code, 0); + for (const file of [proxyFile(h), busFile(h), webuiFile(h)]) assert.match(read(file), new RegExp(copyDir(h, COPY_B))); + writeFileSync(proxyFile(h), read(proxyFile(h)).replaceAll(copyDir(h, COPY_B), copyDir(h))); + const before = [proxyFile(h), busFile(h), webuiFile(h)].map(read); + refuses(proxyUnit(h), /installed units name different copies/); + assert.deepEqual([proxyFile(h), busFile(h), webuiFile(h)].map(read), before); +}); + +test('row334 installed proxy without --proxy refuses and preserves all bytes', t => { + const h = hub(t); + assert.equal(proxyUnit(h).code, 0); + const files = [proxyFile(h), busFile(h), webuiFile(h)], before = files.map(read); + writeFileSync(h.log, ''); + refuses(unit(h), /installed mosaic-proxy.service requires --proxy/); + assert.deepEqual(files.map(read), before); + assert.equal(read(h.log), ''); +}); + +test('row334 dangling proxy symlink without flag refuses without deleting', t => { + const h = hub(t); + symlinkSync(join(h.root, 'absent'), proxyFile(h)); + refuses(unit(h), /installed mosaic-proxy.service requires --proxy/); + assert.equal(readdirSync(h.units).includes('mosaic-proxy.service'), true); +}); + +test('row334 active proxy reports old copy and all three must restart together', t => { + const h = hub(t); + assert.equal(proxyUnit(h).code, 0); + const r = proxyUnit(h, { copy: COPY_B, env: { CASE2_TEST_ACTIVE: 'mosaic-proxy.service mosaic-bus@acme.service mosaic-webui.service' } }); + assert.equal(r.code, 0, r.err); + assert.match(r.out, /mosaic-proxy.service was already running/); + assert.match(r.out, /restart mosaic-proxy.service, mosaic-bus@acme.service and mosaic-webui.service together/); +}); +for (const name of ['mosaic-proxy.service', 'mosaic-bus@acme.service']) test(`row334 failed ${name} start leaves later units unstarted`, t => { + const h = hub(t); + refuses(proxyUnit(h, { env: { CASE2_TEST_FAIL: `start ${name}` } }), /systemctl start .* failed/); + assert.doesNotMatch(read(h.log), /start mosaic-webui.service/); + if (name === 'mosaic-proxy.service') assert.doesNotMatch(read(h.log), /start mosaic-bus@acme.service/); +}); + + +test('row334 installed proxy enforces hardening order and remaining common refusals', t => { + const h = hub(t); + assert.equal(proxyUnit(h).code, 0); + const original = read(proxyFile(h)); + for (const [edit, message] of [ + [s => s.replace('ProtectSystem=strict\nReadWritePaths=' + h.home, 'ReadWritePaths=' + h.home + '\nProtectSystem=strict'), /hardening lines must be in the order/], + [s => s.replace('WorkingDirectory=' + copyDir(h), 'WorkingDirectory=%h'), /names no copy/], + [s => s.replace('Type=simple', 'Type=simple\nX-Note=%h'), /%h is left; a system unit/], + [s => s.replace('RestartSec=15', 'RestartSec=16'), /differs from the render in more than the copy id/], + ]) { + writeFileSync(proxyFile(h), edit(original)); + refuses(proxyUnit(h), message); + } +}); + +test('row334 proxy installed path rejects symlink and non-regular file', t => { + const h = hub(t); + symlinkSync(join(h.root, 'absent'), proxyFile(h)); + refuses(proxyUnit(h), /is a symlink/); + rmSync(proxyFile(h)); + mkdirSync(proxyFile(h)); + refuses(proxyUnit(h), /is not a regular file/); +}); diff --git a/scripts/case2-install.sh b/scripts/case2-install.sh index 4972854ca..7968bea06 100755 --- a/scripts/case2-install.sh +++ b/scripts/case2-install.sh @@ -228,7 +228,7 @@ fi say "business $BUSINESS validates" # 8. What comes next. Root's steps run from root's own checkout. -say "done. Next: root runs case2-unit.sh --copy $COMMIT --business $BUSINESS (design 10 step 2c), then 2d and 3." +say "done. Next: root runs case2-unit.sh --copy $COMMIT --business $BUSINESS (add --proxy when the config has a proxy section; design 10 step 2c), then 2d and 3." if [ "$PROFILE" = library ]; then say "Then Jason places the library token in $SLOT (step 4), and runs case2-precheck.sh --business $BUSINESS --library-status (step 4a)." fi diff --git a/scripts/case2-unit.sh b/scripts/case2-unit.sh index 2361e0bd0..bf5097abb 100755 --- a/scripts/case2-unit.sh +++ b/scripts/case2-unit.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Case 2 row C2-13a (design 9.3, 10 step 2c): render and install the two -# system units a hub runs as, mosaic-bus@.service (enabled as +# system units a hub runs as (plus P1's proxy with --proxy), mosaic-bus@.service (enabled as # mosaic-bus@.service) and mosaic-webui.service, from the existing # templates, which it doesn't change. # # case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH -# [--profile factory|library] [--pm] [--claude PATH] +# [--profile factory|library] [--proxy] [--pm] [--claude PATH] # -- SERVE FLAGS # # Root runs it from a root-owned checkout of the reviewed commit outside @@ -31,8 +31,8 @@ # --pm and --claude. # # On a re-install the installed units must equal the render in everything -# but the copy id, and both must name one copy, so a re-pin or rollback -# re-renders the pair together. A unit that was already running stays on its +# but the copy id, and all selected units must name one copy, so a re-pin or rollback +# re-renders them together. A unit that was already running stays on its # old copy, since `systemctl start` leaves it alone; the script says so and # that the bus and Console must restart together, and restarts nothing. # @@ -41,6 +41,7 @@ # the root and root-owned checks apply only there # CASE2_SYSTEMCTL the systemctl command, default systemctl # CASE2_GETENT the getent command, default getent +# CASE2_PROXY_TEMPLATE default packages/cli/systemd/mosaic-proxy.service.in # CASE2_BUS_TEMPLATE default packages/cli/systemd/mosaic-bus.service.in # CASE2_WEBUI_TEMPLATE default packages/webui/systemd/mosaic-webui.service.in # @@ -53,10 +54,12 @@ SYSTEMCTL="${CASE2_SYSTEMCTL:-systemctl}" GETENT="${CASE2_GETENT:-getent}" BUS_TEMPLATE="${CASE2_BUS_TEMPLATE:-$REPO/packages/cli/systemd/mosaic-bus.service.in}" WEBUI_TEMPLATE="${CASE2_WEBUI_TEMPLATE:-$REPO/packages/webui/systemd/mosaic-webui.service.in}" +PROXY_TEMPLATE="${CASE2_PROXY_TEMPLATE:-$REPO/packages/cli/systemd/mosaic-proxy.service.in}" +PROXY_UNIT=mosaic-proxy.service BUS_UNIT=mosaic-bus@.service WEBUI_UNIT=mosaic-webui.service -usage() { echo 'usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--pm] [--claude PATH] -- SERVE FLAGS' >&2; exit 4; } +usage() { echo 'usage: case2-unit.sh --user NAME --home DIR --business ID --copy ID --node PATH [--profile factory|library] [--proxy] [--pm] [--claude PATH] -- SERVE FLAGS' >&2; exit 4; } die() { echo "case2-unit: $*" >&2; exit 1; } # A value the unit carries as itself: no space, %, $, quote, backslash, & or |. plain() { case "$1" in *[!A-Za-z0-9/._+@-]*) return 1 ;; esac; } @@ -67,7 +70,7 @@ abs_plain() { [ "$1" = / ] || [ "${1%/}" = "$1" ] || die "$2 must not end in /: $1" } -PROFILE=library USER_NAME='' HOME_DIR='' BUSINESS='' COPY_ID='' NODE='' PM=0 CLAUDE='' CLAUDE_SET=0 +PROFILE=library USER_NAME='' HOME_DIR='' BUSINESS='' COPY_ID='' NODE='' PROXY=0 PM=0 CLAUDE='' CLAUDE_SET=0 while [ $# -gt 0 ]; do case "$1" in --profile|--user|--home|--business|--copy|--node|--claude) @@ -78,6 +81,7 @@ while [ $# -gt 0 ]; do --claude) CLAUDE="$2"; CLAUDE_SET=1 ;; esac shift 2 ;; + --proxy) PROXY=1; shift ;; --pm) PM=1; shift ;; --) shift; break ;; *) usage ;; @@ -150,6 +154,7 @@ fi # The checkout the templates come from, when installing for real. if [ "$UNIT_DIR" = "$DEFAULT_UNIT_DIR" ]; then case "$REPO/" in "$HOME_DIR"/*) die "run this from a root-owned checkout outside $HOME_DIR, not $REPO" ;; esac + [ "$PROXY" = 0 ] || root_only "$PROXY_TEMPLATE" 'proxy template' root_only "$BUS_TEMPLATE" 'bus template' root_only "$WEBUI_TEMPLATE" 'Console template' fi @@ -449,7 +454,10 @@ render() { fi if printf '%s\n' "$text" | grep -q '%h'; then die "$template: %h is left after the render"; fi local add="User=$USER_NAME\nGroup=$GROUP\n${HARDENING//$'\n'/\\n}\n" - [ "$kind" = bus ] || add="$add${CAPS//$'\n'/\\n}\n" + [ "$kind" != webui ] || add="$add${CAPS//$'\n'/\\n}\n" + if [ "$kind" = bus ] && [ "$PROXY" = 1 ]; then + text="$(printf '%s\n' "$text" | sed "/^Description=/a Wants=$PROXY_UNIT\\nAfter=$PROXY_UNIT")" + fi # The added lines go at the end of [Service], before its trailing blank # lines. In [Install], WantedBy=multi-user.target replaces # WantedBy=default.target in both units, so both start at boot (Q189). @@ -517,7 +525,7 @@ check_unit() { one WorkingDirectory "$copy" # Environment= lines: PATH, and MOSAIC_CLAUDE_BIN only with --claude. local envs want_envs="[Service] PATH=$UNIT_PATH" - [ "$kind" = webui ] || [ -z "$CLAUDE_ENV" ] || want_envs="$want_envs + [ "$kind" != bus ] || [ -z "$CLAUDE_ENV" ] || want_envs="$want_envs [Service] MOSAIC_CLAUDE_BIN=$CLAUDE" envs="$(printf '%s\n' "$s" | awk -F'\t' '$2 == "Environment" { print $1 "\t" $3 }')" [ "$envs" = "$want_envs" ] || die "$what: the Environment= lines must be exactly: $(printf '%s' "$want_envs" | cut -f2 | tr '\n' ' ')" @@ -537,6 +545,11 @@ check_unit() { one EnvironmentFile "$ENV_FILE" none AmbientCapabilities none CapabilityBoundingSet + elif [ "$kind" = proxy ]; then + one ExecStart "$NODE $copy/packages/model-proxy/src/run.mjs" + none EnvironmentFile + none AmbientCapabilities + none CapabilityBoundingSet else one ExecStart "$NODE $copy/packages/webui/src/cli.mjs serve $FLAGS" none EnvironmentFile @@ -554,7 +567,16 @@ check_unit webui "$WEBUI_TEXT" "rendered $WEBUI_UNIT" "$COPY" # copy, and each equals the render once its copy id is the new one. [ -d "$UNIT_DIR" ] && [ ! -L "$UNIT_DIR" ] || die "no unit directory $UNIT_DIR" installed_ids='' -for pair in "bus:$BUS_UNIT:BUS_TEXT" "webui:$WEBUI_UNIT:WEBUI_TEXT"; do +PAIRS=("bus:$BUS_UNIT:BUS_TEXT" "webui:$WEBUI_UNIT:WEBUI_TEXT") +if [ "$PROXY" = 1 ]; then + PROXY_TEXT="$(render proxy "$PROXY_TEMPLATE")" || exit 1 + check_unit proxy "$PROXY_TEXT" "rendered $PROXY_UNIT" "$COPY" + PAIRS=("proxy:$PROXY_UNIT:PROXY_TEXT" "${PAIRS[@]}") +else + [ ! -e "$UNIT_DIR/$PROXY_UNIT" ] && [ ! -L "$UNIT_DIR/$PROXY_UNIT" ] \ + || die "installed $PROXY_UNIT requires --proxy; nothing was changed" +fi +for pair in "${PAIRS[@]}"; do IFS=: read -r kind name var <<<"$pair" path="$UNIT_DIR/$name" [ ! -L "$path" ] || die "refusing: $path is a symlink" @@ -569,13 +591,17 @@ for pair in "bus:$BUS_UNIT:BUS_TEXT" "webui:$WEBUI_UNIT:WEBUI_TEXT"; do installed_ids="$installed_ids $old" done read -r -a ids <<<"$installed_ids" -[ "${#ids[@]}" -lt 2 ] || [ "${ids[0]}" = "${ids[1]}" ] || die "the installed units name different copies, ${ids[0]} and ${ids[1]}" +for old in "${ids[@]}"; do + [ "$old" = "${ids[0]}" ] || die "the installed units name different copies, ${ids[0]} and $old" +done # `systemctl start` leaves a running unit on the copy it started from, so # note which units run before the write (row 195 owns the restart). BUS_NAME="mosaic-bus@$BUSINESS.service" +NAMES=("$BUS_NAME" "$WEBUI_UNIT") +[ "$PROXY" = 0 ] || NAMES=("$PROXY_UNIT" "${NAMES[@]}") running='' -for name in "$BUS_NAME" "$WEBUI_UNIT"; do +for name in "${NAMES[@]}"; do if "$SYSTEMCTL" is-active --quiet "$name"; then running="$running $name"; fi done @@ -588,23 +614,40 @@ write_unit() { [ "$(id -u)" != 0 ] || chown root:root "$tmp" mv -fT -- "$tmp" "$UNIT_DIR/$name" } -write_unit "$BUS_UNIT" "$BUS_TEXT" -write_unit "$WEBUI_UNIT" "$WEBUI_TEXT" -# Enable both, then start the bus, then the Console (design 10 step 2c). -# serve calls the bus per request, so the units carry no After= or Wants=. +for pair in "${PAIRS[@]}"; do + IFS=: read -r kind name var <<<"$pair" + write_unit "$name" "${!var}" +done +# Enable all selected units before starting proxy (if selected), bus, Console. +# Only the bus depends on the proxy; the Console calls the bus per request. "$SYSTEMCTL" daemon-reload || die "systemctl daemon-reload failed; the units are written, nothing is enabled or started" -"$SYSTEMCTL" enable "$BUS_NAME" "$WEBUI_UNIT" || die "systemctl enable $BUS_NAME $WEBUI_UNIT failed; nothing is started" +"$SYSTEMCTL" enable "${NAMES[@]}" || die "systemctl enable ${NAMES[*]} failed; nothing is started" +if [ "$PROXY" = 1 ]; then + "$SYSTEMCTL" start "$PROXY_UNIT" || die "systemctl start $PROXY_UNIT failed; the bus and Console are not started" +fi "$SYSTEMCTL" start "$BUS_NAME" || die "systemctl start $BUS_NAME failed; the Console is not started" "$SYSTEMCTL" start "$WEBUI_UNIT" || die "systemctl start $WEBUI_UNIT failed; the bus is running" -if [ -z "$running" ]; then - echo "case2-unit: wrote $UNIT_DIR/$BUS_UNIT and $UNIT_DIR/$WEBUI_UNIT from copy $COPY_ID; enabled and started $BUS_NAME, then $WEBUI_UNIT" - exit 0 +if [ "$PROXY" = 1 ]; then + echo "case2-unit: wrote $UNIT_DIR/$PROXY_UNIT, $UNIT_DIR/$BUS_UNIT and $UNIT_DIR/$WEBUI_UNIT from copy $COPY_ID and enabled all three" + if [ -z "$running" ]; then + echo "case2-unit: enabled and started $PROXY_UNIT, then $BUS_NAME, then $WEBUI_UNIT" + exit 0 + fi +else + if [ -z "$running" ]; then + echo "case2-unit: wrote $UNIT_DIR/$BUS_UNIT and $UNIT_DIR/$WEBUI_UNIT from copy $COPY_ID; enabled and started $BUS_NAME, then $WEBUI_UNIT" + exit 0 + fi + echo "case2-unit: wrote $UNIT_DIR/$BUS_UNIT and $UNIT_DIR/$WEBUI_UNIT from copy $COPY_ID and enabled both" fi -echo "case2-unit: wrote $UNIT_DIR/$BUS_UNIT and $UNIT_DIR/$WEBUI_UNIT from copy $COPY_ID and enabled both" -for name in "$BUS_NAME" "$WEBUI_UNIT"; do +for name in "${NAMES[@]}"; do case " $running " in *" $name "*) echo "case2-unit: $name was already running, so it is still on ${ids[0]:+copy }${ids[0]:-the copy it started from}, not copy $COPY_ID" ;; *) echo "case2-unit: started $name on copy $COPY_ID" ;; esac done -echo "case2-unit: restart $BUS_NAME and $WEBUI_UNIT together to put both on copy $COPY_ID; until then they may run different copies" +if [ "$PROXY" = 1 ]; then + echo "case2-unit: restart $PROXY_UNIT, $BUS_NAME and $WEBUI_UNIT together to put all three on copy $COPY_ID; until then they may run different copies" +else + echo "case2-unit: restart $BUS_NAME and $WEBUI_UNIT together to put both on copy $COPY_ID; until then they may run different copies" +fi From 4c49919e9b01f3e1479f4573b120ea03192082fe Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Mon, 26 Oct 2026 17:43:07 -0500 Subject: [PATCH 2/2] row334: record integrated GREEN and killed mutant evidence --- BUILD-LOG.md | 2 + agents/rockerduck/work/queue-334/BUILD.md | 61 +++ agents/rockerduck/work/queue-334/cleanup.txt | 14 + .../work/queue-334/green-evidence.sha256 | 14 + .../work/queue-334/green-imports.txt | 57 ++ .../work/queue-334/green-install.tap | 179 +++++++ .../work/queue-334/green-source.sha256 | 6 + .../rockerduck/work/queue-334/green-unit.tap | 497 ++++++++++++++++++ .../work/queue-334/mutant-after-source.sha256 | 1 + .../work/queue-334/mutant-after.diff | 13 + .../work/queue-334/mutant-after.tap | 133 +++++ .../work/queue-334/mutant-exec-source.sha256 | 1 + .../work/queue-334/mutant-exec.diff | 13 + .../rockerduck/work/queue-334/mutant-exec.tap | 36 ++ .../queue-334/remaining-test-processes.txt | 1 + .../rockerduck/work/queue-334/restoration.txt | 6 + agents/rockerduck/work/queue-334/restored.tap | 23 + docs/SESSIONS.md | 1 + 18 files changed, 1058 insertions(+) create mode 100644 agents/rockerduck/work/queue-334/cleanup.txt create mode 100644 agents/rockerduck/work/queue-334/green-evidence.sha256 create mode 100644 agents/rockerduck/work/queue-334/green-imports.txt create mode 100644 agents/rockerduck/work/queue-334/green-install.tap create mode 100644 agents/rockerduck/work/queue-334/green-source.sha256 create mode 100644 agents/rockerduck/work/queue-334/green-unit.tap create mode 100644 agents/rockerduck/work/queue-334/mutant-after-source.sha256 create mode 100644 agents/rockerduck/work/queue-334/mutant-after.diff create mode 100644 agents/rockerduck/work/queue-334/mutant-after.tap create mode 100644 agents/rockerduck/work/queue-334/mutant-exec-source.sha256 create mode 100644 agents/rockerduck/work/queue-334/mutant-exec.diff create mode 100644 agents/rockerduck/work/queue-334/mutant-exec.tap create mode 100644 agents/rockerduck/work/queue-334/remaining-test-processes.txt create mode 100644 agents/rockerduck/work/queue-334/restoration.txt create mode 100644 agents/rockerduck/work/queue-334/restored.tap diff --git a/BUILD-LOG.md b/BUILD-LOG.md index 49da7d66f..211f28939 100644 --- a/BUILD-LOG.md +++ b/BUILD-LOG.md @@ -5820,3 +5820,5 @@ Before: agents can read the library; supporting-path and push-credential depende 2026-10-25 — Rockerduck row334 (#1832), before: Case 2 renders bus/Console only. Plan: reuse P1 proxy template/runner under --proxy, enforce three-unit re-install checks and proxy→bus→Console starts, cover refusals and both named mutants. Tests held for Sage CLEAR; design in agents/rockerduck/work/queue-334/BUILD.md. 2026-10-25 — Rockerduck row334 (#1832), RED evidence: whole case2-unit.test.mjs against baseline has 48 pass/33 expected new fail; whole case2-install.test.mjs has 27 pass/1 expected new fail. All 74 older tests pass. Implementations restored. Sage sage-4390 authorizes seat-branch candidate commit/push before GREEN; GREEN/mutants held until separate CLEAR after row331. Per-failure evidence: agents/rockerduck/work/queue-334/red-results.txt. + +2026-10-26 — Rockerduck row334 Mos1961: integrated old candidate onto 09a847eda using documented rebase after diagnosing merge queue-guard refusal; old RED preserved. Whole case2-unit 81/81 and case2-install 28/28 pass; named After and direct-ExecStart mutants killed, restored tests 2/2 pass; all nice19, private temp roots, zero skips. No source edits after integration beyond temporary restored mutants, no push/live action. Source c4bba5d2a; evidence agents/rockerduck/work/queue-334/BUILD.md. Full landing gate belongs to Sage; live behavior UNVERIFIED. diff --git a/agents/rockerduck/work/queue-334/BUILD.md b/agents/rockerduck/work/queue-334/BUILD.md index c1483a5c0..8697c63bb 100644 --- a/agents/rockerduck/work/queue-334/BUILD.md +++ b/agents/rockerduck/work/queue-334/BUILD.md @@ -100,3 +100,64 @@ Sage sage-4390 accepts clean RED and explicitly authorizes committing and pushing this candidate to rockerduck/row334 before GREEN. No force push. GREEN and mutants remain held for a separate CLEAR after row331 lands; then rebase onto landed P2 and check its missing-flag refusal code. + +## Mos1961 targeted execution — 2026-10-26 + +Authority: integrate onto refactor09a847ed, preserve old RED, two whole +files serial plus bounded named mutants/restoration. No push, borrowed +posting, live operations or review dispatch. All reviewers Codex; parent +arranges actual new review. Full package/global gate remains Sage's. + +Integration: first attempted merge retained both append-only log sides but +merge-continue was refused by the queue guard for incoming queue files. +Diagnosed scripts/git-hooks/pre-commit and packages/queue/README.md's +merge/rebase protocol; aborted merge, rebased normally without disabling +or overriding any hook. Only BUILD-LOG.md and SESSIONS.md conflicted; +retained current refactor log plus all candidate additions. Integrated +source commit c4bba5d2a3936897035c0e8fc8c3e14ca96b73af on exact base +09a847edaa25b609bac7728ff83f224708a29399. Old candidate bd5720662 stays +on origin/rockerduck/row334; no push performed. Original RED files retain +identical bytes (cleanup.txt records their hashes). + +Resources: before runs, no other node --test process found, memory +available 29270 MiB, swap free 85176 MiB, memory PSI full avg10 0.28. +Own-worktree npm ci --ignore-scripts --no-audit --no-fund rc0, nice19. +Fresh shell-mktemp short TMPDIR, private HOME/XDG_CONFIG_HOME and explicit +private MOSAIC_CONFIG per run. No real config/keys/units accessed. Absolute +node/test/TAP paths. Existing per-command and per-test deadlines preserved. +Import/export-from graph refreshed in green-imports.txt (56 local modules, +only case2-unit.test.mjs and case2-install.test.mjs as test entrypoints). +Sage-owned case2-precheck.sh and case1-accept.test.mjs unchanged, not run. +Only closing Next: line changed in case2-install.sh. + +Measured serial runs (raw TAP beside this file): +- green-unit.tap: rc0, 81/81 pass, zero skips, 78022.489026 ms. +- green-install.tap: rc0, 28/28 pass, zero skips, 8298.345458 ms. +- mutant-after.tap: rc1, selected test 1 fail, zero skips, 259.619391 ms. + Removed only bus After= insertion; expected dependency assertion killed it. +- mutant-exec.tap: rc1, selected test 1 fail, zero skips, 237.081878 ms. + Changed proxy template ExecStart to direct binary; exact ExecStart check + refused, selected content/start-order test killed it. Template restored. +- restored.tap: rc0, 2/2 pass, zero skips, 569.147722 ms, content/start-order + plus rendered ExecStart PIN/no-proxy refusals after both restorations. +Each bounded mutant/restoration command had timeout -k10 60; no timeout hit. +Each TAP header records private paths and measured nice19. No unexpected +red, assertion relaxation, deadline change or blind retry. Mutation diffs +and mutated-source hashes retained, source restored by EXIT traps. + +P2 dependency correction: product362893d043ff96fdd35f18e326cce683db031471 +landed in refactor; queue331 is tracking-only per Mos1915/#436, not a +product blocker. Landed packages/bus/src/model-keys.mjs:161 and :167 refuse +proxy-down on connection/client failure; :168 refuses non2xx as +proxy-key-refused. P1 runner still refuses proxy-not-configured with exit3 +when no proxy section exists. The rendered runner test now passes both +wrong-PIN proxy-install-invalid exit3 and missing-proxy exit3 checks. +This is temp-root test/source evidence; live .53/.54 behavior UNVERIFIED. + +Restoration: every green-source.sha256 pin matches after mutants, including +P1 template and PIN. Cleanup: all five logged test HOME/config/TMPDIR roots +removed; no node --test process remains at 22:42:35Z. Test fixture cleanup +completed. Temporary source backup copies were retained outside repository. +Raw evidence hashes in green-evidence.sha256. SLOTBACK: targeted work +complete; source ready for parent-arranged Codex review. Full package/global +landing gate and live install acceptance are not claimed. diff --git a/agents/rockerduck/work/queue-334/cleanup.txt b/agents/rockerduck/work/queue-334/cleanup.txt new file mode 100644 index 000000000..adc8e7bec --- /dev/null +++ b/agents/rockerduck/work/queue-334/cleanup.txt @@ -0,0 +1,14 @@ +Mos1961 targeted serial-slot cleanup/restoration +green-unit.tap: private root /mnt/storage/scratch/tmp/EHvgUM exists-before=True +removed=True +green-install.tap: private root /mnt/storage/scratch/tmp/iXTGcB exists-before=True +removed=True +mutant-after.tap: private root /mnt/storage/scratch/tmp/3LlK4H exists-before=True +removed=True +mutant-exec.tap: private root /mnt/storage/scratch/tmp/JuznlZ exists-before=True +removed=True +restored.tap: private root /mnt/storage/scratch/tmp/ayiWpX exists-before=True +removed=True +red-unit.log: old RED bytes preserved sha256=8a5c1074b520e3b4ff713e8766cae14b468d0589853499cb4ab0cc8510df3cea +red-install.log: old RED bytes preserved sha256=11138bdf1dcd314e35bf240e0a46c5d9deef204508b5bbec1d298c84a2e05f6f +red-results.txt: old RED bytes preserved sha256=d4e2fcb9c4387c6a328aa8d95576f2ec5a317b1a74210e341026ee89b3c1b76c diff --git a/agents/rockerduck/work/queue-334/green-evidence.sha256 b/agents/rockerduck/work/queue-334/green-evidence.sha256 new file mode 100644 index 000000000..d913abdd2 --- /dev/null +++ b/agents/rockerduck/work/queue-334/green-evidence.sha256 @@ -0,0 +1,14 @@ +cf0390df3b2800ccfa74ca8e1701de6f23496f12e376f63a3ed415b1e8280ba7 agents/rockerduck/work/queue-334/green-unit.tap +32d48a5bf5a9743e36525cef07c17989d3a4f3304d2c54359d5599ed548dde26 agents/rockerduck/work/queue-334/green-install.tap +4f11595c78fd8bc63ccc6da58fec28231c5fec0a77638cfd1f92a2bcbd5c4ffa agents/rockerduck/work/queue-334/mutant-after.tap +64545ce09254a7fd7674b4b91a19e31d093254917ae4370bb5e6d9372761cdd1 agents/rockerduck/work/queue-334/mutant-exec.tap +b4d9e2f1f42422603c48dbf4fde5a10b789abd4cb46bbd17d759ddae4d26a203 agents/rockerduck/work/queue-334/restored.tap +9d1a7b2c97a75cc22a35e62ab9d617289f62087e02f9dfb6eeb870de1cbd7a1c agents/rockerduck/work/queue-334/green-source.sha256 +0081e0326c000c066ac9245f7e31518cbf198d944bf11abc16c8d2379a04b100 agents/rockerduck/work/queue-334/green-imports.txt +06b739ad1947f0059f71af354328fc307da594d262cf4c886a7b73143a872861 agents/rockerduck/work/queue-334/mutant-after.diff +86b9100a1863f6c13e68c6638341659aed917254dee6c61207228fae41138158 agents/rockerduck/work/queue-334/mutant-exec.diff +32b803c436830fc36e4dc5ce48d021d69617b3add0102554558147a20d31401e agents/rockerduck/work/queue-334/mutant-after-source.sha256 +eb85013c2b52472d1210a52268ecd5d337ea46026f2cf64cabcc97e168ba9a52 agents/rockerduck/work/queue-334/mutant-exec-source.sha256 +acf321d41771070a070d14806c8b84bd6be7c6e30ee95567a22ec2c08918e3bf agents/rockerduck/work/queue-334/restoration.txt +8322de11b7085dc4de6e5be111cb55168598eb2ed631844569c2938c82ac42f7 agents/rockerduck/work/queue-334/cleanup.txt +ecfdf44317fa3ffd544d0f5707970acad2e20cfd1f690a5652a1fdacbf6b83f8 agents/rockerduck/work/queue-334/remaining-test-processes.txt diff --git a/agents/rockerduck/work/queue-334/green-imports.txt b/agents/rockerduck/work/queue-334/green-imports.txt new file mode 100644 index 000000000..2d8e8553a --- /dev/null +++ b/agents/rockerduck/work/queue-334/green-imports.txt @@ -0,0 +1,57 @@ +Mos1961 static imports/export-from graph; whole files serial, case1-accept excluded. +packages/cli/tests/case2-unit.test.mjs -> packages/business/tests/helpers.mjs, packages/seat/src/sandbox.mjs, packages/cli/tests/helpers.mjs, packages/cli/tests/case-sudo-fixture.mjs +packages/business/tests/helpers.mjs -> (builtins/external only) +packages/seat/src/sandbox.mjs -> packages/business/src/vocabulary.mjs +packages/business/src/vocabulary.mjs -> (builtins/external only) +packages/cli/tests/helpers.mjs -> packages/bus/src/broker.mjs, packages/bus/src/store.mjs, packages/business/tests/helpers.mjs, packages/harness/tests/helpers.mjs, packages/plugins/tests/helpers.mjs, packages/cli/src/transport.mjs +packages/bus/src/broker.mjs -> packages/bus/src/proxy-page-vocabulary.mjs, packages/model-proxy/src/validation.mjs, packages/bus/src/address.mjs, packages/processing-control/src/state.mjs, packages/plugins/src/kinds.mjs, packages/tasks/src/requirements.mjs, packages/bus/src/landing.mjs, packages/business/src/vocabulary.mjs +packages/bus/src/proxy-page-vocabulary.mjs -> (builtins/external only) +packages/model-proxy/src/validation.mjs -> (builtins/external only) +packages/bus/src/address.mjs -> (builtins/external only) +packages/processing-control/src/state.mjs -> (builtins/external only) +packages/plugins/src/kinds.mjs -> (builtins/external only) +packages/tasks/src/requirements.mjs -> (builtins/external only) +packages/bus/src/landing.mjs -> (builtins/external only) +packages/bus/src/store.mjs -> (builtins/external only) +packages/harness/tests/helpers.mjs -> packages/business/src/index.mjs, packages/business/tests/helpers.mjs, packages/plugins/src/loader.mjs +packages/business/src/index.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/role.mjs, packages/business/src/vars.mjs, packages/business/src/credentials.mjs, packages/business/src/business.mjs, packages/business/src/access.mjs, packages/business/src/project.mjs, packages/business/src/resolve.mjs, packages/business/src/library-seats.mjs +packages/business/src/errors.mjs -> (builtins/external only) +packages/business/src/role.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs +packages/business/src/util.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs +packages/business/src/vars.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs, packages/plugins/src/kinds.mjs +packages/business/src/credentials.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/util.mjs +packages/business/src/business.mjs -> packages/business/src/errors.mjs, packages/business/src/launch.mjs, packages/business/src/vars.mjs, packages/business/src/credentials.mjs, packages/business/src/role.mjs, packages/business/src/vocabulary.mjs, packages/plugins/src/kinds.mjs, packages/library/src/mapping.mjs, packages/business/src/util.mjs +packages/business/src/launch.mjs -> packages/business/src/util.mjs, packages/business/src/errors.mjs +packages/library/src/mapping.mjs -> packages/library/src/problems.mjs +packages/library/src/problems.mjs -> (builtins/external only) +packages/business/src/access.mjs -> packages/business/src/errors.mjs, packages/business/src/business.mjs, packages/business/src/util.mjs, packages/business/src/vocabulary.mjs +packages/business/src/project.mjs -> packages/business/src/errors.mjs, packages/business/src/vars.mjs, packages/business/src/util.mjs +packages/business/src/resolve.mjs -> packages/business/src/errors.mjs, packages/business/src/vocabulary.mjs, packages/business/src/vars.mjs, packages/business/src/util.mjs, packages/business/src/project.mjs +packages/business/src/library-seats.mjs -> packages/business/src/errors.mjs, packages/business/src/business.mjs, packages/business/src/vocabulary.mjs +packages/plugins/src/loader.mjs -> packages/plugins/src/kinds.mjs +packages/plugins/tests/helpers.mjs -> (builtins/external only) +packages/cli/src/transport.mjs -> packages/cli/src/errors.mjs +packages/cli/src/errors.mjs -> (builtins/external only) +packages/cli/tests/case-sudo-fixture.mjs -> (builtins/external only) +packages/cli/tests/case2-install.test.mjs -> packages/business/tests/helpers.mjs, packages/library/tests/helpers.mjs, packages/library/src/index.mjs, packages/seat/src/checkout.mjs, packages/project/src/git.mjs, packages/cli/tests/helpers.mjs +packages/library/tests/helpers.mjs -> packages/library/src/mapping.mjs +packages/library/src/index.mjs -> packages/library/src/problems.mjs, packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/supporting.mjs, packages/library/src/links.mjs, packages/library/src/reader.mjs, packages/library/src/render.mjs, packages/library/src/survey.mjs, packages/library/src/mirror.mjs, packages/library/src/sync.mjs, packages/library/src/index-build.mjs, packages/library/src/query.mjs, packages/library/src/limits.mjs, packages/library/src/guard.mjs, packages/library/src/write.mjs +packages/library/src/scope.mjs -> (builtins/external only) +packages/library/src/supporting.mjs -> packages/library/src/problems.mjs, packages/library/src/scope.mjs +packages/library/src/links.mjs -> (builtins/external only) +packages/library/src/reader.mjs -> packages/project/src/git.mjs, packages/library/src/scope.mjs, packages/library/src/links.mjs, packages/library/src/problems.mjs +packages/project/src/git.mjs -> packages/seat/src/checkout.mjs, packages/project/src/paths.mjs, packages/processing-control/src/effects.mjs +packages/seat/src/checkout.mjs -> packages/processing-control/src/effects.mjs +packages/processing-control/src/effects.mjs -> packages/processing-control/src/state.mjs, packages/processing-control/src/runtimes.mjs +packages/processing-control/src/runtimes.mjs -> packages/processing-control/src/state.mjs +packages/project/src/paths.mjs -> (builtins/external only) +packages/library/src/render.mjs -> (builtins/external only) +packages/library/src/survey.mjs -> packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/links.mjs, packages/library/src/reader.mjs, packages/library/src/problems.mjs +packages/library/src/mirror.mjs -> packages/project/src/paths.mjs, packages/project/src/git.mjs, packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/problems.mjs, packages/library/src/reader.mjs +packages/library/src/sync.mjs -> packages/seat/src/checkout.mjs, packages/project/src/git.mjs, packages/library/src/mapping.mjs, packages/library/src/problems.mjs, packages/library/src/reader.mjs, packages/library/src/index-build.mjs, packages/library/src/mirror.mjs +packages/library/src/index-build.mjs -> packages/library/src/reader.mjs, packages/library/src/problems.mjs +packages/library/src/query.mjs -> packages/library/src/problems.mjs, packages/library/src/mapping.mjs, packages/library/src/index-build.mjs, packages/library/src/reader.mjs +packages/library/src/limits.mjs -> (builtins/external only) +packages/library/src/guard.mjs -> packages/project/src/git.mjs, packages/library/src/scope.mjs, packages/library/src/reader.mjs, packages/library/src/problems.mjs, packages/library/src/mirror.mjs, packages/library/src/limits.mjs, packages/library/src/reply-protocol.mjs +packages/library/src/reply-protocol.mjs -> (builtins/external only) +packages/library/src/write.mjs -> packages/project/src/git.mjs, packages/seat/src/checkout.mjs, packages/business/src/vocabulary.mjs, packages/library/src/mapping.mjs, packages/library/src/scope.mjs, packages/library/src/supporting.mjs, packages/library/src/problems.mjs, packages/library/src/reader.mjs, packages/library/src/mirror.mjs, packages/library/src/sync.mjs diff --git a/agents/rockerduck/work/queue-334/green-install.tap b/agents/rockerduck/work/queue-334/green-install.tap new file mode 100644 index 000000000..3511bb7ee --- /dev/null +++ b/agents/rockerduck/work/queue-334/green-install.tap @@ -0,0 +1,179 @@ +# TMPDIR=/mnt/storage/scratch/tmp/iXTGcB HOME=/mnt/storage/scratch/tmp/iXTGcB/home MOSAIC_CONFIG=/mnt/storage/scratch/tmp/iXTGcB/home/.config/mosaic-dev/config.json nice=19 +TAP version 13 +# Subtest: the library install writes the business file, personas and slot dir, makes the copy and starts nothing +ok 1 - the library install writes the business file, personas and slot dir, makes the copy and starts nothing + --- + duration_ms: 247.114691 + type: 'test' + ... +# Subtest: a library re-run passes and leaves every file as it was +ok 2 - a library re-run passes and leaves every file as it was + --- + duration_ms: 409.006062 + type: 'test' + ... +# Subtest: a re-run refuses business-file-differs and leaves the file unchanged +ok 3 - a re-run refuses business-file-differs and leaves the file unchanged + --- + duration_ms: 279.306698 + type: 'test' + ... +# Subtest: a re-run refuses persona-differs when an installed persona isn't the staged one, and writes nothing +ok 4 - a re-run refuses persona-differs when an installed persona isn't the staged one, and writes nothing + --- + duration_ms: 282.805377 + type: 'test' + ... +# Subtest: the factory install writes no library mapping, persona or slot dir +ok 5 - the factory install writes no library mapping, persona or slot dir + --- + duration_ms: 183.788653 + type: 'test' + ... +# Subtest: the factory install refuses a library project and bus.tester off, before anything is written +ok 6 - the factory install refuses a library project and bus.tester off, before anything is written + --- + duration_ms: 75.316181 + type: 'test' + ... +# Subtest: the library install refuses bus.tester on and a persona var in the input +ok 7 - the library install refuses bus.tester on and a persona var in the input + --- + duration_ms: 94.011039 + type: 'test' + ... +# Subtest: the install refuses root, a business id mismatch, another --home and a config dir with group bits +ok 8 - the install refuses root, a business id mismatch, another --home and a config dir with group bits + --- + duration_ms: 68.69039 + type: 'test' + ... +# Subtest: the library install needs --personas +ok 9 - the library install needs --personas + --- + duration_ms: 6.411755 + type: 'test' + ... +# Subtest: a validate refusal removes the business file this run wrote +ok 10 - a validate refusal removes the business file this run wrote + --- + duration_ms: 254.969107 + type: 'test' + ... +# Subtest: N4: a validate refusal on a re-run leaves the matching business file in place, byte for byte +ok 11 - N4: a validate refusal on a re-run leaves the matching business file in place, byte for byte + --- + duration_ms: 424.725266 + type: 'test' + ... +# Subtest: a clean library host passes the precheck with no mirror yet +ok 12 - a clean library host passes the precheck with no mirror yet + --- + duration_ms: 435.686925 + type: 'test' + ... +# Subtest: the library precheck refuses a persona file at 0644 +ok 13 - the library precheck refuses a persona file at 0644 + --- + duration_ms: 417.655889 + type: 'test' + ... +# Subtest: the library precheck refuses a persona whose digest isn't persona.sha256 +ok 14 - the library precheck refuses a persona whose digest isn't persona.sha256 + --- + duration_ms: 411.08414 + type: 'test' + ... +# Subtest: the library precheck refuses a persona dir with group bits +ok 15 - the library precheck refuses a persona dir with group bits + --- + duration_ms: 451.558674 + type: 'test' + ... +# Subtest: the library precheck refuses a business file at 0644 +ok 16 - the library precheck refuses a business file at 0644 + --- + duration_ms: 435.345965 + type: 'test' + ... +# Subtest: the library precheck refuses a changes.jsonl at 0644 +ok 17 - the library precheck refuses a changes.jsonl at 0644 + --- + duration_ms: 584.394398 + type: 'test' + ... +# Subtest: the library precheck refuses a Discord binding +ok 18 - the library precheck refuses a Discord binding + --- + duration_ms: 441.83167 + type: 'test' + ... +# Subtest: --library-status refuses library-mirror-missing before the bus has made the mirror +ok 19 - --library-status refuses library-mirror-missing before the bus has made the mirror + --- + duration_ms: 337.042932 + type: 'test' + ... +# Subtest: --library-status refuses library-never-synced on a fresh mirror +ok 20 - --library-status refuses library-never-synced on a fresh mirror + --- + duration_ms: 350.216282 + type: 'test' + ... +# Subtest: --library-status names a recorded lastError before the null lastFetch it leaves (N3) +ok 21 - --library-status names a recorded lastError before the null lastFetch it leaves (N3) + --- + duration_ms: 369.786709 + type: 'test' + ... +# Subtest: --library-status prints each R-problem's path as an escaped JSON string, then the count, and passes +ok 22 - --library-status prints each R-problem's path as an escaped JSON string, then the count, and passes + --- + duration_ms: 410.961598 + type: 'test' + ... +# Subtest: --library-status takes no --profile +ok 23 - --library-status takes no --profile + --- + duration_ms: 5.4699 + type: 'test' + ... +# Subtest: Vikunja 614: install preserves the explicit notifier decision bytes and mode and creates none when absent +ok 24 - Vikunja 614: install preserves the explicit notifier decision bytes and mode and creates none when absent + --- + duration_ms: 479.343091 + type: 'test' + ... +# Subtest: row 322 F8: library personas install from the copy with no clone node_modules +ok 25 - row 322 F8: library personas install from the copy with no clone node_modules + --- + duration_ms: 146.617921 + type: 'test' + ... +# Subtest: row 322 F9: importer refusal keeps the error line rather than the Node banner +ok 26 - row 322 F9: importer refusal keeps the error line rather than the Node banner + --- + duration_ms: 108.029088 + type: 'test' + ... +# Subtest: C2-21: library install supplies chief identity and books publish for its real read grant +ok 27 - C2-21: library install supplies chief identity and books publish for its real read grant + --- + duration_ms: 236.226186 + type: 'test' + ... +# Subtest: row334 install Next tells root to select proxy only when configured +ok 28 - row334 install Next tells root to select proxy only when configured + --- + duration_ms: 242.832964 + type: 'test' + ... +1..28 +# tests 28 +# suites 0 +# pass 28 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 8298.345458 diff --git a/agents/rockerduck/work/queue-334/green-source.sha256 b/agents/rockerduck/work/queue-334/green-source.sha256 new file mode 100644 index 000000000..8f6ad736b --- /dev/null +++ b/agents/rockerduck/work/queue-334/green-source.sha256 @@ -0,0 +1,6 @@ +30d9674f6b5b704b82bf7dfcf054b425d6b9480144ab52bb00f668af514c17bd scripts/case2-unit.sh +9e52d30113ae1cfa82f947674a4132dd689fc43ac1a1e8cdc4bce0c71e42fde1 scripts/case2-install.sh +373f64bf56f031a1d76873f1444b35f2de2a8e26a84dca9107f1993dbd9669bb packages/cli/tests/case2-unit.test.mjs +716f7728f018b16f917e60547459f6791dab5d3239dd4dcda5a7365f54850ade packages/cli/tests/case2-install.test.mjs +16c31f119d064a836794d167d57a6a1b765303005d93d1feba3e07e4b9288bd2 packages/cli/systemd/mosaic-proxy.service.in +889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b packages/model-proxy/PIN diff --git a/agents/rockerduck/work/queue-334/green-unit.tap b/agents/rockerduck/work/queue-334/green-unit.tap new file mode 100644 index 000000000..2eed91f73 --- /dev/null +++ b/agents/rockerduck/work/queue-334/green-unit.tap @@ -0,0 +1,497 @@ +# TMPDIR=/mnt/storage/scratch/tmp/EHvgUM HOME=/mnt/storage/scratch/tmp/EHvgUM/home MOSAIC_CONFIG=/mnt/storage/scratch/tmp/EHvgUM/home/.config/mosaic-dev/config.json nice=19 +TAP version 13 +# Subtest: row253 factory socket uses actual config and target-uid query without widening hardening +ok 1 - row253 factory socket uses actual config and target-uid query without widening hardening + --- + duration_ms: 320.786952 + type: 'test' + ... +# Subtest: row253 installer refuses unsafe location and query facts before unit writes +ok 2 - row253 installer refuses unsafe location and query facts before unit writes + --- + duration_ms: 3259.255387 + type: 'test' + ... +# Subtest: row253 query timeout kills its process group and leaves no running child +ok 3 - row253 query timeout kills its process group and leaves no running child + --- + duration_ms: 7050.967328 + type: 'test' + ... +# Subtest: row253 protected homes refuse before any filesystem access +ok 4 - row253 protected homes refuse before any filesystem access + --- + duration_ms: 9.235035 + type: 'test' + ... +# Subtest: row253 C4 sleep query has exact inner reason and cleans all members +ok 5 - row253 C4 sleep query has exact inner reason and cleans all members + --- + duration_ms: 10728.278487 + type: 'test' + ... +# Subtest: row253 C4 signals query has exact inner reason and cleans all members +ok 6 - row253 C4 signals query has exact inner reason and cleans all members + --- + duration_ms: 10727.497398 + type: 'test' + ... +# Subtest: row253 C4 member query has exact inner reason and cleans all members +ok 7 - row253 C4 member query has exact inner reason and cleans all members + --- + duration_ms: 10864.916145 + type: 'test' + ... +# Subtest: row253 C4 overflow is output-limit in both sudo modes +ok 8 - row253 C4 overflow is output-limit in both sudo modes + --- + duration_ms: 471.505102 + type: 'test' + ... +# Subtest: row253 C4 stalled supervisor uses the outer reason and explicit residual cleanup +ok 9 - row253 C4 stalled supervisor uses the outer reason and explicit residual cleanup + --- + duration_ms: 14141.133414 + type: 'test' + ... +# Subtest: row253 C4 inline supervisor is byte-identical in both host scripts +ok 10 - row253 C4 inline supervisor is byte-identical in both host scripts + --- + duration_ms: 1.040122 + type: 'test' + ... +# Subtest: row253 C4 cleanup budget starts after inventory pass one +ok 11 - row253 C4 cleanup budget starts after inventory pass one + --- + duration_ms: 36.998899 + type: 'test' + ... +# Subtest: row253 query reaps its group even when a child closes stdout before the query returns +ok 12 - row253 query reaps its group even when a child closes stdout before the query returns + --- + duration_ms: 128.332368 + type: 'test' + ... +# Subtest: row253 config parser is strict +ok 13 - row253 config parser is strict + --- + duration_ms: 8.326775 + type: 'test' + ... +# Subtest: a clean library render writes both units 0644 with the fixed lines, and enables both then starts the bus then the Console +ok 14 - a clean library render writes both units 0644 with the fixed lines, and enables both then starts the bus then the Console + --- + duration_ms: 95.375021 + type: 'test' + ... +# Subtest: PATH starts with the --node directory, for a node outside the default list and for /usr/bin/node +ok 15 - PATH starts with the --node directory, for a node outside the default list and for /usr/bin/node + --- + duration_ms: 107.764189 + type: 'test' + ... +# Subtest: a failed bus start refuses with the Console not started +ok 16 - a failed bus start refuses with the Console not started + --- + duration_ms: 95.26919 + type: 'test' + ... +# Subtest: the script never links a unit file +ok 17 - the script never links a unit file + --- + duration_ms: 0.161935 + type: 'test' + ... +# Subtest: factory renders --pm once and one MOSAIC_CLAUDE_BIN line, and without them both tokens render empty +ok 18 - factory renders --pm once and one MOSAIC_CLAUDE_BIN line, and without them both tokens render empty + --- + duration_ms: 601.778739 + type: 'test' + ... +# Subtest: a re-install over running units says they are still on the old copy and must restart together, never that it started them +ok 19 - a re-install over running units says they are still on the old copy and must restart together, never that it started them + --- + duration_ms: 414.344645 + type: 'test' + ... +# Subtest: a re-install to another copy re-renders both units, and an edited installed unit refuses +ok 20 - a re-install to another copy re-renders both units, and an edited installed unit refuses + --- + duration_ms: 994.134837 + type: 'test' + ... +# Subtest: a template with a namespace, user or system call restriction refuses +ok 21 - a template with a namespace, user or system call restriction refuses + --- + duration_ms: 263.798116 + type: 'test' + ... +# Subtest: the bus template's EnvironmentFile line must be there and point at the session env, and the Console template must have none +ok 22 - the bus template's EnvironmentFile line must be there and point at the session env, and the Console template must have none + --- + duration_ms: 181.439557 + type: 'test' + ... +# Subtest: a template holding an unknown token, PermissionsStartOnly or a privileged Exec prefix refuses +ok 23 - a template holding an unknown token, PermissionsStartOnly or a privileged Exec prefix refuses + --- + duration_ms: 138.913066 + type: 'test' + ... +# Subtest: a symlink at either unit path refuses +ok 24 - a symlink at either unit path refuses + --- + duration_ms: 167.097448 + type: 'test' + ... +# Subtest: a --node that is relative, not root-owned or under refuses +ok 25 - a --node that is relative, not root-owned or under refuses + --- + duration_ms: 18.382732 + type: 'test' + ... +# Subtest: a re-install with a different --node or different serve flags refuses +ok 26 - a re-install with a different --node or different serve flags refuses + --- + duration_ms: 476.601285 + type: 'test' + ... +# Subtest: an installed pair whose units name different copies refuses +ok 27 - an installed pair whose units name different copies refuses + --- + duration_ms: 244.045399 + type: 'test' + ... +# Subtest: a copy id that is short, uppercase, holds / or .., or names no directory refuses +ok 28 - a copy id that is short, uppercase, holds / or .., or names no directory refuses + --- + duration_ms: 28.577084 + type: 'test' + ... +# Subtest: library refuses a privileged-floor miss, a bad proof pair and every flag outside its set +ok 29 - library refuses a privileged-floor miss, a bad proof pair and every flag outside its set + --- + duration_ms: 270.700937 + type: 'test' + ... +# Subtest: library refuses a proof file not owned by 's uid +ok 30 - library refuses a proof file not owned by 's uid + --- + duration_ms: 15.926859 + type: 'test' + ... +# Subtest: factory refuses duplicate socket, a missing --port or --business, and each proxy flag +ok 31 - factory refuses duplicate socket, a missing --port or --business, and each proxy flag + --- + duration_ms: 178.797946 + type: 'test' + ... +# Subtest: row253 factory refuses retired TCP and a value after the socket marker +ok 32 - row253 factory refuses retired TCP and a value after the socket marker + --- + duration_ms: 26.729147 + type: 'test' + ... +# Subtest: factory refuses a --claude that is relative, not root-owned or under , and a re-install with another --pm or --claude +ok 33 - factory refuses a --claude that is relative, not root-owned or under , and a re-install with another --pm or --claude + --- + duration_ms: 1287.523935 + type: 'test' + ... +# Subtest: the precheck passes on a good host and prints free memory, without the key +ok 34 - the precheck passes on a good host and prints free memory, without the key + --- + duration_ms: 165.265761 + type: 'test' + ... +# Subtest: the precheck refuses each failed host check +ok 35 - the precheck refuses each failed host check + --- + duration_ms: 1355.479314 + type: 'test' + ... +# Subtest: the precheck refuses a user missing from passwd, a business file that does not load, and a symlinked run root +ok 36 - the precheck refuses a user missing from passwd, a business file that does not load, and a symlinked run root + --- + duration_ms: 749.037298 + type: 'test' + ... +# Subtest: a bwrap that fails refuses and prints the sysctl and where bwrap is +ok 37 - a bwrap that fails refuses and prints the sysctl and where bwrap is + --- + duration_ms: 158.018943 + type: 'test' + ... +# Subtest: an unprivileged port floor at or below the Console's port refuses, and so does a missing Console unit +ok 38 - an unprivileged port floor at or below the Console's port refuses, and so does a missing Console unit + --- + duration_ms: 775.768583 + type: 'test' + ... +# Subtest: bus.tester: library refuses it on, factory needs it on, and factory refuses a library business +ok 39 - bus.tester: library refuses it on, factory needs it on, and factory refuses a library business + --- + duration_ms: 591.243454 + type: 'test' + ... +# Subtest: the claude check runs only for a claude-code instance, and refuses a claude that appends or answers wrong +ok 40 - the claude check runs only for a claude-code instance, and refuses a claude that appends or answers wrong + --- + duration_ms: 1192.916891 + type: 'test' + ... +# Subtest: the claude check runs the bus unit's MOSAIC_CLAUDE_BIN over claude on PATH +ok 41 - the claude check runs the bus unit's MOSAIC_CLAUDE_BIN over claude on PATH + --- + duration_ms: 380.298256 + type: 'test' + ... +# Subtest: the session env file refuses when missing, open to others, a symlink, empty, or emptied by a later line +ok 42 - the session env file refuses when missing, open to others, a symlink, empty, or emptied by a later line + --- + duration_ms: 944.757771 + type: 'test' + ... +# Subtest: inside a session's sandbox a bind below 1024 fails with EACCES, and a bind on a free high port succeeds +ok 43 - inside a session's sandbox a bind below 1024 fails with EACCES, and a bind on a free high port succeeds + --- + duration_ms: 94.761095 + type: 'test' + ... +# Subtest: Vikunja 614 factory: scoped @anthropic-ai Claude path renders and passes installed read-back +ok 44 - Vikunja 614 factory: scoped @anthropic-ai Claude path renders and passes installed read-back + --- + duration_ms: 804.156726 + type: 'test' + ... +# Subtest: Vikunja 614 factory: plain paths still refuse every named unsafe character +ok 45 - Vikunja 614 factory: plain paths still refuse every named unsafe character + --- + duration_ms: 87.565396 + type: 'test' + ... +# Subtest: Vikunja 614 precheck: explicit null and named notifier decisions pass +ok 46 - Vikunja 614 precheck: explicit null and named notifier decisions pass + --- + duration_ms: 305.744175 + type: 'test' + ... +# Subtest: Vikunja 614 precheck: notifier config refuses missing, public, malformed and extra-key decisions +ok 47 - Vikunja 614 precheck: notifier config refuses missing, public, malformed and extra-key decisions + --- + duration_ms: 1300.724491 + type: 'test' + ... +# Subtest: row334 no-proxy renders stay byte-identical to the pre-row renderer +ok 48 - row334 no-proxy renders stay byte-identical to the pre-row renderer + --- + duration_ms: 257.734638 + type: 'test' + ... +# Subtest: row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order +ok 49 - row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order + --- + duration_ms: 137.176987 + type: 'test' + ... +# Subtest: row334 proxy refuses continuation by message before writing +ok 50 - row334 proxy refuses continuation by message before writing + --- + duration_ms: 90.060095 + type: 'test' + ... +# Subtest: row334 proxy refuses not-setting by message before writing +ok 51 - row334 proxy refuses not-setting by message before writing + --- + duration_ms: 93.993348 + type: 'test' + ... +# Subtest: row334 proxy refuses RestrictNamespaces by message before writing +ok 52 - row334 proxy refuses RestrictNamespaces by message before writing + --- + duration_ms: 93.341838 + type: 'test' + ... +# Subtest: row334 proxy refuses PrivateUsers by message before writing +ok 53 - row334 proxy refuses PrivateUsers by message before writing + --- + duration_ms: 94.764023 + type: 'test' + ... +# Subtest: row334 proxy refuses SystemCallFilter by message before writing +ok 54 - row334 proxy refuses SystemCallFilter by message before writing + --- + duration_ms: 94.826317 + type: 'test' + ... +# Subtest: row334 proxy refuses PermissionsStartOnly by message before writing +ok 55 - row334 proxy refuses PermissionsStartOnly by message before writing + --- + duration_ms: 96.116509 + type: 'test' + ... +# Subtest: row334 proxy refuses EnvironmentFile by message before writing +ok 56 - row334 proxy refuses EnvironmentFile by message before writing + --- + duration_ms: 119.193391 + type: 'test' + ... +# Subtest: row334 proxy refuses AmbientCapabilities by message before writing +ok 57 - row334 proxy refuses AmbientCapabilities by message before writing + --- + duration_ms: 116.325629 + type: 'test' + ... +# Subtest: row334 proxy refuses CapabilityBoundingSet by message before writing +ok 58 - row334 proxy refuses CapabilityBoundingSet by message before writing + --- + duration_ms: 117.596342 + type: 'test' + ... +# Subtest: row334 proxy refuses privileged by message before writing +ok 59 - row334 proxy refuses privileged by message before writing + --- + duration_ms: 98.105075 + type: 'test' + ... +# Subtest: row334 proxy refuses direct-binary by message before writing +ok 60 - row334 proxy refuses direct-binary by message before writing + --- + duration_ms: 114.60378 + type: 'test' + ... +# Subtest: row334 proxy refuses nnp by message before writing +ok 61 - row334 proxy refuses nnp by message before writing + --- + duration_ms: 103.113825 + type: 'test' + ... +# Subtest: row334 proxy refuses cwd by message before writing +ok 62 - row334 proxy refuses cwd by message before writing + --- + duration_ms: 102.872946 + type: 'test' + ... +# Subtest: row334 proxy refuses environment by message before writing +ok 63 - row334 proxy refuses environment by message before writing + --- + duration_ms: 104.833099 + type: 'test' + ... +# Subtest: row334 proxy refuses install by message before writing +ok 64 - row334 proxy refuses install by message before writing + --- + duration_ms: 113.150594 + type: 'test' + ... +# Subtest: row334 proxy refuses user by message before writing +ok 65 - row334 proxy refuses user by message before writing + --- + duration_ms: 99.6967 + type: 'test' + ... +# Subtest: row334 proxy refuses group by message before writing +ok 66 - row334 proxy refuses group by message before writing + --- + duration_ms: 100.919966 + type: 'test' + ... +# Subtest: row334 proxy refuses ProtectSystem by message before writing +ok 67 - row334 proxy refuses ProtectSystem by message before writing + --- + duration_ms: 105.543055 + type: 'test' + ... +# Subtest: row334 proxy refuses ReadWritePaths by message before writing +ok 68 - row334 proxy refuses ReadWritePaths by message before writing + --- + duration_ms: 107.705639 + type: 'test' + ... +# Subtest: row334 proxy refuses ProtectHome by message before writing +ok 69 - row334 proxy refuses ProtectHome by message before writing + --- + duration_ms: 107.590511 + type: 'test' + ... +# Subtest: row334 proxy refuses PrivateTmp by message before writing +ok 70 - row334 proxy refuses PrivateTmp by message before writing + --- + duration_ms: 109.894567 + type: 'test' + ... +# Subtest: row334 proxy refuses token by message before writing +ok 71 - row334 proxy refuses token by message before writing + --- + duration_ms: 85.918305 + type: 'test' + ... +# Subtest: row334 proxy template missing or symlink refuses +ok 72 - row334 proxy template missing or symlink refuses + --- + duration_ms: 167.940142 + type: 'test' + ... +# Subtest: row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status +ok 73 - row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status + --- + duration_ms: 306.45812 + type: 'test' + ... +# Subtest: row334 reinstall repins all three and refuses a proxy copy mismatch +ok 74 - row334 reinstall repins all three and refuses a proxy copy mismatch + --- + duration_ms: 580.756121 + type: 'test' + ... +# Subtest: row334 installed proxy without --proxy refuses and preserves all bytes +ok 75 - row334 installed proxy without --proxy refuses and preserves all bytes + --- + duration_ms: 217.139684 + type: 'test' + ... +# Subtest: row334 dangling proxy symlink without flag refuses without deleting +ok 76 - row334 dangling proxy symlink without flag refuses without deleting + --- + duration_ms: 115.14093 + type: 'test' + ... +# Subtest: row334 active proxy reports old copy and all three must restart together +ok 77 - row334 active proxy reports old copy and all three must restart together + --- + duration_ms: 367.168744 + type: 'test' + ... +# Subtest: row334 failed mosaic-proxy.service start leaves later units unstarted +ok 78 - row334 failed mosaic-proxy.service start leaves later units unstarted + --- + duration_ms: 138.123277 + type: 'test' + ... +# Subtest: row334 failed mosaic-bus@acme.service start leaves later units unstarted +ok 79 - row334 failed mosaic-bus@acme.service start leaves later units unstarted + --- + duration_ms: 132.720562 + type: 'test' + ... +# Subtest: row334 installed proxy enforces hardening order and remaining common refusals +ok 80 - row334 installed proxy enforces hardening order and remaining common refusals + --- + duration_ms: 667.650113 + type: 'test' + ... +# Subtest: row334 proxy installed path rejects symlink and non-regular file +ok 81 - row334 proxy installed path rejects symlink and non-regular file + --- + duration_ms: 239.721676 + type: 'test' + ... +1..81 +# tests 81 +# suites 0 +# pass 81 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 78022.489026 diff --git a/agents/rockerduck/work/queue-334/mutant-after-source.sha256 b/agents/rockerduck/work/queue-334/mutant-after-source.sha256 new file mode 100644 index 000000000..249776e59 --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-after-source.sha256 @@ -0,0 +1 @@ +3260d5f6498aaaf810412356c0fd2e1ff10e91f481c8b365ca32e6e4165166d9 scripts/case2-unit.sh diff --git a/agents/rockerduck/work/queue-334/mutant-after.diff b/agents/rockerduck/work/queue-334/mutant-after.diff new file mode 100644 index 000000000..12ecf6e97 --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-after.diff @@ -0,0 +1,13 @@ +diff --git a/scripts/case2-unit.sh b/scripts/case2-unit.sh +index bf5097abb..d8a1aae18 100755 +--- a/scripts/case2-unit.sh ++++ b/scripts/case2-unit.sh +@@ -456,7 +456,7 @@ render() { + local add="User=$USER_NAME\nGroup=$GROUP\n${HARDENING//$'\n'/\\n}\n" + [ "$kind" != webui ] || add="$add${CAPS//$'\n'/\\n}\n" + if [ "$kind" = bus ] && [ "$PROXY" = 1 ]; then +- text="$(printf '%s\n' "$text" | sed "/^Description=/a Wants=$PROXY_UNIT\\nAfter=$PROXY_UNIT")" ++ text="$(printf '%s\n' "$text" | sed "/^Description=/a Wants=$PROXY_UNIT")" + fi + # The added lines go at the end of [Service], before its trailing blank + # lines. In [Install], WantedBy=multi-user.target replaces diff --git a/agents/rockerduck/work/queue-334/mutant-after.tap b/agents/rockerduck/work/queue-334/mutant-after.tap new file mode 100644 index 000000000..de1d5befc --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-after.tap @@ -0,0 +1,133 @@ +# TMPDIR=/mnt/storage/scratch/tmp/3LlK4H HOME=/mnt/storage/scratch/tmp/3LlK4H/home MOSAIC_CONFIG=/mnt/storage/scratch/tmp/3LlK4H/home/.config/mosaic-dev/config.json nice=19 budget=60s +TAP version 13 +# Subtest: row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order +not ok 1 - row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order + --- + duration_ms: 139.480123 + type: 'test' + location: '/home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:966:1' + failureType: 'testCodeFailure' + error: |- + The input did not match the regular expression /Description=[^\n]+\nWants=mosaic-proxy.service\nAfter=mosaic-proxy.service\n/. Input: + + '# Mosaic bus host, one instance per business: mosaic-bus@.\n' + + '# Rendered by scripts/bus-service.sh from packages/cli/systemd/; /mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n' + + '# /usr/bin:/usr/local/bin:/bin and the claude line below are filled in at install time. Edit the template and reinstall; do\n' + + '# not edit the installed copy. The bus store allows one broker per data\n' + + '# root, so run one instance per data root (packages/cli/README.md).\n' + + '[Unit]\n' + + 'Description=Mosaic bus host (%i)\n' + + 'Wants=mosaic-proxy.service\n' + + 'Documentation=file:///mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/packages/cli/README.md\n' + + 'StartLimitIntervalSec=600\n' + + 'StartLimitBurst=5\n' + + '\n' + + '[Service]\n' + + 'Type=simple\n' + + 'WorkingDirectory=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n' + + 'Environment=PATH=/usr/bin:/usr/local/bin:/bin\n' + + "# The Claude Code binary that managed sessions and the manifest's\n" + + '# claudeVersion run, pinned at install (`--claude PATH`, default\n' + + '# `command -v claude`). Without it they run `claude` from PATH above.\n' + + 'Environment=MOSAIC_CLAUDE_BIN=/usr/bin/true\n' + + '# Claude Code sessions log in with what this 0600 file sets, which the\n' + + "# operator writes: CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, or a proxy's\n" + + '# ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL. The `-` lets the unit start\n' + + '# without it, and a Claude Code launch then refuses.\n' + + 'EnvironmentFile=-/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.config/mosaic-dev/secrets/claude-session.env\n' + + '# The host reads the system config and the business file, boots the broker\n' + + '# (packages/bus/src/process.mjs) and starts the notifier. Config problems and\n' + + '# refusals exit 3, usage 4, invalid input 2: none of those is retried. A\n' + + '# child that dies takes the host down with exit 1, and the unit restarts\n' + + '# the pair.\n' + + 'ExecStart=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/scripts/mosaic bus start %i\n' + + 'Restart=on-failure\n' + + 'RestartSec=15\n' + + 'RestartPreventExitStatus=2 3 4\n' + + '# `systemctl --user stop` sends SIGTERM to the host, which stops the\n' + + '# notifier after its poll in flight, then closes the broker.\n' + + 'KillSignal=SIGTERM\n' + + 'KillMode=mixed\n' + + 'TimeoutStopSec=60\n' + + 'NoNewPrivileges=yes\n' + + 'User=mosaic\n' + + 'Group=mosaic\n' + + 'ProtectSystem=strict\n' + + 'ReadWritePaths=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic\n' + + 'ProtectHome=yes\n' + + 'PrivateTmp=yes\n' + + '\n' + + '[Install]\n' + + 'WantedBy=multi-user.target\n' + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: + actual: |- + # Mosaic bus host, one instance per business: mosaic-bus@. + # Rendered by scripts/bus-service.sh from packages/cli/systemd/; /mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, + # /usr/bin:/usr/local/bin:/bin and the claude line below are filled in at install time. Edit the template and reinstall; do + # not edit the installed copy. The bus store allows one broker per data + # root, so run one instance per data root (packages/cli/README.md). + [Unit] + Description=Mosaic bus host (%i) + Wants=mosaic-proxy.service + Documentation=file:///mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/packages/cli/README.md + StartLimitIntervalSec=600 + StartLimitBurst=5 + + [Service] + Type=simple + WorkingDirectory=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Environment=PATH=/usr/bin:/usr/local/bin:/bin + # The Claude Code binary that managed sessions and the manifest's + # claudeVersion run, pinned at install (`--claude PATH`, default + # `command -v claude`). Without it they run `claude` from PATH above. + Environment=MOSAIC_CLAUDE_BIN=/usr/bin/true + # Claude Code sessions log in with what this 0600 file sets, which the + # operator writes: CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, or a proxy's + # ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL. The `-` lets the unit start + # without it, and a Claude Code launch then refuses. + EnvironmentFile=-/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.config/mosaic-dev/secrets/claude-session.env + # The host reads the system config and the business file, boots the broker + # (packages/bus/src/process.mjs) and starts the notifier. Config problems and + # refusals exit 3, usage 4, invalid input 2: none of those is retried. A + # child that dies takes the host down with exit 1, and the unit restarts + # the pair. + ExecStart=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/scripts/mosaic bus start %i + Restart=on-failure + RestartSec=15 + RestartPreventExitStatus=2 3 4 + # `systemctl --user stop` sends SIGTERM to the host, which stops the + # notifier after its poll in flight, then closes the broker. + KillSignal=SIGTERM + KillMode=mixed + TimeoutStopSec=60 + NoNewPrivileges=yes + User=mosaic + Group=mosaic + ProtectSystem=strict + ReadWritePaths=/mnt/storage/scratch/tmp/3LlK4H/case2-unit-jxPM4A/home/mosaic + ProtectHome=yes + PrivateTmp=yes + + [Install] + WantedBy=multi-user.target + + operator: 'match' + stack: |- + TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:976:10) + Test.runInAsyncScope (node:async_hooks:226:14) + Test.run (node:internal/test_runner/test:1402:25) + Test.start (node:internal/test_runner/test:1262:17) + startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) + ... +1..1 +# tests 1 +# suites 0 +# pass 0 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 259.619391 diff --git a/agents/rockerduck/work/queue-334/mutant-exec-source.sha256 b/agents/rockerduck/work/queue-334/mutant-exec-source.sha256 new file mode 100644 index 000000000..d3a69a8a4 --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-exec-source.sha256 @@ -0,0 +1 @@ +5c1dd9b5275023f0a4ad6d75c0d85bfdbea9ceaa7f1ff224b530f6ebf17767c8 packages/cli/systemd/mosaic-proxy.service.in diff --git a/agents/rockerduck/work/queue-334/mutant-exec.diff b/agents/rockerduck/work/queue-334/mutant-exec.diff new file mode 100644 index 000000000..e974e6d9b --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-exec.diff @@ -0,0 +1,13 @@ +diff --git a/packages/cli/systemd/mosaic-proxy.service.in b/packages/cli/systemd/mosaic-proxy.service.in +index d4d67d6b5..71b010867 100644 +--- a/packages/cli/systemd/mosaic-proxy.service.in ++++ b/packages/cli/systemd/mosaic-proxy.service.in +@@ -9,7 +9,7 @@ Type=simple + WorkingDirectory=@REPO@ + Environment=PATH=@PATH@ + @CONFIG_ENV@ +-ExecStart=@NODE@ @REPO@/packages/model-proxy/src/run.mjs ++ExecStart=@REPO@/opt/cli-proxy-api + Restart=on-failure + RestartSec=15 + RestartPreventExitStatus=2 3 4 diff --git a/agents/rockerduck/work/queue-334/mutant-exec.tap b/agents/rockerduck/work/queue-334/mutant-exec.tap new file mode 100644 index 000000000..96d0d8405 --- /dev/null +++ b/agents/rockerduck/work/queue-334/mutant-exec.tap @@ -0,0 +1,36 @@ +# TMPDIR=/mnt/storage/scratch/tmp/JuznlZ HOME=/mnt/storage/scratch/tmp/JuznlZ/home MOSAIC_CONFIG=/mnt/storage/scratch/tmp/JuznlZ/home/.config/mosaic-dev/config.json nice=19 budget=60s +TAP version 13 +# Subtest: row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order +not ok 1 - row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order + --- + duration_ms: 122.755437 + type: 'test' + location: '/home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:966:1' + failureType: 'testCodeFailure' + error: |- + case2-unit: rendered mosaic-proxy.service: ExecStart= must be exactly once in [Service], as ExecStart=/usr/bin/node /mnt/storage/scratch/tmp/JuznlZ/case2-unit-X31DMY/home/mosaic/.local/share/mosaic-stack/copies/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/packages/model-proxy/src/run.mjs + + + 1 !== 0 + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: 0 + actual: 1 + operator: 'strictEqual' + stack: |- + TestContext. (file:///home/jwoltje/.t3/worktrees/mosaic-stack/rockerduck-row334/packages/cli/tests/case2-unit.test.mjs:969:10) + Test.runInAsyncScope (node:async_hooks:226:14) + Test.run (node:internal/test_runner/test:1402:25) + Test.start (node:internal/test_runner/test:1262:17) + startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) + ... +1..1 +# tests 1 +# suites 0 +# pass 0 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 237.081878 diff --git a/agents/rockerduck/work/queue-334/remaining-test-processes.txt b/agents/rockerduck/work/queue-334/remaining-test-processes.txt new file mode 100644 index 000000000..6255799e1 --- /dev/null +++ b/agents/rockerduck/work/queue-334/remaining-test-processes.txt @@ -0,0 +1 @@ +No node --test processes found at 2026-10-26T22:42:35Z (ps search rc1). diff --git a/agents/rockerduck/work/queue-334/restoration.txt b/agents/rockerduck/work/queue-334/restoration.txt new file mode 100644 index 000000000..69b4cb1db --- /dev/null +++ b/agents/rockerduck/work/queue-334/restoration.txt @@ -0,0 +1,6 @@ +scripts/case2-unit.sh: OK +scripts/case2-install.sh: OK +packages/cli/tests/case2-unit.test.mjs: OK +packages/cli/tests/case2-install.test.mjs: OK +packages/cli/systemd/mosaic-proxy.service.in: OK +packages/model-proxy/PIN: OK diff --git a/agents/rockerduck/work/queue-334/restored.tap b/agents/rockerduck/work/queue-334/restored.tap new file mode 100644 index 000000000..5782fd89c --- /dev/null +++ b/agents/rockerduck/work/queue-334/restored.tap @@ -0,0 +1,23 @@ +# TMPDIR=/mnt/storage/scratch/tmp/ayiWpX HOME=/mnt/storage/scratch/tmp/ayiWpX/home MOSAIC_CONFIG=/mnt/storage/scratch/tmp/ayiWpX/home/.config/mosaic-dev/config.json nice=19 budget=60s +TAP version 13 +# Subtest: row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order +ok 1 - row334 proxy uses P1 runner, bus dependencies and proxy bus Console start order + --- + duration_ms: 143.930692 + type: 'test' + ... +# Subtest: row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status +ok 2 - row334 rendered ExecStart refuses wrong PIN and missing proxy with P1 status + --- + duration_ms: 308.811879 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 569.147722 diff --git a/docs/SESSIONS.md b/docs/SESSIONS.md index 4961089a1..aab7bc3ba 100644 --- a/docs/SESSIONS.md +++ b/docs/SESSIONS.md @@ -1882,3 +1882,4 @@ are never rewritten or removed; corrections are new entries. 2026-10-25 — rockerduck — row334 (#1832), Case 2 proxy system unit — design/read phase; tests held for Sage CLEAR; queue start lock diagnosed. 2026-10-25 — rockerduck — row334 (#1832), Case 2 proxy system unit — queue start rev4079; tests then implementation written, design accepted by Sage; verification held for CLEAR, P2 refusal-code check pending row331. 2026-10-25 — rockerduck — row334 RED-only slot sage-4387 — both whole files against pre-change scripts: 74 older tests pass, 34 new expected failures; implementations restored, slot returned; GREEN/mutants held. +2026-10-26 — rockerduck — row334 Mos1961 targeted serial slot — integrated 09a847eda, whole files 81+28 pass, two mutants killed/restored 2 pass; old RED preserved, test roots removed, SLOTBACK; no push/live action/review dispatch.