Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94ab4c2fe6 | ||
|
|
81e037d20d | ||
|
|
47148991b4 |
@@ -5177,39 +5177,3 @@ Before: managed project/thread verbs had no Console conversation area. After: fi
|
||||
2026-10-21T01:28:05Z | Darkwing | row 232 #1734 installer I1 build, round 1 in review | Before: stack-release.sh managed only user units (systemctl --user), and stack-copy.sh had no bundle copy. After: --units external (adopt, activate, rollback --to, status, confirm, revert, gate --since, AWAITING-UNITS, stale-start, external-pm, --plan --expect-from) and stack-copy check --units external, copy --bundle FILE SHA, wrapper ID --create; user mode byte-identical to the base by test. First build 0af0c73c6 on 00d4cc1f6; rebased onto row 200 (cb5fdb064) as a0ffabc3f on darkwing/row232-r1; --sso refused under external (D9), row 200 config_checks run under external (D10). Gate on Sage's slot (sage-1618): cli 561/0, every scripts/test-*.sh green; 17/17 mutants killed. Results commit 84f1a91e6 (pushed, seat branch only). Manifest 7a3b4ea1 (9 paths), queue revs 2595-2596, request comment 29825, reviewer Filbert. Packet agents/darkwing/work/queue-232/BUILD.md.
|
||||
2026-10-21T04:50:44Z | Darkwing | row 233 #1735 installer I3 build, round 1 in review | Before: root had no upgrade driver for root-owned units and no host run sheet; stack-release.sh had no rehearse --backup last and no external plan refusals. After: scripts/stack-upgrade.sh upgrade and rollback (r6 A1-A5, A2f, R1-R4) with 20 tests, docs/guides/host-run-sheet.md, TOOLS.md lines, and on Sage's rulings stack-release.sh --backup last, BACKUP_STORE and the --plan refusals open-activation and migrate-required (3 tests). Base e65a3ab4d (row 232's landing). Gate on Sage's slot (sage-1704) on d99166ade: cli 616/0, every scripts/test-*.sh green, 1201/0 summed by awk; m1-m8 8/8 killed. Correction: the process sweep after the gate found an orphaned sleep 60 from the lock test's flock holder (N1); 08db6ac3f fixes it test only, Sage ruled the gate stands (sage-1707), rerun c0 20/0 and m1 killed with 0 left (sage-1708). Tip 1a1dc80ca (pushed, seat branch only). Manifest 464ce9eb (7 paths), queue revs 2644 and 2647, request comment 29901, reviewer Filbert. Packet agents/darkwing/work/queue-233/BUILD.md.
|
||||
2026-10-21T06:37:41Z | Darkwing | row 240 #1746 installer I4 build, round 1 in review | Before: root had no host check for the bwrap AppArmor profile, its pins or a boot unit, and stack-upgrade.sh exited 1 args-failed when the args move after A5 failed, while exit 1 means the old copy runs. After: scripts/case1-hostcheck.sh (seven items, --check, --enforce, --upstream), scripts/case1-pins.sh, mosaic-hostcheck.service and 16 tests; the args move failure exits 5 args-failed, documented in TOOLS.md and run sheet section 6 and tested; run sheet section 3 puts the pinned npm on PATH and names the bin/claude.exe --claude path; sections 8 and 10 have precheck lines. Verification: slot run r1 on 47ec9fe2f failed at the singles (the new N1 test's after hook threw ENOENT after the fixture cleanup removed the root); b45852daa drops the hook; r2 on b45852daa green: singles 16/0 and 21/0, c0 plus M1-M8 8/8 killed, cli 639/0, scripts 585/0. Candidate darkwing/row240-r3 ad1b23ab2 on c771a36f4, manifest 573ece95 (9 paths), revs 2694 and 2695, comment 29943.
|
||||
2026-10-21T09:00Z | Herb | row 215 C2-04 implementation started | Before: business files reject library entries and root consumers assume code projects; the organization writer can change all project mappings. Plan: approved manifest 2522025af on C2-01 a2c72ac95, Filbert reply to herb-0056, scope sage-1848/1852/1860. Focused slot sage-1869 observed expected red mapping and M9 cases, then 14/0 green for new T1/T2 cases, no skips; clear herb-0062 with empty test/fixture process scan. After that clear, T3/T4 tests and host-only mirror/bus implementation continue under sage-1874, unrun while Sage holds the slot. Full singles, suites and implementation review remain pending. No source commit, push or live change.
|
||||
2026-10-21T13:29Z | Herb | row 215 C2-04 source verified for candidate review | Before: business code assumed every project had a root and organization writes could replace project mappings. After: library mappings load without agent checkouts or publish grants, project mappings are protected before and after serialization, host-only bare mirrors share a bounded publication lock with sync, and library.file/library.status are human-only async bus reads. Base f8276c5eb preserves all nine landed overlaps. Granted sage-2008 whole singles: 16 files, 451/0, no skips or cancellations, ended 13:27:27.279728Z; all source hashes unchanged, process scan empty, no own-path drift through 8a04f4aa4. Full landing gate and implementation review remain pending; no HTTP, sync writer or live change.
|
||||
|
||||
2026-10-20 19:09:44 UTC | Gander row 196 #1694 design phase | Before: tester TCP reaches every local uid and human proofs do not bind the socket peer. After: design draft at agents/gander/work/queue-196/DESIGN.md inventories listeners, proposes private tester HTTP and SO_PEERCRED binding, aligns the per-request principal contract with Morgana and Gizmoduck, and lists migration, tests, mutants and same-uid limits. Python versus other credential options and Console provenance require Duckworth ruling. Documentation only. No product code, suite, live probe, secret access or deployment.
|
||||
|
||||
2026-10-20 19:16:20 UTC | Gander row 196 #1694 design r2 | Before: Duckworth r1 requested concurrent helper-fd evidence (B1) and selected O1 with interpreter, proof-only and image conditions. After: design adds eight concurrent genuine proof processes plus a racing copier, M20 swapped socket and post-helper socket survival, root-owned system ELF pinning and activation evidence, safe gid validation, cap traffic without helpers, and unchanged P19 R2 text. Mos accepted socket-only tester access (mos-1015 via sage-1363); any authenticated browser relay is a separate row. Documentation coverage checks passed. No product code, suites or live action.
|
||||
|
||||
2026-10-20 19:21:19 UTC | Gander row 196 #1694 design approval and N5 | Before: Duckworth approved r2 (duckworth-0009, cb6d840df) with a nonblocking interpreter-upgrade note. After: r3 chooses startup safety revalidation, appends actual interpreter identity to bus/peercred-starts.jsonl and retains old activation evidence. Operator re-pin uses the next reviewed copy, respecting already-active refusal. Added task-by-task PLAN.md for inline implementation and independent manifest review. Documentation checks passed. No product code, suites or live action.
|
||||
|
||||
2026-10-20 19:34:28 UTC | Gander row 196 build paused at design mismatch | Before: approved design promised Unix tester cleanup only for the owned inode. After: scratch test shows Node/libuv close unlinks a replacement inode before JS close handlers. Evidence agents/gander/work/queue-196/evidence/tester-cleanup-blocker.txt. Sent Sage/Duckworth gander-0016/0017, recommending explicit same-uid residual with private 0700 parent retained. Interpreter, concurrent peer, principal, human, peer-transport, transport, tester and process single files passed. Partial code uncommitted, tester transport not wired. No suites, mutant batches or live actions.
|
||||
|
||||
2026-10-21 18:45 UTC | Gander row 196 preservation before rebase | Sage-2051, Mos order mos-1193, explicitly authorizes commit and fast-forward push of the current build before deferred full verification. Product and evidence preserved together; prior focused checks and stopped gates are recorded in the row196 packet, with no claim of full acceptance. Next: rebase onto a36523713 on new gander/row196-r2, report range-diff/patch-id/conflicts, then await Sage's clear for M1-M29 and all requested suites. No live action, force push, branch deletion or tests during hold.
|
||||
|
||||
2026-10-21T16:34:44Z | Huey | Q198/Q199 system-manager design, mos-1183, Vikunja 452 | Before: pinned foundation 6c75887b0 has separate bus, development queue, run evidence, turn/cohort controls and launch/usage paths; the assignment requests a mechanical manager design. After: docs/plans/2026-10-21_q198-system-manager.md proposes admission/cooldown, priority and safe interruption, durable requests, bounded retry/DLQ/replay/rerouting, Console monitoring, optional decision adapters with USD reservations, six ordered slices and three recommended owner decisions. Verification: 26 pinned file:line references resolve, ten-line summary, manual source/contract review, git diff --check and installed queue guard pass. No builds/suites, runtime writes, credential reads, service changes or paid calls. Huey queue next refused the linked worktree, then returned nothing from canonical checkout; direct brief controls this assignment. Gitea issue and queue-row capture are handed to Sage under the no-credential-read/no-queue-write boundary.
|
||||
|
||||
2026-10-21T18:45:47Z | Huey | Q198 system-manager design r2, mos-1194, Vikunja 452 | Before: Scrooge requested changes on add7cb506 for decision-key worker exposure, cap scope and absent sampler ownership. After: distinct MOSAIC_DECISION_OPENROUTER_KEY with S6 sessionEnv canary requirement; exclusive per-instance key with per-key caps and provider limit on every enablement; S2 owns supervisor sampler and waits until after MVP/re-pin. Also records P1 interpretation, missing-confidence fallback and stand-in timeout selection, explains verified Noul spelling, excludes notifier/gateway retry loops with citations, and cites lifecycle revocation requirement. Verification: 30 pinned citation spans resolve, ten-line summary, manual diff/source review and whitespace/queue-guard checks. No builds, suites, live changes, credential reads or paid calls.
|
||||
|
||||
2026-10-21T19:56:11Z | Huey | Q198 design r3, mos-1201/1201a, Vikunja 452 | Before: Scrooge approved r2 7e785a08f with three notes. After: N1 names proposed system.health bus read verb and includes broker handler/authorization in S2 scope and review; N2 labels exclusive ownership as a setup attestation that cannot be mechanically proved and identifies provider key limit as real ceiling; N3 adds recommended Q4 for P1 narrowing and removes the Mos-flag instruction. Other design content retained. Verification: manual r2-to-r3 delta review, ten-line summary, whitespace and installed queue-guard checks. No builds, suites, live changes or paid calls.
|
||||
|
||||
2026-10-21T20:19:53Z | Huey | Q198 design r4, mos-1203, DECISIONS Q204, Vikunja 452 | Before: r3 a36952564 presented Q1–Q4 for owner approval. After: section 9 records Q20a–Q20c verbatim as approved; D11 labels Huey’s reading of configurable daily/monthly caps with $0.10/$1 defaults in the one instance config via reviewed schema; provider key ceiling and explicit enable/key requirements retained; Q4 pending, Jason restated 2026-10-21, P1 unchanged. Verification: quotes match DECISIONS ledger, unrelated sections and P1 equal r3, ten-line summary, whitespace and installed queue guard checked. No builds, suites, live changes or paid calls.
|
||||
|
||||
2026-10-21T20:48:49Z | Huey | Q198 design r5, mos-1206, DECISIONS Q205/Q206, Vikunja 452 | Before: r4 1e8bccff1 left Q4 pending and long outages could exhaust request retry budgets. After: protected mode separate from unchanged D1 human kill authority; mechanical detection, safe-point pause/proof, JEV-first endpoint-before-headless probes at 60-second increments to 600 seconds without attempt limit, upstream reset waits, shared D11 probe accounting, one test session then batches, proposed three-failed-exit escalation, frozen outage clocks/counters without DLQ, advisory online-service routing, Q4 superseded and Q22 pending. Thresholds/deadlines/batches/escalation explicitly labelled Huey readings. Acceptance proposals updated, no implementation. Verification: complete Q205/Q206 read, quotes match ledger, D1/inventory/Q1–Q3 unchanged, 30 pinned citation references resolve, 11-line summary, manual consistency/diff review, whitespace and installed queue guard checked. No builds, suites, real probes, live changes or paid calls.
|
||||
|
||||
2026-10-21T21:04:37Z | Huey | Q198 design r6, mos-1208/mos-1210, DECISIONS Q207, scrooge-0003, Vikunja 452 | Before: r5 fd44f7c60 gated probes on JEV and lacked request-local resume failure separation. After: parallel independent probes; central JEV/smaller-model/rules endpoint chain, per-model timeout/calibration, 4 KiB metadata limit and isolated fallback credentials; subscription quota vs metered USD accounting and separately enabled paid-probe budget (proposed $0 defaults). S-F1–S-F7: bounded outage classification, request-local D6/two-resume DLQ rule and batch definition; escalation latch with authorized revision-bound system.recovery.release separate from kill clear; cooperative F5 pause/F6 proof only; proposed configurable 24-hour cumulative pause expiry; full Q205 kill sentence with labelled protected-mode interpretation; r3–r6 history. S5/S6 acceptance proposals updated. Verification: Q205/Q207 quotes match ledger, D1/inventory/Q1–Q3 unchanged, 30 pinned references resolve, summary within 15 lines, manual consistency/delta review, whitespace and installed queue guard checked. No builds, suites, real probes, live changes, credential reads or paid calls.
|
||||
|
||||
2026-10-21T21:39:25Z | Huey | Q198 r6.1 touch-up, mos-1222, scrooge-0004 N1–N3, Vikunja 452 | Before: approved r6 2ee68cd69 had unprovable session-call denial wording, implicit queue/late-call behavior and a partial Q207 paragraph. After: rule/S6 tests require session decision calls/output have no routing authority; non-waiting dispatchers use internal rules immediately; timed-out JEV does not occupy fallback decision slot but retains spend reservation; full Q207 paragraph copied exactly from DECISIONS; matching Q22 reading corrected. ENV_ALLOW and all runtime code unchanged. Verification: exact full-quote equality, obsolete wording absent, D1 unchanged, summary within 15 lines, manual N1–N3 delta review, whitespace and installed queue guard checked. No builds, suites, probes, live changes or paid calls. Review/handoff via T3 as Mos authorized.
|
||||
|
||||
2026-10-21T21:11:44Z | Della mos-1213 / Vikunja 460 planning phase | Before: PRD 1.10 has no email feature; MP 95b0298 and EP 7a64921 are read-only prior inputs. Scope: independent post-v1 email plan on della/email-plan, no implementation/live access/MVP or queue changes. Gitea issue enrollment belongs to Mos/Sage because this seat has no API credential.
|
||||
|
||||
2026-10-21T21:12:18Z | Della mos-1213 / Vikunja 460 planning verification | After: docs/plans/2026-10-21_email-plan-della.md is 341 lines, with 13 post-v1 rows and six Jason questions. Verified 42 pinned citation anchors, ten requested coverage areas, identical prior src trees, append-only records, clean whitespace and repository queue guard. No configured CI pipeline or CI-queue wrapper found in the current foundation; documentation-only validation applies, no product suites or live tests run. Phase B/C and Gitea issue/queue enrollment remain with Mos/Sage. Only della/email-plan is authorized for push.
|
||||
|
||||
2026-10-21T21:37:07Z | Della mos-1220 / Vikunja 460 phase B cross-review | Before: independent plans Della 191dff32f and Ludwig 4a27b73ac delivered. After: docs/plans/2026-10-21_email-review-by-della.md reviews all 218 Ludwig plan lines, records ten findings, five grafts, six retained strengths, nine disagreements and eleven merged Jason questions. Ludwig review 143415779 read in full after ludwig-0002 arrived; reconciliation records new mail-access action, no agent reroute and correction of Della dataRoot credential example. Original plan unchanged. Planning only, no product/MVP/queue/live change.
|
||||
|
||||
2026-10-21T21:43:02Z | Della mos-1223 / Vikunja 460 phase C synthesis | Before: independent plans/reviews complete, Mos selected Della base. After: docs/plans/2026-10-21_email-plan.md merges Ludwig grafts and accepted corrections, with 16 post-v1 rows (eight READY, eight WAIT/optional), eleven deduplicated Jason questions, per-row test paths and explicit Q210 non-v1 scheduling. Original Della plan/review preserved; Ludwig originals remain on their branch. Static checks cover graft/row/question/citation anchors and original blobs. No source code, suite, mailbox, secret file, service, MVP or queue change. Candidate goes to Ludwig before Sage landing/queue handoff, copying Mos.
|
||||
|
||||
2026-10-21T21:45:20Z | Della mos-1223 / ludwig-0004 focused corrections | Before: b096a16cc left content-key location implicit and E05 core registration marked ready. After: merged plan 399 lines fixes external configDir secret key/lifecycle namespace outside dataRoot backup/restore, E01 schema and E03 missing/expired-key restore tests, and E05/E06 test-local registry readiness with core kinds.mjs registration gated on approved E01/Q4. Sixteen rows and eleven questions retained; originals unchanged. Focused static checks and queue guard apply, no product/live changes. Reviewer will check changed lines only.
|
||||
|
||||
+1
-17
@@ -75,8 +75,7 @@ session's workspace and its own process group. Same contract, plus:
|
||||
| `MOSAIC_POLICY_FILE`, `MOSAIC_TOOLS_FILE` | The bundle's gate policy and typed tools. |
|
||||
| `MOSAIC_TOOL_SOCKET` | The runner's tool socket, which the typed tools call. |
|
||||
| `MOSAIC_TURN_MARKER` | `pi`: the extension writes it at `agent_end`; a pi turn that exits 0 without it failed. |
|
||||
| `MOSAIC_EXTENSIONS` | `pi` only: extension files loaded with `-e`; a missing one exits 2. The pi module names two: the gate and typed tools extension, then the unslop check's `tools/unslop-hook/extension.ts` (row 66). |
|
||||
| `MOSAIC_UNSLOP_LOG` | The unslop check's JSONL log, `<run>/unslop.jsonl`, which the runner sets for both adapters and reads after each turn (row 66). |
|
||||
| `MOSAIC_EXTENSIONS` | `pi` only: extension files loaded with `-e`; a missing one exits 2. |
|
||||
| `MOSAIC_CLAUDE_SETTINGS`, `MOSAIC_CLAUDE_MCP_CONFIG` | `claude` only: the bundle's gate hook and MCP server; required. |
|
||||
| `MOSAIC_THINKING` | The route's thinking level (row 65), which the harness module's `levels()` already checked. `pi` passes `--thinking` (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`) and omits it when unset, as for `run-task.sh` workers. `claude` passes `--effort` (`low`, `medium`, `high`, `xhigh`, `max`) and requires it; unset exits 2. |
|
||||
| `MOSAIC_CLAUDE_BIN` | `claude` only: absolute path of the CLI to run, from the host's environment (the bus unit pins it). Unset or empty runs `claude` from `PATH`; a relative path or a non-executable file exits 2. |
|
||||
@@ -111,18 +110,3 @@ argument, which Linux caps at 128 KiB; row 213 passes the file instead, so no
|
||||
local user reads the prompt in `/proc/<pid>/cmdline`. Pi 0.85.1 uses the path
|
||||
string itself as the prompt when the file is missing or can't be read, so the
|
||||
pi adapter exits 2 unless the path is a readable regular file.
|
||||
|
||||
### The unslop check (row 66)
|
||||
|
||||
Both adapters run the mechanical writing check from `tools/unslop-hook`,
|
||||
driven by one `lists.json`. `pi` loads it as its second `-e` extension.
|
||||
`claude` runs `claude-hook.js` from the bundle's `settings.json`: the Stop
|
||||
hook checks the turn's replies, and the UserPromptSubmit hook adds the
|
||||
correction notice as context on the next turn when the last reply had
|
||||
tells. Each hook command ends `; exit 0`, so neither blocks. Both log to
|
||||
`MOSAIC_UNSLOP_LOG`, and the runner adds a note for the operator to the
|
||||
next RESULT it sends (`packages/harness/README.md`, the runner). The
|
||||
harness modules mount the three files read-only at their own paths, and
|
||||
the manifest records their digests. `MOSAIC_UNSLOP_HOOK` and `UNSLOP_LISTS`
|
||||
aren't in the session environment's allowlist, so a managed session can't
|
||||
switch the check off or swap its lists.
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
# Row 251 build: T27 lists no identities right after `ssh-add -t 1` (Vikunja #453)
|
||||
|
||||
Brief `docs/plans/2026-10-21_t27-ssh-add-lifetime.md` (rev 2931), Mos ruling mos-1185 item 2, assigned in
|
||||
sage-2075. Owner Darkwing, reviewer Dewey, gate owner Sage. Branch `darkwing/row251` from 3b0aef995,
|
||||
claimed in-progress at rev 2938.
|
||||
|
||||
## Step 1: the failure names its cause (e5e4b2e5a)
|
||||
|
||||
T27's two lists now carry a message that prints only when they fail. It gives the time from addKey's
|
||||
start to its resolve and to each `ssh-add -l` call, the hrtime at each with how far into its second it
|
||||
fell, `/proc/uptime` at each, and whether the agent process and its socket were still there. The checks
|
||||
themselves did not change. The commit holds nothing else.
|
||||
|
||||
## Step 2: the cause
|
||||
|
||||
ssh-agent counts a key's lifetime in whole seconds of CLOCK_BOOTTIME, at the add and at the reap. I read
|
||||
OpenSSH 10.5p1, the version on dragon-lin (`ssh -V`: OpenSSH_10.5p1), at tag V_10_5_P1 (ssh-agent.c
|
||||
sha256 873691c4, misc.c sha256 ee467f43):
|
||||
|
||||
- `misc.c:1790-1798` and `:1828`: `monotime()` returns `ts.tv_sec` of `clock_gettime(CLOCK_BOOTTIME)`,
|
||||
falling back to MONOTONIC. The fraction of the second is dropped.
|
||||
- `ssh-agent.c:1315`: the `-t` constraint sets `*deathp = monotime() + seconds`. Lines 1410 and 1598
|
||||
do the same for the agent's default lifetime.
|
||||
- `ssh-agent.c:1064`: the reaper drops a key when `now >= id->death`, `now` being `monotime()` again.
|
||||
- `ssh-agent.c:2650`: the main loop runs `reaper()` after every poll, before it reads requests. A list
|
||||
that arrives after the boundary sees the key gone.
|
||||
|
||||
So a key added at second s plus a fraction f dies at s + N, and `-t N` keeps it N - f seconds, between
|
||||
N - 1 and N. With `-t 1`, an add late in a second leaves the key milliseconds to live. That matches
|
||||
Sage's probe in the brief: 8 of 80 `-t 1` adds missed, each one made at 0.9947-0.9973 of a monotonic
|
||||
second and finished at 0.998-0.0008, and none earlier in the second missed. It also matches proof 5's
|
||||
failure, where the first list ran 31.9 ms into the test and found no identities.
|
||||
|
||||
Node's hrtime is CLOCK_MONOTONIC. BOOTTIME differs from it by the time the host spent suspended. On
|
||||
dragon-lin the difference read 0.000001 s at 19:09Z, so a monotonic second boundary is a BOOTTIME one
|
||||
here.
|
||||
|
||||
`addKey` and the agent start are not the cause. `addKey` passes the lifetime through as `-t`
|
||||
(`host-run.mjs:90`), and the agent starts with no default lifetime (`:175`). Production adds the key
|
||||
with `timeout + 30` (`:180`), where losing up to a second makes no difference. The only caller that
|
||||
can't afford the lost fraction is T27, which asks for 1 s. The fix belongs in the test's lifetime choice,
|
||||
and `host-run.mjs` doesn't change.
|
||||
|
||||
The slot confirms this against T27 itself (below), not just from the source.
|
||||
|
||||
## Step 3: the fix (this commit)
|
||||
|
||||
T27 adds the key with `-t 2`. The agent then keeps it more than 1 s and at most 2 s. The first list
|
||||
runs milliseconds after the add, so it has over a second of margin even under load. The sleep before
|
||||
the second list grows from 2.5 s to 3.5 s, which keeps the old 1.5 s margin past the new 2 s ceiling.
|
||||
Both checks stay: listed after the add, gone after the lifetime. A comment above the add says why the
|
||||
lifetime is 2.
|
||||
|
||||
I considered `-t 3` with a 4.5 s sleep for a 2 s floor. One second of floor is far above anything the
|
||||
first list has needed (31.9 ms in proof 5), and the concurrent-suite run below tests it under load, so I
|
||||
took the smaller change.
|
||||
|
||||
## Base
|
||||
|
||||
The branch stays on 3b0aef995. By 19:15Z origin/refactor was at 6096b051b, after rows 66 and 243
|
||||
landed. `git diff 3b0aef995 6096b051b` touches neither `packages/bus/src/host-run.mjs` nor
|
||||
`packages/bus/tests/host-run.test.mjs`, so there's no rebase (sage-2084). Row 243 did change
|
||||
`packages/bus/tests/process.test.mjs`. My slot's bus suites run that file as it was at 3b0aef995, and the
|
||||
gate rerun on Sage's slot runs it as landed.
|
||||
|
||||
## Prediction for part A on e5e4b2e5a (written before the slot)
|
||||
|
||||
The hook starts `ssh-add -t 1` at the given fraction of a monotonic second. From the brief's probe, the
|
||||
agent stores the key about 3 ms later. The first list reaches the agent a few ms after addKey resolves:
|
||||
Node's exit event, the mark, and `ssh-add -l`'s own start. A red needs the add to land before the second
|
||||
boundary and the list to land after it.
|
||||
|
||||
- 0.990: green. The add and the list both land before the boundary.
|
||||
- 0.993, 0.995, 0.996, 0.997: red expected. The add lands before the boundary, the list after. At 0.993
|
||||
and 0.997 I'm less sure, because the list (at 0.993) or the add (at 0.997) can land right at the
|
||||
boundary. A green at either is in line with the cause, and so is a red.
|
||||
- 0.998: green. The add lands after the boundary, so the key gets almost a full second.
|
||||
|
||||
Every red should show "first list got" an answer with no SHA256 line. It should also show addKey
|
||||
resolving before a second boundary and the first list starting after it or within a few ms of it, with
|
||||
the agent alive and its socket present.
|
||||
|
||||
Under sage-2084's rule, on e5e4b2e5a only a red at 0.990 or 0.998 counts toward the stop, and two such
|
||||
reds stop the run. On the fix commit any red counts, and two stop it. In parts B to D, the first red stops
|
||||
the run.
|
||||
|
||||
## Slot plan
|
||||
|
||||
All scripts are in `/mnt/storage/scratch/darkwing-251-out/`, launched from `/`, each behind the busy
|
||||
checks and chained with `&&`, TMPDIR under `/mnt/storage/scratch/tmp`.
|
||||
|
||||
1. Confirmation. `align-hooks.mjs` is a load hook, outside the repo, that serves `host-run.mjs` with
|
||||
`addKey` wrapped to start `ssh-add` at a chosen fraction of a monotonic second. T27 runs unchanged
|
||||
under it, alone (`--test-name-pattern`). It runs at fractions 0.990, 0.993, 0.995, 0.996, 0.997 and
|
||||
0.998, three times each:
|
||||
- on e5e4b2e5a (step 1, `-t 1`). Expected: some first lists fail, and the step 1 message shows the
|
||||
add's resolve and the list on either side of a second boundary, with the agent alive and the
|
||||
socket present. These reds are the point of the run.
|
||||
- on the fix commit (`-t 2`). Expected: all 18 pass.
|
||||
2. `host-run.test.mjs` whole, once, on the fix commit.
|
||||
3. The bus suite whole, three times in a row.
|
||||
4. The bus suite whole in two clean worktrees at the same commit, started together.
|
||||
|
||||
## Slot results
|
||||
|
||||
Sage's CLEAR came in sage-2154 at 20:58:55Z. `slot-251.sh` ran parts A and B from 20:59:22Z to 21:01:33Z,
|
||||
on node v26.8.1 and OpenSSH_10.5p1, with TMPDIR `/mnt/storage/scratch/tmp/r251`. At the start, BOOTTIME
|
||||
minus MONOTONIC read 0.000001 s, then 0.000000 s twice (dewey-0769 N1). So the hrtime fractions below
|
||||
put the agent's second boundary in the right place.
|
||||
|
||||
### Part A: T27 alone under `align-hooks.mjs`, 3 runs per fraction
|
||||
|
||||
The fraction is when the hook started `ssh-add`. The hook logged each start within 0.0001 of its target.
|
||||
|
||||
| fraction | e5e4b2e5a (`-t 1`) | 68f2dfd4b (`-t 2`) |
|
||||
|---|---|---|
|
||||
| 0.990 | 3 pass | 3 pass |
|
||||
| 0.993 | 3 pass | 3 pass |
|
||||
| 0.995 | 3 red | 3 pass |
|
||||
| 0.996 | 3 red | 3 pass |
|
||||
| 0.997 | 3 pass | 3 pass |
|
||||
| 0.998 | 3 pass | 3 pass |
|
||||
|
||||
e5e4b2e5a went red 6 times out of 18, every time at a fraction the prediction named, so none of them
|
||||
counted toward the stop. 68f2dfd4b passed all 18. The fix runs used 68f2dfd4b, whose test blob is the same
|
||||
as c19b4167e's (280132c7).
|
||||
|
||||
Every red failed on the first list and got `"The agent has no identities.\n"`, with the agent alive and
|
||||
its socket present. The step 1 message gave these hrtime fractions. "addKey start" is the mark before the
|
||||
hook's wait, so its fraction is earlier than the ssh-add start.
|
||||
|
||||
| run | addKey resolved | first list mark |
|
||||
|---|---|---|
|
||||
| 0.995 rep 1 | 0.9992 (+317.6 ms) | 0.9993 |
|
||||
| 0.995 rep 2 | 0.9991 (+846.5 ms) | 0.9991 |
|
||||
| 0.995 rep 3 | 0.9988 (+845.0 ms) | 0.9988 |
|
||||
| 0.996 rep 1 | 0.9999 (+839.8 ms) | 1.0000 |
|
||||
| 0.996 rep 2 | 0.0004 (+845.0 ms) | 0.0004 |
|
||||
| 0.996 rep 3 | 0.0002 (+835.9 ms) | 0.0002 |
|
||||
|
||||
At 0.995 the add finished about 4 ms in, before the boundary, and the list mark came just before it. The
|
||||
`ssh-add -l` process then reached the agent after the boundary. At 0.996 the agent stored the key before
|
||||
the boundary, and addKey resolved just after it. In both cases the key's whole second ended between the
|
||||
add and the list, which is the cause step 2 gives. The two edge fractions came out green on the first
|
||||
build. At 0.993 the list still reached the agent before the boundary, and at 0.997 the add landed after
|
||||
it, so the key got almost a full second. The prediction allowed either result at those two.
|
||||
|
||||
### Part B: `host-run.test.mjs` whole on 68f2dfd4b
|
||||
|
||||
24 tests, 24 passed (21:01:18Z, 14.0 s).
|
||||
|
||||
### The stop before C1, and the resume
|
||||
|
||||
At 21:01:33Z the script stopped before C1, with exit 4 and no red. My own `busy.sh` matched two `sleep 60`
|
||||
processes, mine, in `darkwing-r251/packages/bus`. Part B left them. They come from T27 "the start sweep
|
||||
keeps a live bus dir and kills only a matching live process" (`host-run.test.mjs:528` and `:536`). Its
|
||||
`t.after` SIGKILLs the `/bin/sh -c 'sleep 60; :'` parent, but the `sleep` child lives on for up to 60 s.
|
||||
That code is outside this row's diff, so the row leaves it alone, and it's recorded below as a follow-up.
|
||||
Sage confirmed (sage-2159) that the right move is to resume only the scope that hadn't run.
|
||||
|
||||
`slot-251-cd.sh` runs C and D as `slot-251.sh` has them, with the same two busy checks. Before each check,
|
||||
it waits up to 75 s for those orphans to exit: my uid, my trees, a command line of exactly `sleep 60`.
|
||||
It logs them as it waits. Any other process still trips the checks.
|
||||
|
||||
### Parts C and D: the bus suite whole on 68f2dfd4b
|
||||
|
||||
| run | start | tests | pass | fail | time |
|
||||
|---|---|---|---|---|---|
|
||||
| C1 | 21:02:48Z | 598 | 598 | 0 | 21.6 s |
|
||||
| C2 | 21:04:06Z | 598 | 598 | 0 | 21.4 s |
|
||||
| C3 | 21:05:26Z | 598 | 598 | 0 | 22.1 s |
|
||||
| D1, darkwing-r251 | 21:06:44Z | 598 | 598 | 0 | 24.2 s |
|
||||
| D2, darkwing-r251b, TMPDIR `r251-b` | 21:06:44Z | 598 | 598 | 0 | 24.2 s |
|
||||
|
||||
The script waited 33 s before C2, 34 s before C3, 33 s before D and 32 s before the sweep. Each time it
|
||||
was waiting for that run's `sleep 60` orphans (two per suite, four after D), and nothing else. After the
|
||||
wait, the sweep of my trees, the out dir and TMPDIR found 0 processes left (21:08:04Z). Sage confirmed
|
||||
(sage-2159, sage-2160) that the short gitea-api and `node --check` runs they made during the slot weren't
|
||||
stops. None of my busy checks refused on any of them.
|
||||
|
||||
These runs used the bus files as they were at 3b0aef995. Since then, origin/refactor (666173292, then
|
||||
7247d80c7 and c3d88840c with row 196) has changed `broker.mjs`, `runtime.mjs` and `server.mjs`, which T27's
|
||||
file imports, along with other bus files. None of those commits touch this row's two paths or
|
||||
`host-run.mjs`, and `git merge-tree` of c3d88840c with 68f2dfd4b is clean. The gate rerun in
|
||||
a clean worktree on Sage's slot runs T27 against them.
|
||||
|
||||
### Follow-up, not in this row
|
||||
|
||||
T27's start-sweep test leaves the `sleep 60` child of each planted shell running for up to 60 s after
|
||||
the test. Killing the process group (`process.kill(-pid)`; both shells are spawned `detached`) or
|
||||
`exec sleep 60` in the shell would end the child along with its parent.
|
||||
@@ -1,100 +0,0 @@
|
||||
# Row 250 build notes (Gizmoduck)
|
||||
|
||||
Vikunja #450, Mos ruling mos-1182 item 3. Brief: docs/plans/2026-10-21_k12-cohort-events.md. Reviewer
|
||||
Filbert, gate owner Sage. Branch gizmoduck/row250 from origin/refactor 3b0aef995. Line numbers below are on
|
||||
this branch unless a commit is named.
|
||||
|
||||
## Step 1
|
||||
|
||||
cbba6ff07 changes only the K12 assertion (packages/conversation/tests/cohort.test.mjs:292 on 3b0aef995).
|
||||
On failure it prints the shim's answer, with `ok` and `unavailable`, and `h.ctrl.evidence.releases`.
|
||||
|
||||
## Step 2: the cause
|
||||
|
||||
K12 reads the shim after the controller has started to release it.
|
||||
|
||||
- The force stop sets the binding `stopped` (packages/conversation/src/controller.mjs:1615). Then it pauses at
|
||||
`scope-release` (:1623) and calls `#releaseScope` (:1624).
|
||||
- `#releaseScope` calls `releaseCohort` (:1639). That sends `hello`, then `release`
|
||||
(packages/conversation/src/cohort.mjs:261-265).
|
||||
- The shim answers `release` and exits 10 ms later. It unlinks its socket first (shim.mjs:165-176). systemd
|
||||
then collects the empty scope, `engine` included.
|
||||
- K12's `forceStop` helper returns once it sees `stopped` (cohort.test.mjs:148, polling every 10 ms). The
|
||||
test then reads `engine/cgroup.freeze` (:281 on 3b0aef995) and asks the shim for `events` (:291).
|
||||
|
||||
Nothing in K12 orders those reads before the release. Unloaded, the test usually sends its `events` request
|
||||
within the 10 ms before the shim exits, so it passes. Under load the release wins. `shimRequest` then
|
||||
returns `{ ok: false, unavailable: "the shim socket is gone" }` (cohort.mjs:46), or "unreachable" or
|
||||
"closed the connection" (:62-63), and `ev.populated` is undefined. Both recorded failures fit this
|
||||
pattern:
|
||||
|
||||
- Row 197 proof 4, pair1-b: K12 failed in 339 ms on `undefined !== 0` at :292. 339 ms is far below the
|
||||
3 s `shimRequest` timeout (cohort.mjs:56), so the request didn't time out. The `cgroup.freeze` read at
|
||||
:281 passed, so the scope still existed then.
|
||||
- BUILD-LOG.md:4092, row 56's gate: "`populated` undefined with load around 12".
|
||||
|
||||
Row 50 (a9cc522a0, #1536) added the release after a proven stop. K12 is older. Its comment still says
|
||||
"the shim holds the scope", and that stopped being true in row 50. E1 (cohort.test.mjs:923-925) already
|
||||
holds `scope-release` so it can read the shim while the shim still answers. K12 never got the hold. No
|
||||
other test reads the shim after a proven stop and expects an answer. R1 expects the shim gone, R3 is an
|
||||
uncertain stop, and K15 reads before its stop.
|
||||
|
||||
The cgroup read itself has no race. The kill's `waitFor` (shim.mjs:117-126) had already read `populated 0`
|
||||
for the stop to be proven. The read is the shim's call to `events()` (shim.mjs:83-96), and it reads one
|
||||
kernel file. So the brief's allowance for a bounded retry doesn't apply, and there is none.
|
||||
|
||||
The fix goes in the test's setup, which the brief allows ("Use the shim, the cohort controller or the
|
||||
test's setup and teardown, whichever the evidence points to"). The controller's release is correct and
|
||||
specified (README "Scope release", R1). Delaying it for a reader would change row 50's behavior.
|
||||
|
||||
## Step 2: the change
|
||||
|
||||
packages/conversation/tests/cohort.test.mjs, K12:
|
||||
|
||||
- It runs with `gate()`, holds `scope-release` before the stop, and waits until the hold is reached. Then it
|
||||
does every read that needs the scope: `cgroup.freeze`, `events` and `members`.
|
||||
- After the reads it lets the release go and asserts one entry, `["force-stop", "released"]`. This is new
|
||||
coverage: K12 now also shows the forking cohort's scope released.
|
||||
- The assertions are unchanged. `populated` must be 0 and the member list must be empty. The step 1 message
|
||||
stays.
|
||||
|
||||
packages/conversation/src/shim.mjs:167-168, `release` (:167 on 3b0aef995). It answered a failed `events()` with "the engine
|
||||
cgroup is not empty", so it reported unavailable as not empty. The refusal was already safe, but the reason
|
||||
was false. Now an `events()` answer that isn't `ok` is returned as it is, with the read's own reason. Only
|
||||
`populated` 1 gives "not empty". Nothing else matched that string (grep of packages/).
|
||||
|
||||
## Tests
|
||||
|
||||
- K12 as above.
|
||||
- R13, the brief's new case, placed after R3. After a proven stop, with `scope-release` held, the test makes
|
||||
`engine/cgroup.events` mode 000. Then:
|
||||
- `events` returns `ok: false`, has no `populated`, and the reason is "engine/cgroup.events unreadable
|
||||
(EACCES)".
|
||||
- On release, the controller records one entry `["force-stop", "unavailable", <that reason>]`.
|
||||
- The unit stays active, and the shim still answers `hello`.
|
||||
|
||||
Then `close()` reuses the stop's release, so there is still one entry. The `finally` closes the
|
||||
controller again (a second close is a no-op), restores mode 444, the kernel's mode for cgroup.events,
|
||||
and releases the scope. On
|
||||
3b0aef995's shim.mjs, R13 fails on the reason, because it reads "the engine cgroup is not empty".
|
||||
- K15 already covers a stop, as opposed to a release, with `events` unavailable: the shim gone, the file
|
||||
mode 000, or `engine` missing, each ending `uncertain` with its reason.
|
||||
|
||||
## File added beyond the brief
|
||||
|
||||
packages/conversation/README.md:599 listed "R1–R3, R5–R12" for cohort.test.mjs. With R13 it now reads
|
||||
"R1–R3, R5–R13". The brief's files don't include the README. Sage added it to this row in sage-2082.
|
||||
|
||||
## Runs
|
||||
|
||||
None yet. They need Sage's slot. Sage's sage-2082 says the run is on the pushed candidate in a clean
|
||||
worktree, and that it adds the control-board suite whole, so it counts as the gate run.
|
||||
|
||||
## Round 2
|
||||
|
||||
Filbert's C1 (#1755 comment 30125): R13 never closed its in-process controller, so the controller's
|
||||
socket server (controller.mjs:548) stayed open, and `reap` only kills units and engines. Only `close()`
|
||||
closes it (:1789). R13 now calls `h.ctrl.close()` after its checks and asserts one release entry, as R2
|
||||
does. Its `finally` also closes the controller, for a failure partway through. The second close is safe:
|
||||
`server` is null by then (:1791), and `#releaseScope` returns the cached release (:1634-1648). Branch
|
||||
gizmoduck/row250-r2, on e9cfd92f8.
|
||||
@@ -1,399 +0,0 @@
|
||||
# Row 215 build record
|
||||
|
||||
Owner: Herb. Reviewer: Filbert. Claim: herb-215-start, rev 2753.
|
||||
Brief: docs/plans/2026-10-20_case2-rows.md, C2-04, pin
|
||||
16847e94ae1768881711318fe81cbb5e6c66b971. Design: Gosalyn r11,
|
||||
sections 1.1, 1.3, 2.1, M4, M9 and 7.2.
|
||||
|
||||
Base: a2c72ac952df94ecab7e391d5042f49b7f88b816, row 212's reviewed
|
||||
candidate, under Q177. Branch: herb/row215. Rebuild on the combined 212+197
|
||||
landing when Sage names it. Do not replay or revert landed changes.
|
||||
|
||||
## Scope rulings (sage-1848)
|
||||
|
||||
1. Add packages/bus/src/runtime.mjs for library adapter injection and the
|
||||
library skip in protectedRoots. The skip has its own consumer test. Change
|
||||
nothing else there.
|
||||
2. Add packages/library/src/mirror.mjs, named mirror rather than store. It
|
||||
creates a bare mirror without a remote, reads at the served commit and
|
||||
reads sync state. Export one state filename constant, and export this
|
||||
module through packages/library/src/index.mjs. Row 222 imports the constant.
|
||||
3. Add packages/bus/src/server.mjs only to await library.file and
|
||||
library.status, with socket tests proving their replies are results, not {}.
|
||||
4. HTTP exposure is deferred. Row 225 owns the library.status route;
|
||||
C2-11b owns library pages. Leave serve.mjs alone. webui/src/cli.mjs gets
|
||||
only callback wiring next to the project-file callbacks on both listeners.
|
||||
5. Reuse existing refusal codes where possible.
|
||||
6. Build on a2c72ac95 until Sage supplies the 212 landing SHA.
|
||||
|
||||
Additional ruling, sage-1852: library-state-invalid is approved for malformed,
|
||||
unsafe or mismatched state, including a missing file while the served ref
|
||||
exists. The version-1 shared contract below is approved. Row 222 also owns
|
||||
runtime.mjs for its sync and timer wiring, recorded in that row's manifest.
|
||||
|
||||
Additional rulings, sage-1860, after Filbert's CHANGES on 6a508804f:
|
||||
|
||||
- B1 adds packages/cli/src/config.mjs and cli/tests/trackers-boot.test.mjs.
|
||||
trackerFor skips library entries. A real bus boot with tracker.baseUrl and
|
||||
a library entry succeeds and gets no tracker from that entry.
|
||||
- B2 refuses a role publish grant naming a library project in the loader.
|
||||
- B3 readers use the sync lock. mirror.mjs exports withLibraryLock, with a
|
||||
5000 ms wait bound and library-sync-busy on timeout. Sync locks only the
|
||||
served-ref move and state publication, never the fetch.
|
||||
- N3, git-socket doPush/recordPush accepting a library ID, is a later row.
|
||||
Sage records it in DEFERRED.md when 215 lands. No fix here.
|
||||
|
||||
## Shared contract with row 222
|
||||
|
||||
Agreed in herb-0048, megavolt-0081/0082 and sage-1852. This section is the
|
||||
contract Filbert reviews and Megavolt cites for Dewey. It is not a sync writer.
|
||||
|
||||
Module: packages/library/src/mirror.mjs. Export
|
||||
`SYNC_STATE_FILE = 'mosaic-library-sync.json'`. The full path is
|
||||
`join(mirror, SYNC_STATE_FILE)`, inside the bare repository. Only sync.mjs
|
||||
writes it, using a sibling temp file, fsync, rename, and directory fsync.
|
||||
|
||||
Version 1 has exactly these keys:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"branch": "main",
|
||||
"served": null,
|
||||
"lastFetch": null,
|
||||
"lastError": null,
|
||||
"diverged": null,
|
||||
"problems": []
|
||||
}
|
||||
```
|
||||
|
||||
- branch is the configured mapping branch and must match the reader's branch.
|
||||
- served is null or a full lowercase 40-hex commit ID. refs/heads/served is
|
||||
authority. The state value must equal that ref, which must name a commit.
|
||||
- lastFetch is null or a canonical ISO UTC timestamp.
|
||||
- lastError is null or exactly {code, at}. code matches [a-z-]{1,64}; at is
|
||||
canonical ISO UTC. It never holds stderr, prose or a credential value.
|
||||
- diverged is null or exactly {commit, at}, with the same commit/time rules.
|
||||
- problems uses C2-01's exact {code, path, message, line?}. code is R1-R7,
|
||||
message is that code's fixed RULES text, line is a positive safe integer
|
||||
when present. No file body or arbitrary message is accepted.
|
||||
- An absent file and absent served ref return the empty object above with
|
||||
the configured branch. An absent file with an existing served ref refuses.
|
||||
- Unknown keys, bad types, unsafe filesystem metadata, invalid JSON and a
|
||||
mismatch refuse library-state-invalid. Reads use a bounded regular owned
|
||||
private file without following links. The read never repairs state.
|
||||
- refs/remotes/library/<branch> is not duplicated in this file. Row 222 may
|
||||
read it when it needs the fetched tip.
|
||||
|
||||
Exports consumed by row 222:
|
||||
|
||||
| Export | Contract |
|
||||
| --- | --- |
|
||||
| mirrorPath({business, project, dataRoot}) | Require a library entry; return projectRepo's checked path |
|
||||
| ensureMirror(context) | Promise of the mirror path; race-safe idempotent bare init; no remote or fetch |
|
||||
| servedCommit(mirror) | Promise of full commit ID or null; refs/heads/served only |
|
||||
| readSyncState(mirror, {branch}) | Promise of checked version-1 state; compare with served ref |
|
||||
| withLibraryLock(mirror, operation) | Await the same exclusive lock as readers, then await operation({readSyncState}); always release |
|
||||
|
||||
The lock is a stable private regular file, mosaic-library-sync.lock inside
|
||||
the mirror. It is never unlinked. A kernel flock is held by the caller's
|
||||
file descriptor. Acquisition waits at most 5000 ms and refuses
|
||||
library-sync-busy on timeout. Unsafe lock metadata refuses library-state-invalid.
|
||||
|
||||
There is no fs.flock API. The exact protocol is: open the stable file with
|
||||
O_NOFOLLOW, check regular/private/owned/single-link metadata, pass its fd as
|
||||
child FD 3 to `flock --exclusive --wait 5 --conflict-exit-code 75 3` using
|
||||
asynchronous spawn, await
|
||||
that child's exit 0, then run the callback while the parent still holds its
|
||||
original descriptor. Both descriptors share the open file description, so
|
||||
the lock survives acquisition-child exit. Finally close the parent's fd.
|
||||
Process death also closes it. No holder child stays alive in the callback,
|
||||
no stale file is deleted, and unrelated operation children inherit only 0-2.
|
||||
Acquisition never uses spawnSync: the bus must serve other calls while a
|
||||
library reader waits (megavolt-0087).
|
||||
|
||||
A scratch-only probe on node v26.8.1 at 2026-10-21T08:34:00Z confirmed this:
|
||||
acquisition child exited 0; a second flock -n returned 1 while the parent fd
|
||||
stayed open; after closeSync it returned 0. The probe removed its own root.
|
||||
This was a design probe, not a package test, suite, Docker command or proof.
|
||||
|
||||
readSyncState takes that lock around reading the served ref and state file.
|
||||
The callback-scoped readSyncState({branch}) supplied by withLibraryLock reads
|
||||
under the already-held lock and does not reacquire it. The helper awaits
|
||||
asynchronous callbacks and releases in finally. A callback-scoped reader
|
||||
used after its callback ends refuses; it cannot escape its lock lifetime.
|
||||
|
||||
Row 222 fetches without this lock, then calls withLibraryLock across the
|
||||
served-ref move and atomic state write. Its tests hold publication between
|
||||
those steps and prove a concurrent reader waits, then sees the new consistent
|
||||
pair, including first sync. Row 215 tests that publication shape and timeout.
|
||||
A file read releases the lock after snapshotting a consistent served SHA,
|
||||
then reads that immutable commit. Row 222's separate outer sync lock spans
|
||||
fetch to prevent two sync operations interleaving (megavolt-0086).
|
||||
|
||||
Host adapter exports for this row:
|
||||
|
||||
- libraryStatus(context): return {project, ...state}, with no repository path
|
||||
or content. Do not fetch or rebuild on this read.
|
||||
- readLibraryFile({...context, path}): read a mapped, readable file at the
|
||||
served commit, returning {project, path, commit, content}. No caller-picked
|
||||
commit, working-tree fallback, fetch or write. C2-01's R1/R2/R7 exclusions
|
||||
apply. A never-synced mirror refuses library-commit for a file read.
|
||||
|
||||
Row 222 owns syncCommand, sync, writeSyncState, its outer sync lock, the timer
|
||||
and state publication. Row 215 owns the shared publication/read lock per
|
||||
sage-1860. Sync rebuilds problems with existing readLibrary({repo, commit,
|
||||
mapping}). It does not need a second rebuild function from this row.
|
||||
|
||||
## Root consumer audit and reviewer notes
|
||||
|
||||
On a2c72ac95, ran exactly the sage-1860 audit:
|
||||
`git grep -n 'entry\.root\|\.root)' -- 'packages/*/src/*.mjs'`.
|
||||
It has 14 hits. runtime.mjs:95, business/cli.mjs:61,72,78,118,
|
||||
instance-settings.mjs:142-143, resolve.mjs:44, cli/config.mjs:62-63 and
|
||||
project/paths.mjs:42 all get the library guard in this row. business.mjs:233
|
||||
and :242 are code-project validation after the library dispatch, not an
|
||||
unguarded consumer. queue.mjs:1144 compares queue genesis roots and never
|
||||
iterates business.projects; it is safe and unchanged. A second search for
|
||||
projectFilePath/business.projects/b.projects found no additional root reader.
|
||||
ensureCheckouts destructures root rather than spelling .root; its guard and
|
||||
the launcher's filter remain in T1. Bare projectFilePath/loadProject remain
|
||||
strict and unchanged.
|
||||
|
||||
Filbert N1 is handled at the existing owned paths.mjs boundary: projectRepo
|
||||
defaults to record-project use and refuses a library entry with project-invalid.
|
||||
Only mirrorPath's internal call opts into allowLibrary. Thus ordinary human
|
||||
and tester project init cannot occupy an uninitialized library mirror path.
|
||||
No record API or bus argument exposes that internal option.
|
||||
|
||||
Filbert N2: ensureMirror failure refuses bus boot. No socket becomes ready.
|
||||
The runtime closes resources it opened, following its existing failure path.
|
||||
A T4 test uses an unsafe/pre-existing mirror and proves the refusal, rather
|
||||
than serving a half-configured library adapter.
|
||||
|
||||
## Verification record
|
||||
|
||||
Planning stage. No product code, package test, suite, image build, live operation
|
||||
or push for row 215 has happened. Product implementation awaits Filbert's
|
||||
manifest approval. Sage owns suite and full-gate grants. Row 197's proof
|
||||
commit is separate and is not part of this row's changes.
|
||||
|
||||
## Implementation ledger
|
||||
|
||||
Plan: agents/herb/work/queue-215/MANIFEST.md at 2522025af, approved by
|
||||
Filbert in the reply to herb-0056. Execution is inline by Herb under the
|
||||
executing-plans and test-driven-development skills. No agent delegation.
|
||||
|
||||
Pre-flight: T1's validated mapping feeds T2's protected document and T3's
|
||||
mirror context; T3's lock/state helpers feed T4's injected host adapter.
|
||||
The shared contract is pinned above, with no interface conflict found.
|
||||
|
||||
Sage-1867 overrides COMMON's singles allowance: every test and executable
|
||||
probe needs an explicit slot grant. No further probe/test has run since
|
||||
that reminder. Read-only inspection and test authoring continue while the
|
||||
slot is held. The first red execution is pending; product code is unchanged.
|
||||
|
||||
Filbert's approved-manifest build notes: ensureMirror creates the lock in
|
||||
its staged directory before publication; a missing lock in an existing
|
||||
mirror refuses library-state-invalid. The top-level metadata allowlist
|
||||
permits only normal bare Git entries plus the state and stable lock files.
|
||||
Tests cover an unknown entry. The host needs /usr/bin/flock; ENOENT yields
|
||||
a handled library-state-invalid refusal, never an unhandled child error.
|
||||
Lock acquisition uses /usr/bin/flock directly and asynchronous spawn.
|
||||
|
||||
T1: consumer and loader regression tests authored, not run. T2: direct M9
|
||||
write and serialization regression tests authored, not run. No completion
|
||||
or passing claim is made for either task.
|
||||
|
||||
Update, sage-1869 focused slot, 2026-10-21T08:47:48Z to 08:51:07Z:
|
||||
the busy check was CLEAR before the first test. T1's mapping regression
|
||||
failed 0/1 on unsupported kind as expected, then passed 2/0 with the publish
|
||||
refusal included. Other focused greens: business CLI 1/0, resolver 1/0,
|
||||
instance settings 1/0, seat checkout 1/0, project paths 1/0, sandboxed launcher
|
||||
1/0, and trackers-boot whole 2/0. T2's direct writer case failed 0/1 on the
|
||||
missing refusal, then its whole new file passed 4/0. Green total 14/0 with
|
||||
no skips or cancellations. Logs and counts: granted-t1/. The final /proc
|
||||
scan found no test process or fixture cwd/argv reference; its private root
|
||||
was removed. Clear sent as herb-0062. Existing files' other cases have not
|
||||
been run yet, so T1/T2's full-file acceptance is still pending.
|
||||
|
||||
Sage-1874 directs continued authoring and implementation while the landing
|
||||
gate/proof holds the slot. T3/T4 tests were written first. Their initial
|
||||
red runs cannot execute during that hold; implementation proceeds under
|
||||
that owner direction, with no claim of a witnessed red or green for T3/T4.
|
||||
Their baseline red and candidate checks need a later explicit grant.
|
||||
|
||||
Implementation ruling: initialization uses GNU /usr/bin/mv --no-clobber
|
||||
--no-target-directory for its bounded staging rename, rather than Node's
|
||||
renameSync, which could replace an empty directory made by a competing
|
||||
actor. This preserves pre-existing directories and needs no new package on
|
||||
the Linux/coreutils bus host. The host also needs /usr/bin/flock. Neither
|
||||
command has been executed for T3/T4 yet. Publication errors fail closed.
|
||||
Sync-state reads are capped at 8 MiB, including a checked extra byte; an
|
||||
oversized or concurrently changed file refuses library-state-invalid.
|
||||
|
||||
T5 static dependency audit found two partial pinned-copy fixtures that copy
|
||||
business/src but not its newly imported library mapping validator:
|
||||
cli/tests/stack-release.test.mjs:1772 and stack-release-fixture.mjs:309 on
|
||||
the base. Each now includes packages/library/src in the existing copy list.
|
||||
This changes fixture closure only, no assertion or timeout. The complete
|
||||
stack-release file and each test file importing that shared fixture require
|
||||
a later granted single-file run. They are outside the four-file T3/T4 slot.
|
||||
|
||||
Sage-1879 places the four-file T3/T4 focused run after their 212+197 proof,
|
||||
before Gizmoduck, and requires their explicit clear before starting. No run
|
||||
has occurred after herb-0062. Row 197's N7 base-image-tag finding is left to
|
||||
Sage's DEFERRED entry; no row 197 source change is made here.
|
||||
|
||||
|
||||
Focused T3/T4 grant sage-1882, 2026-10-21 09:13-09:18Z: busy check
|
||||
CLEAR. Final whole-file results: mirror 16/0, bus library 6/0, WebUI
|
||||
library-cli 1/0, project-runtime 3/0, all with zero skips/cancellations.
|
||||
Syntax checks passed for the four files and five changed host modules.
|
||||
Logs, all intermediate failures, counts and empty /proc cleanup scan are
|
||||
in granted-t34/. Baseline a2c72ac95: three focused bus cases 0/3
|
||||
(unknown-verb), CLI 0/1 (missing callbacks). Mirror baseline 0/1 is an
|
||||
import refusal for the new module, not a witnessed behavioral red.
|
||||
An initial whole baseline bus attempt left a runtime after its expected
|
||||
failure; its exact runner was stopped, no process remained, and the
|
||||
baseline was narrowed to the three bounded broker/socket cases.
|
||||
Candidate fixture setup errors and a mock-child timeout were corrected
|
||||
before the final whole-file passes. No suite or Docker/image/proof ran.
|
||||
|
||||
Filbert's 09:09 publication note: no dependence on mv -n's skipped-rename
|
||||
exit status across coreutils versions. Save staging dev/ino before mv;
|
||||
only its disappearance plus the same dev/ino at the mirror proves a win.
|
||||
A remaining original staging inode means a loss, requiring a valid winner.
|
||||
Only that owned original staging inode is removed. Numeric no-clobber
|
||||
statuses 0 and 1, including a diagnostic, are tested with a competing
|
||||
winner. Spawn errors, signals/timeouts and inconsistent outcomes refuse.
|
||||
Coreutils must provide atomic --no-clobber --no-target-directory semantics;
|
||||
it need not use any particular skipped-rename status convention.
|
||||
|
||||
|
||||
Landing update: prepared herb/row215-on212 on fefd54e13 (includes row 212
|
||||
landing ee7b2f137), without history replay or stash. Only BUILD-LOG.md and
|
||||
cli/tests/stack-release.test.mjs overlap the a2c72ac95-to-landing change
|
||||
set. BUILD-LOG preserves all landed entries and appends the existing Herb
|
||||
entry. stack-release preserves the landing plus only the library/src copy
|
||||
list addition. No test has run on this landing yet. All further execution
|
||||
requires a Sage grant (supersedes the original COMMON singles rule).
|
||||
|
||||
|
||||
Sage-1979 early singles on fefd54e13, stopped after file10 per sage-1983:
|
||||
- packages/bus/tests/library.test.mjs: 6/0
|
||||
- packages/bus/tests/project-runtime.test.mjs: 3/0
|
||||
- packages/business/tests/business.test.mjs: 18/0
|
||||
- packages/business/tests/cli.test.mjs: 10/0
|
||||
- packages/business/tests/instance-settings.test.mjs: 12/0
|
||||
- packages/business/tests/library-projects-protected.test.mjs: 4/0
|
||||
- packages/business/tests/resolve.test.mjs: 11/0
|
||||
- packages/cli/tests/launcher.test.mjs: 30/0
|
||||
- packages/cli/tests/stack-release-external.test.mjs: 25/0
|
||||
- packages/cli/tests/stack-release.test.mjs: 196/0
|
||||
|
||||
Total315/0, zero skips/cancellations. This is an early read only, not gate
|
||||
evidence for a merged candidate. The sequential driver was paused during
|
||||
file10 so it could not start file11, then terminated after file10 exited0.
|
||||
No file11 log exists. Results/logs are in granted-singles/. Later landed
|
||||
overlaps require a new branch and all16 singles again after their merge.
|
||||
|
||||
|
||||
Current merge preparation per sage-1983/1987: new branch
|
||||
herb/row215-on-f827 on f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87.
|
||||
Nine landed overlaps are recorded in current-MERGE.json and the exact
|
||||
candidate deltas against the landing are in current-merge-only.patch.
|
||||
Two textual conflicts were resolved manually: Broker keeps hostKeys and
|
||||
adds library; business.mjs keeps CREATIVE_DEFINITIONS and adds checkMapping.
|
||||
The other seven merges preserve the landing plus the original C2-04 edits.
|
||||
All other product/test paths match the early215 tree byte for byte. The
|
||||
landing's BUILD-LOG is preserved and the existing Herb entry is appended.
|
||||
No history replay, stash, force push, branch deletion or source commit.
|
||||
No test/probe/syntax check ran on the merged tree after the slot was cleared.
|
||||
All16 whole singles need a new Sage grant before candidate commit/review.
|
||||
The10 old-base315/0 results are early reads only, never merged gate evidence.
|
||||
|
||||
|
||||
## Source candidate and sage-2008 receipts
|
||||
|
||||
Source commit: e333af4dc7af3a9d3789c8c0db26a0df8bdddfee, on
|
||||
f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87. SOURCE.json records all30
|
||||
changed source/phase-log paths with blob SHA256 and Git mode. The next
|
||||
commit contains only this packet. No product change follows the tests.
|
||||
|
||||
Sage-2008: start13:15:15.548943Z; end13:27:27.279728Z, 2026-10-21.
|
||||
Each of the16 TEST-FILES.txt files ran whole, sequentially. All451 passed,
|
||||
with0 failed/skipped/cancelled. Per-file outputs are in granted-2008/;
|
||||
EVIDENCE.json records their counts, Node durations and log hashes.
|
||||
|
||||
| File | Pass/fail |
|
||||
| --- | ---: |
|
||||
| packages/bus/tests/library.test.mjs | 6/0 |
|
||||
| packages/bus/tests/project-runtime.test.mjs | 3/0 |
|
||||
| packages/business/tests/business.test.mjs | 19/0 |
|
||||
| packages/business/tests/cli.test.mjs | 10/0 |
|
||||
| packages/business/tests/instance-settings.test.mjs | 13/0 |
|
||||
| packages/business/tests/library-projects-protected.test.mjs | 4/0 |
|
||||
| packages/business/tests/resolve.test.mjs | 11/0 |
|
||||
| packages/cli/tests/launcher.test.mjs | 31/0 |
|
||||
| packages/cli/tests/stack-release-external.test.mjs | 25/0 |
|
||||
| packages/cli/tests/stack-release.test.mjs | 196/0 |
|
||||
| packages/cli/tests/stack-upgrade.test.mjs | 21/0 |
|
||||
| packages/cli/tests/trackers-boot.test.mjs | 2/0 |
|
||||
| packages/library/tests/mirror.test.mjs | 16/0 |
|
||||
| packages/project/tests/project.test.mjs | 15/0 |
|
||||
| packages/seat/tests/checkout.test.mjs | 78/0 |
|
||||
| packages/webui/tests/library-cli.test.mjs | 1/0 |
|
||||
|
||||
All29 product/test hashes equal their pre-run values. The final /proc cwd
|
||||
and argv scan was empty; the private test root was removed. Clear sent
|
||||
as herb-0082 at13:28:38Z. No further runs occurred. No image, Docker,
|
||||
lane, proof or full suite was part of this grant.
|
||||
|
||||
Before commit, checked f8276c5eb..8a04f4aa4 on every215 source path and
|
||||
all16 test paths: no overlap. Row248's grant-executor test is outside them.
|
||||
The current root-consumer grep still returns14 sites, all classified by
|
||||
the earlier audit: business code roots after dispatch, guarded library
|
||||
skips at consumers, and queue's unrelated genesis-root invariant.
|
||||
|
||||
Sage-2016 authorizes the source commit, packet receipts and seat-only push,
|
||||
then Filbert's candidate review. The landing gate stays with Sage. Earlier
|
||||
focused and old-base receipts are archived in granted-t1/, granted-t34/
|
||||
and granted-singles/, with their limits kept above. Full package/shell
|
||||
landing checks and implementation approval remain pending. No HTTP route,
|
||||
remote fetch, sync writer, timer or live operation was added.
|
||||
|
||||
Raw Node error logs retain their original space-only lines. Packet whitespace
|
||||
checks exclude *.log so the recorded output bytes stay unchanged; source and
|
||||
other packet files pass the ordinary diff check.
|
||||
|
||||
## Merge-scoped round 2 after rows 249 and 197 (sage-2054)
|
||||
|
||||
Row197 landed as a36523713 after proof6 passed 8/8 gates. Row249's
|
||||
broker fix is also in this base. Source a6101e21c596e2972ab5a7e3087736075899505e, single parent a3652371338e60187d4e95cee4a0f30f3c8a8f06,
|
||||
is on the new herb/row215-on197 branch. The old branch stays untouched.
|
||||
No force push, branch deletion or stash was used. The merge was clean.
|
||||
|
||||
Only broker.mjs and stack-release.test.mjs changed upstream among the30
|
||||
source/phase-log paths. Both retain every landed hunk. The broker keeps
|
||||
row249's installed flag and hostLineLeft handling. The stack-release test
|
||||
keeps row197's leasePort import, after hook and closed-port lease helper;
|
||||
215 adds only its library fixture copy. The other28 blobs and all modes
|
||||
match the prior source. All30 paths have exactly the same -U0 added and
|
||||
removed lines as f8276c5eb..e333af4dc. BUILD-LOG.md is append-only.
|
||||
|
||||
Stable patch-id, old and new: d191e7e9586cd3b7c18310daacdf0c1fdbc8be01.
|
||||
r2-range-diff.txt reports only the commit message changed (!); its patch
|
||||
is unchanged.
|
||||
r2-MERGE.json records every path; r2-merge-only.patch contains both merged
|
||||
source diffs against the new base. SOURCE.json names the new source.
|
||||
|
||||
Filbert approved round1 in comment30071, rev2897. This round requests
|
||||
merge-only review. The earlier451/0 receipts belong to the prior base;
|
||||
no test, probe, syntax check, Docker command or lane ran in this round.
|
||||
Merged-tree evidence remains pending Sage's explicit clear.
|
||||
r2-TEST-FILES.txt proposes all16 original whole singles plus all66
|
||||
bus test files whose local import closure reaches broker.mjs, deduplicated
|
||||
to80 whole files. This includes shared fixture and runtime imports.
|
||||
Sage's slot and row196 landing gate come first. The full landing gate
|
||||
remains Sage's. No library behavior, assertion or timeout changed.
|
||||
@@ -1,261 +0,0 @@
|
||||
{
|
||||
"grant": "sage-2008",
|
||||
"sourceCommit": "e333af4dc7af3a9d3789c8c0db26a0df8bdddfee",
|
||||
"base": "f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87",
|
||||
"start": "2026-10-21T13:15:15.548778+00:00",
|
||||
"end": "2026-10-21T13:27:27.279728+00:00",
|
||||
"summary": {
|
||||
"tests": 451,
|
||||
"pass": 451,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"file": "packages/bus/tests/library.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "01-packages_bus_tests_library.test.mjs.log",
|
||||
"sha256": "c19016583abc936534f41bde26eb39e095496eda944622142b1d18ffd5018bc0",
|
||||
"nodeDurationMs": 359.869493
|
||||
},
|
||||
{
|
||||
"file": "packages/bus/tests/project-runtime.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "02-packages_bus_tests_project-runtime.test.mjs.log",
|
||||
"sha256": "f123231042d1562fee6dad3d885ac587967e0287f63603c861d04c1907363530",
|
||||
"nodeDurationMs": 312.717335
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/business.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 19,
|
||||
"pass": 19,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "03-packages_business_tests_business.test.mjs.log",
|
||||
"sha256": "ae990ebccf7f21b9b32fd9c25fdd637873251c078e17dd95471b82b548322980",
|
||||
"nodeDurationMs": 199.91256
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/cli.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 10,
|
||||
"pass": 10,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "04-packages_business_tests_cli.test.mjs.log",
|
||||
"sha256": "28512dc38e2bce04294048a2f1c7dc7cf0c322028f874d1d35aa83b87570ea54",
|
||||
"nodeDurationMs": 2381.258516
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/instance-settings.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "05-packages_business_tests_instance-settings.test.mjs.log",
|
||||
"sha256": "146623624012da1399fb4ee3de4c0e13df1af28caae81f4870315a67ac368f8f",
|
||||
"nodeDurationMs": 608.08011
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "06-packages_business_tests_library-projects-protected.test.mjs.log",
|
||||
"sha256": "675ae18523218ab70a4addee039f41df6ae08ee414f20527f975a2004dde65b2",
|
||||
"nodeDurationMs": 118.54831
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/resolve.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 11,
|
||||
"pass": 11,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "07-packages_business_tests_resolve.test.mjs.log",
|
||||
"sha256": "6557938cb8e6d79617c0ea911a6e0ad7303cf5a4f9dd5a5631c70d093e6b06fe",
|
||||
"nodeDurationMs": 94.022587
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/launcher.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 31,
|
||||
"pass": 31,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "08-packages_cli_tests_launcher.test.mjs.log",
|
||||
"sha256": "c3404f1931595914d469cb00a951a5e1648f7792733c86bddbfa099552e5791c",
|
||||
"nodeDurationMs": 24989.261794
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release-external.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 25,
|
||||
"pass": 25,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "09-packages_cli_tests_stack-release-external.test.mjs.log",
|
||||
"sha256": "55224b6204d4d05a4cb669fb2845aa4168ab868223c3f341ab026032c47458b4",
|
||||
"nodeDurationMs": 96332.465778
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 196,
|
||||
"pass": 196,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "10-packages_cli_tests_stack-release.test.mjs.log",
|
||||
"sha256": "3f7430ce1f28482a5b66fc0e7db76969298f0dd32c3793e242bc10110dc44e6e",
|
||||
"nodeDurationMs": 533493.817869
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-upgrade.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 21,
|
||||
"pass": 21,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "11-packages_cli_tests_stack-upgrade.test.mjs.log",
|
||||
"sha256": "d18a3eff64b39a5128ab7e842721748b214dc3037ecc9d2c93c58f023859d695",
|
||||
"nodeDurationMs": 60456.446459
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/trackers-boot.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 2,
|
||||
"pass": 2,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "12-packages_cli_tests_trackers-boot.test.mjs.log",
|
||||
"sha256": "22e56455a6a56c98b02f942ed3d38504e4f8486343235c4035c88b967625bce5",
|
||||
"nodeDurationMs": 502.723687
|
||||
},
|
||||
{
|
||||
"file": "packages/library/tests/mirror.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 16,
|
||||
"pass": 16,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "13-packages_library_tests_mirror.test.mjs.log",
|
||||
"sha256": "def30105a3d561118e360535d9d3129226361f2e7902f316e47c74f65f1c0e47",
|
||||
"nodeDurationMs": 5963.543966
|
||||
},
|
||||
{
|
||||
"file": "packages/project/tests/project.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 15,
|
||||
"pass": 15,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "14-packages_project_tests_project.test.mjs.log",
|
||||
"sha256": "e63ab0d23ab24aa1f1f2c1ea8017e8541f415dcb20dff697a37bb7a6368e174d",
|
||||
"nodeDurationMs": 355.86586
|
||||
},
|
||||
{
|
||||
"file": "packages/seat/tests/checkout.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 78,
|
||||
"pass": 78,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "15-packages_seat_tests_checkout.test.mjs.log",
|
||||
"sha256": "c9e7168f589047b8176ec4ee8d2f03adb9fb68f692b363ba6d0036f670811ede",
|
||||
"nodeDurationMs": 4880.907448
|
||||
},
|
||||
{
|
||||
"file": "packages/webui/tests/library-cli.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "16-packages_webui_tests_library-cli.test.mjs.log",
|
||||
"sha256": "1ca5b92bc4f2de9ef6aa7156cdea62742fb9ddf054ebfb56a9548431e0cfec0d",
|
||||
"nodeDurationMs": 191.536271
|
||||
}
|
||||
],
|
||||
"cleanup": {
|
||||
"processes": [],
|
||||
"removed": "/mnt/storage/scratch/gt-j5nm6iqn",
|
||||
"sourceHashesUnchanged": 29
|
||||
},
|
||||
"drift": {
|
||||
"base": "f8276c5eb",
|
||||
"tip": "8a04f4aa4aba493eb89e92aa9e0c34084be7058e",
|
||||
"overlap": []
|
||||
},
|
||||
"earlierRuns": {
|
||||
"granted-t1": "focused T1/T2 red/green on a2c72ac95",
|
||||
"granted-t34": "focused T3/T4 with baseline import refusal and corrected fixture errors recorded",
|
||||
"granted-singles": "old fefd54e13 early315/0, not merged gate evidence"
|
||||
},
|
||||
"mergeRound": {
|
||||
"sourceCommit": "a6101e21c596e2972ab5a7e3087736075899505e",
|
||||
"base": "a3652371338e60187d4e95cee4a0f30f3c8a8f06",
|
||||
"status": "not-run; awaiting Sage clear",
|
||||
"priorReceipts": "sage-2008 receipts apply to e333af4dc on f8276c5eb only"
|
||||
}
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
# C2-04 library business entry implementation plan
|
||||
|
||||
> Execution: Herb implements in this session using the executing-plans skill.
|
||||
> Filbert approves this manifest before any product implementation.
|
||||
|
||||
**Goal:** Load a library mapping without giving an agent a checkout, protect
|
||||
all project mappings from organization writes, and expose human-only bus
|
||||
reads of the bare mirror's served commit and sync status.
|
||||
|
||||
**Architecture:** C2-01 checks mappings and reads commits. Business consumers
|
||||
skip library entries. A host-only mirror module owns local mirror reads and
|
||||
initialization. runtime.mjs injects that module into the broker, preserving
|
||||
the broker's sandbox import closure. Sync and HTTP routes belong to later rows.
|
||||
|
||||
**Tech stack:** Existing Node ESM, node:test and bounded local Git helpers.
|
||||
No dependencies. node_modules remains the plain canonical symlink.
|
||||
|
||||
**Spec:** Pinned C2-04 brief; Gosalyn's approved design 1.1, 1.3, 2.1,
|
||||
M4/M9 and 7.2; BUILD.md's sage-1848/1852/1860 scope and shared-state contract.
|
||||
|
||||
## Constraints and review focus
|
||||
|
||||
- Base a2c72ac95; rebase only onto Sage's named 212 landing on a new branch.
|
||||
- Existing code-project entries retain root/repo/remote behavior. Library
|
||||
entries have no root or repo override and use C2-01 checkMapping.
|
||||
- Preserve the broker's pinned imports. No library import in broker.mjs and
|
||||
no new runner mount. Do not edit serve.mjs or add an HTTP route.
|
||||
- No fetch, remote config, credential read, timer, sync writer, bus write or
|
||||
live operation. All tests use made-up content and local repositories.
|
||||
- All test/probe runs require Sage's grant (sage-1867), including singles.
|
||||
Stop and report two failures in one gate. Do not push without authorization.
|
||||
|
||||
Review focus, with owning tasks below: library-first iteration must not
|
||||
break a later code project (T1); serialized documents cannot bypass M9
|
||||
(T2); racing initialization must not replace another mirror (T3); stale or
|
||||
unsafe state must not leak content (T3); async socket replies must preserve
|
||||
the result and human-only admission (T4).
|
||||
|
||||
## Paths and evidence from the base
|
||||
|
||||
| Product path | Allowed change |
|
||||
| --- | --- |
|
||||
| packages/business/src/business.mjs | Dispatch kind:library to checkMapping before code-root validation (:228-244) |
|
||||
| packages/business/src/organization.mjs | Compare canonical projects in write before publication (:177 onward) |
|
||||
| packages/business/src/cli.mjs | Skip library roots in validate, resolve --project and credential exclusion roots (:60-61, :71-79, :118) |
|
||||
| packages/business/src/resolve.mjs | Skip library entries while matching a project file (:44) |
|
||||
| packages/business/src/instance-settings.mjs | Skip library before projectFilePath (:142), nothing else |
|
||||
| packages/seat/src/checkout.mjs | Skip library entries in ensureCheckouts (:315-327) |
|
||||
| packages/cli/src/launcher.mjs | Pass only code entries to ensureCheckouts (:354) |
|
||||
| packages/cli/src/config.mjs | Skip library entries in trackerFor's root loop (:61-63), per sage-1860 |
|
||||
| packages/project/src/paths.mjs | Skip library entries in overlap loop (:41-44); default record use refuses library, mirrorPath internally opts into allowLibrary |
|
||||
| packages/library/src/mirror.mjs | New bare init, checked state and served-commit file read module |
|
||||
| packages/library/src/index.mjs | Export mirror module interface and SYNC_STATE_FILE |
|
||||
| packages/bus/src/broker.mjs | New injected library adapter, human-only admission and two async verbs |
|
||||
| packages/bus/src/runtime.mjs | Library adapter wiring, mirror initialization and protectedRoots skip only |
|
||||
| packages/bus/src/server.mjs | Await the two library verbs only |
|
||||
| packages/webui/src/cli.mjs | Two library read callbacks beside project callbacks on main and tester listener; no routes |
|
||||
|
||||
packages/business/src/project.mjs need not change: callers skip a library
|
||||
before projectFilePath or loadProject. Do not weaken their code-root checks.
|
||||
scripts/stack-copy.sh already copies packages/library/src and needs no edit.
|
||||
|
||||
Test paths to modify: business/tests/business.test.mjs, cli.test.mjs,
|
||||
resolve.test.mjs, instance-settings.test.mjs; seat/tests/checkout.test.mjs;
|
||||
cli/tests/launcher.test.mjs, trackers-boot.test.mjs; project/tests/project.test.mjs;
|
||||
bus/tests/project-runtime.test.mjs. All paths are under packages/.
|
||||
|
||||
T5 dependency-audit addition: cli/tests/stack-release.test.mjs and its
|
||||
stack-release-fixture.mjs helper copy packages/library/src alongside
|
||||
business/src, whose validator now imports the mapping checker. No assertions
|
||||
or timeouts change. Whole-file dependent singles require a later Sage slot.
|
||||
|
||||
New tests: packages/business/tests/library-projects-protected.test.mjs;
|
||||
packages/library/tests/mirror.test.mjs; packages/bus/tests/library.test.mjs;
|
||||
packages/webui/tests/library-cli.test.mjs. Reuse existing made-up fixtures.
|
||||
If a new fixture is needed, define it within the corresponding new test file.
|
||||
No unrelated test assertion or timeout changes.
|
||||
|
||||
Record paths: agents/herb/work/queue-215/{MANIFEST.md,BUILD.md}, later source
|
||||
manifest and test receipts there; one append-only BUILD-LOG.md phase for this
|
||||
row when implementation begins. Sage owns docs/SESSIONS.md.
|
||||
|
||||
## T1. Mapping and consumer skips
|
||||
|
||||
- [ ] Add failing business tests: accept a frozen library mapping without a
|
||||
root, retain mixed/only-library documents, and propagate C2-01's mapping
|
||||
and playground refusal codes. A role publish naming a library project
|
||||
refuses at load, even with an otherwise valid fork identity and remote.
|
||||
Existing code validation remains unchanged.
|
||||
- [ ] Add a separate regression for each consumer: CLI validate and its
|
||||
credential exclusion roots; CLI resolve --project books has no project
|
||||
layer; resolveInstance finds a later real project; instance settings still
|
||||
writes an unrelated setting; ensureCheckouts returns no library checkout;
|
||||
launcher creates no books workspace clone; projectRepo skips a library
|
||||
while still rejecting overlap with a real code root. Put books first.
|
||||
- [ ] Add the real bus boot regression in cli/tests/trackers-boot.test.mjs:
|
||||
tracker.baseUrl is set and books is a library entry; boot succeeds, books
|
||||
produces no tracker, and a later real tracker project still works.
|
||||
- [ ] projectRepo(context, {allowLibrary = false} = {}) refuses a library
|
||||
entry by default with project-invalid. Only mirrorPath opts in. Test that
|
||||
ordinary human and tester record initialization leave no directory at the
|
||||
future mirror path; no public verb can supply allowLibrary.
|
||||
- [ ] Add runtime's protectedRoots consumer regression in T4's real runtime
|
||||
fixture. A valid credential outside code/data roots still loads with a
|
||||
library entry, and existing credential protections still refuse unsafe files.
|
||||
- [ ] Run each changed test singly, confirm the new cases fail for the
|
||||
intended root assumption, then implement only the table's guards and
|
||||
checkMapping dispatch. Re-run the same files singly.
|
||||
|
||||
CLI validate reports a library entry as library, without an absent-project
|
||||
warning. CLI resolve --project books resolves without loading a project file,
|
||||
as the design's skip requires. It does not fabricate project vars or a root.
|
||||
|
||||
## T2. M9 at the organization writer
|
||||
|
||||
- [ ] In the new business test file, call organizationWriter.write directly
|
||||
with a changed playground prefix and, separately, a changed hybrid entry.
|
||||
Both refuse organization-projects-protected. Snapshot business bytes and
|
||||
changes.jsonl before each call; assert both remain identical afterward.
|
||||
- [ ] Cover addition, deletion and changes to code projects too, since M9
|
||||
protects all projects. Reordered object keys are allowed; array changes
|
||||
are changes. An ordinary non-project write still succeeds and logs.
|
||||
- [ ] Add a serialization regression so a proposed object's serialized
|
||||
projects cannot differ from those checked before publication.
|
||||
- [ ] Run the file singly to see the missing refusal, compare canonical
|
||||
projects against old disk JSON and the document that actually lands,
|
||||
before any publication/receipt, then re-run it singly.
|
||||
|
||||
## T3. Bare mirror, served file and read-only state
|
||||
|
||||
- [ ] Add failing tests for mirrorPath and ensureMirror: exact projectRepo
|
||||
default, no checkout/remote, retained no-links/overlap protections,
|
||||
idempotence, simultaneous creators and preservation of a pre-existing
|
||||
non-mirror directory or unsafe Git metadata.
|
||||
- [ ] Add failing state tests for BUILD.md's full version-1 contract: missing
|
||||
state/ref, valid state, malformed JSON, unknown keys/types, branch mismatch,
|
||||
invalid times/IDs/problem shape, symlink/hardlink/non-private file and
|
||||
missing or mismatched served ref. Assert reads change no bytes.
|
||||
- [ ] Add shared-lock tests: withLibraryLock(mirror, operation) waits at most
|
||||
5000 ms, refuses library-sync-busy on timeout and releases after a throw.
|
||||
A reader arriving between the publisher's served move and state write
|
||||
waits, then reads the consistent pair. Cover first sync and fast-forward
|
||||
in independent processes, same-process independent acquisitions and
|
||||
release after owner death. A callback-scoped reader expires on release.
|
||||
- [ ] Implement the lock by async spawn of flock on the parent's inherited
|
||||
fd 3, as pinned in BUILD.md. Await acquisition-child exit before calling
|
||||
operation. Never spawnSync during acquisition, which could freeze the bus
|
||||
for 5 s. A parallel ordinary bus read remains responsive while a library
|
||||
read waits. Only the publication/read lock is shared; fetch is outside it.
|
||||
- [ ] Add served-read tests against local fixtures containing spaces,
|
||||
capitals, a .canvas and unmapped top-level note. Seed a served ref and state
|
||||
without fetching. A newer unrelated HEAD does not change the returned
|
||||
file. R1/R2/R7 exclusions, traversal, a missing path, a caller commit and a
|
||||
never-synced mirror refuse. Status contains no fixture body marker.
|
||||
- [ ] Implement mirror.mjs and index exports using the shared contract.
|
||||
Initialization stages into an owned private sibling directory and renames
|
||||
atomically; a losing creator validates the winner and removes only its own
|
||||
staging directory. Git uses existing bounded safe helpers, no remote.
|
||||
- [ ] Run mirror.test.mjs singly, red then green. Re-run C2-01 reader.test.mjs
|
||||
singly if a reader assumption changes. Do not change C2-01 reader rules.
|
||||
|
||||
mirror.mjs validates a bare mirror's metadata before Git reads it, including
|
||||
no remote/include/indirection. It does not apply inspectGit's working-tree
|
||||
.git assumption to a bare repository. Failures reuse library-git or the
|
||||
approved library-state-invalid code. State reads are bounded and private.
|
||||
|
||||
## T4. Human-only bus reads and deferred Console callbacks
|
||||
|
||||
- [ ] Add broker tests for library.file and library.status using injected
|
||||
adapters. Each agent session refuses human-required before adapter access,
|
||||
including bad arguments and an absent adapter. A reader or tester does not
|
||||
gain a human capability. Human calls validate keys, then use checked
|
||||
library context. Secret checking and bounded refusal evidence remain.
|
||||
- [ ] Add real startBroker/socket tests for both verbs. Seed only local
|
||||
fixture mirror data. Assert result shape/content and an actual status
|
||||
field, not merely successful transport or {}. Cover never-synced status
|
||||
and runtime's protectedRoots skip. Keep the pinned import-closure test.
|
||||
- [ ] Inject a separate library adapter via runtime, initialize only library
|
||||
mirrors, add the two async request paths, and include them in server's
|
||||
awaited list. Do not import library or fs into broker.
|
||||
- [ ] Unsafe or pre-existing non-mirror initialization refuses bus boot,
|
||||
closes opened resources and never publishes a ready socket. Add that
|
||||
runtime regression in library.test.mjs.
|
||||
- [ ] Wire main and tester Console callbacks beside project-file callbacks.
|
||||
No HTTP route is shipped. The new CLI test captures the startServer
|
||||
options with a test-only module loader and calls the supplied callbacks
|
||||
against a fixture bus, checking the verb and transport identity. No
|
||||
product test seam, UI page, endpoint or serve.mjs change is needed.
|
||||
- [ ] Run library.test.mjs, project-runtime.test.mjs and library-cli.test.mjs
|
||||
individually, red then green. Human admission may use the existing
|
||||
fixture authentication seam; do not forge or bypass a live identity.
|
||||
|
||||
## T5. Review packet and Sage's gate
|
||||
|
||||
- [ ] Search packages/*/tests and scripts/test-*.sh for each changed source
|
||||
path, imports and 64-hex pins. Record the resulting test-file list and run
|
||||
each changed/touched test singly. Stop and report a scope error.
|
||||
- [ ] Self-review the diff against this manifest and all acceptance cases.
|
||||
Record results, commands, skips, source hashes and remaining limits in
|
||||
BUILD.md. Request Sage's slot for the required business, seat, cli, project,
|
||||
bus and webui suites and every scripts/test-*.sh. Do not run them ungranted.
|
||||
- [ ] After applicable tests are green, make the source commit, build the
|
||||
candidate manifest from the authorized pushed tip, and move the row with
|
||||
scripts/mosaic. Sage posts token-requiring requests; Filbert reviews the
|
||||
candidate. Push only when authorized. No merge or live change by Herb.
|
||||
|
||||
## Self-review
|
||||
|
||||
Every brief acceptance item is in T1-T4. Added host support paths match
|
||||
sage-1848/1860. BUILD.md records the complete 14-hit root audit. State shape
|
||||
and authority match sage-1852; the shared read/publication lock follows
|
||||
sage-1860 and Megavolt's agreement. Fetch, timers, outer sync serialization
|
||||
and HTTP stay with their later rows.
|
||||
This is a plan only; no product edits or test execution precede approval.
|
||||
|
||||
|
||||
Landing update: prepared herb/row215-on212 on fefd54e13 (includes row 212
|
||||
landing ee7b2f137), without history replay or stash. Only BUILD-LOG.md and
|
||||
cli/tests/stack-release.test.mjs overlap the a2c72ac95-to-landing change
|
||||
set. BUILD-LOG preserves all landed entries and appends the existing Herb
|
||||
entry. stack-release preserves the landing plus only the library/src copy
|
||||
list addition. No test has run on this landing yet. All further execution
|
||||
requires a Sage grant (supersedes the original COMMON singles rule).
|
||||
|
||||
|
||||
Current merge preparation per sage-1983/1987: new branch
|
||||
herb/row215-on-f827 on f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87.
|
||||
Nine landed overlaps are recorded in current-MERGE.json and the exact
|
||||
candidate deltas against the landing are in current-merge-only.patch.
|
||||
Two textual conflicts were resolved manually: Broker keeps hostKeys and
|
||||
adds library; business.mjs keeps CREATIVE_DEFINITIONS and adds checkMapping.
|
||||
The other seven merges preserve the landing plus the original C2-04 edits.
|
||||
All other product/test paths match the early215 tree byte for byte. The
|
||||
landing's BUILD-LOG is preserved and the existing Herb entry is appended.
|
||||
No history replay, stash, force push, branch deletion or source commit.
|
||||
No test/probe/syntax check ran on the merged tree after the slot was cleared.
|
||||
All16 whole singles need a new Sage grant before candidate commit/review.
|
||||
The10 old-base315/0 results are early reads only, never merged gate evidence.
|
||||
|
||||
|
||||
Candidate status: source commit e333af4dc7af3a9d3789c8c0db26a0df8bdddfee. The16 whole
|
||||
singles passed451/0 under sage-2008 with zero skips/cancellations; raw
|
||||
outputs and merge receipts are in this packet, indexed by EVIDENCE.json
|
||||
and SOURCE.json. Sage keeps the landing gate. Filbert's implementation
|
||||
review and that gate remain pending. Prior315/0 on fefd54e13 is early
|
||||
read evidence only. Sage-2016 authorizes the seat-only source/packet push.
|
||||
@@ -1,157 +0,0 @@
|
||||
{
|
||||
"sourceCommit": "a6101e21c596e2972ab5a7e3087736075899505e",
|
||||
"base": "a3652371338e60187d4e95cee4a0f30f3c8a8f06",
|
||||
"paths": [
|
||||
{
|
||||
"path": "BUILD-LOG.md",
|
||||
"sha256": "b7c8f906f2db095dfe02d29b4064836af83ae877a87b38c09466b8c9a327e019",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/broker.mjs",
|
||||
"sha256": "762234259d72db87aff510751fe14003099759ae37bc8eaf14f1ea1de61d2005",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"sha256": "c759e665514a5bcad40536bc9f979837187fe6523462b3c0a0687182885c3ac6",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/server.mjs",
|
||||
"sha256": "207c7a76752c753ef7380f18f9ce1a4f23e8fa35142973b6358aaf0c45f44899",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/tests/library.test.mjs",
|
||||
"sha256": "58d839709e005571b398a11abda5a50f542bab0e37bd97b72f43cde926434301",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/business.mjs",
|
||||
"sha256": "5fd3fee664d3e70153d988b4c1a42406f888a31b3927fa52375e66619d8cec59",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/cli.mjs",
|
||||
"sha256": "31cfe9090900169416e1207dc6db865b046439273917e9de442add4159c89eb3",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/instance-settings.mjs",
|
||||
"sha256": "3873411688d927336a909d0299acddeba92a653102c660d276471f5a0f6eebd3",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"sha256": "eaa650499d2d078552a2c0e5b13a6126e0aca02f73160032a7325b3f5aa90964",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/resolve.mjs",
|
||||
"sha256": "712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/business.test.mjs",
|
||||
"sha256": "910f924d90b6f9b18c1f36d97cebd0b7a0a15a080b73530c4fb847bfd435fb3f",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/cli.test.mjs",
|
||||
"sha256": "d54ba2338bcdfec22764030cf3ec9e3464ab275b15321d6d1b039169ea37fd85",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/instance-settings.test.mjs",
|
||||
"sha256": "072e25c5237e1be4294c7a4a95daa2ab593832786013e1283b19725c330647c1",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"sha256": "cfc726ec7bf73c1dc9fc6395cba85e374b7a006bac45bd8c47c969550557147f",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/resolve.test.mjs",
|
||||
"sha256": "c74af44a83ee918196e2c1016b62786e757c0ae774c9b1613280d3fbbf3ffb22",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/config.mjs",
|
||||
"sha256": "ab7b9f452123b6f7e98f4f59cbb3cc4483fd296e4af5522412410ee53d1b20e0",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/launcher.mjs",
|
||||
"sha256": "d8a870d8eb8254adfd576688696705359fefbf517b40e5d7482500bf27941022",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/launcher.test.mjs",
|
||||
"sha256": "99234f247e8414120d2fd214efd590e9d573eca86180d7b775cb506ac1c12c78",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release-fixture.mjs",
|
||||
"sha256": "86a3c15446d4c119206097c754cd15f5bef7b7e93c9f16e9d8696ec8c475eea9",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release.test.mjs",
|
||||
"sha256": "46cc95a6e75a89b907cdd5e9bd03853e1d1f75f1ced81084d968c5476466822e",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/trackers-boot.test.mjs",
|
||||
"sha256": "c90493e45bfa09bf0b01600aaf04d6ecd79d939357beacc1a9cd65f958bb7c22",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/index.mjs",
|
||||
"sha256": "ecda99dea46390b81fffa6f414d56a13737233e01d883b82cd186e0e21b6c4d1",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/mirror.mjs",
|
||||
"sha256": "75ce08fba0956c846f2ca9ab1b565974657925f94ac952c720e7308783946480",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/tests/mirror.test.mjs",
|
||||
"sha256": "e96473be70ece8c8232ce5325822244b593f273371b74b4126920654cde9d72c",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/project/src/paths.mjs",
|
||||
"sha256": "bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/project/tests/project.test.mjs",
|
||||
"sha256": "0ebe1862ce70f26c4a6a44304182327f9a6944d16cc87f674fbb1d32e08ac602",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/src/checkout.mjs",
|
||||
"sha256": "859201bd192522e51c33b86ef45f73487b27cdfc48ea7e4e09870e26d056048a",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/tests/checkout.test.mjs",
|
||||
"sha256": "663040d7c737aba6403e6397bacf1325b558cc14df3e5677f0a28f9499c45127",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/src/cli.mjs",
|
||||
"sha256": "e98fd2fe4e621d5b4fa1ed95c4d4585469e7ab7a11dd379dc541dddb1b1a1f02",
|
||||
"mode": "100644"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/tests/library-cli.test.mjs",
|
||||
"sha256": "1983912b76f01f8e6d0c564e3bbcd763c0b2c44044988b192ef827446f98556c",
|
||||
"mode": "100644"
|
||||
}
|
||||
],
|
||||
"priorSourceCommit": "e333af4dc7af3a9d3789c8c0db26a0df8bdddfee"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
packages/bus/tests/library.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/business/tests/business.test.mjs
|
||||
packages/business/tests/cli.test.mjs
|
||||
packages/business/tests/instance-settings.test.mjs
|
||||
packages/business/tests/library-projects-protected.test.mjs
|
||||
packages/business/tests/resolve.test.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/stack-release-external.test.mjs
|
||||
packages/cli/tests/stack-release.test.mjs
|
||||
packages/cli/tests/stack-upgrade.test.mjs
|
||||
packages/cli/tests/trackers-boot.test.mjs
|
||||
packages/library/tests/mirror.test.mjs
|
||||
packages/project/tests/project.test.mjs
|
||||
packages/seat/tests/checkout.test.mjs
|
||||
packages/webui/tests/library-cli.test.mjs
|
||||
@@ -1,229 +0,0 @@
|
||||
{
|
||||
"base": "fefd54e13",
|
||||
"landing": "f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87",
|
||||
"overlaps": [
|
||||
"packages/bus/src/broker.mjs",
|
||||
"packages/bus/src/runtime.mjs",
|
||||
"packages/business/src/business.mjs",
|
||||
"packages/business/src/instance-settings.mjs",
|
||||
"packages/business/tests/business.test.mjs",
|
||||
"packages/business/tests/instance-settings.test.mjs",
|
||||
"packages/cli/src/launcher.mjs",
|
||||
"packages/cli/tests/launcher.test.mjs",
|
||||
"packages/library/src/index.mjs"
|
||||
],
|
||||
"initialConflicts": [
|
||||
"packages/bus/src/broker.mjs",
|
||||
"packages/business/src/business.mjs"
|
||||
],
|
||||
"remainingConflicts": [],
|
||||
"resolutions": {
|
||||
"packages/bus/src/broker.mjs": "retain landed hostKeys constructor parameter and add library parameter",
|
||||
"packages/business/src/business.mjs": "retain landed CREATIVE_DEFINITIONS import and add checkMapping import"
|
||||
},
|
||||
"sourcePaths": [
|
||||
{
|
||||
"path": "packages/bus/src/broker.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "dca11dd58561bf3f399d18d7521aefa93f43e0ee3de9c532c1da073ce5a17466",
|
||||
"sha256": "925b3dd6744565349ec421a58b3374ce3d21181e6c2d3d32ffb99c79271b9450"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "6f69e9fb838cf1d8ee60d1b7090395193d3dbfdc6492a401a4b72c356c371ca9",
|
||||
"sha256": "c759e665514a5bcad40536bc9f979837187fe6523462b3c0a0687182885c3ac6"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/server.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "207c7a76752c753ef7380f18f9ce1a4f23e8fa35142973b6358aaf0c45f44899",
|
||||
"sha256": "207c7a76752c753ef7380f18f9ce1a4f23e8fa35142973b6358aaf0c45f44899"
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/tests/library.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "58d839709e005571b398a11abda5a50f542bab0e37bd97b72f43cde926434301",
|
||||
"sha256": "58d839709e005571b398a11abda5a50f542bab0e37bd97b72f43cde926434301"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/business.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "e132f92211cd35f951e85ff5e90471a2316755cb35ad7eabf516e780ce6c13ad",
|
||||
"sha256": "5fd3fee664d3e70153d988b4c1a42406f888a31b3927fa52375e66619d8cec59"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/cli.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "31cfe9090900169416e1207dc6db865b046439273917e9de442add4159c89eb3",
|
||||
"sha256": "31cfe9090900169416e1207dc6db865b046439273917e9de442add4159c89eb3"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/instance-settings.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "04d61c1ec89a5d67da75aede46c3a8e2197aadd63b11bef8e4fc37d90e8862cf",
|
||||
"sha256": "3873411688d927336a909d0299acddeba92a653102c660d276471f5a0f6eebd3"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "eaa650499d2d078552a2c0e5b13a6126e0aca02f73160032a7325b3f5aa90964",
|
||||
"sha256": "eaa650499d2d078552a2c0e5b13a6126e0aca02f73160032a7325b3f5aa90964"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/resolve.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109",
|
||||
"sha256": "712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/business.test.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "55aafd3f0eea816d5f42283b7b74323dd32a698d7b95dd9cc54529dbf7b16058",
|
||||
"sha256": "910f924d90b6f9b18c1f36d97cebd0b7a0a15a080b73530c4fb847bfd435fb3f"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/cli.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "d54ba2338bcdfec22764030cf3ec9e3464ab275b15321d6d1b039169ea37fd85",
|
||||
"sha256": "d54ba2338bcdfec22764030cf3ec9e3464ab275b15321d6d1b039169ea37fd85"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/instance-settings.test.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "c0959f3af3df653bbf469471d3bbe3f28bc4478cba8ba57910af7f09498c4c3f",
|
||||
"sha256": "072e25c5237e1be4294c7a4a95daa2ab593832786013e1283b19725c330647c1"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "cfc726ec7bf73c1dc9fc6395cba85e374b7a006bac45bd8c47c969550557147f",
|
||||
"sha256": "cfc726ec7bf73c1dc9fc6395cba85e374b7a006bac45bd8c47c969550557147f"
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/resolve.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "c74af44a83ee918196e2c1016b62786e757c0ae774c9b1613280d3fbbf3ffb22",
|
||||
"sha256": "c74af44a83ee918196e2c1016b62786e757c0ae774c9b1613280d3fbbf3ffb22"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/config.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "ab7b9f452123b6f7e98f4f59cbb3cc4483fd296e4af5522412410ee53d1b20e0",
|
||||
"sha256": "ab7b9f452123b6f7e98f4f59cbb3cc4483fd296e4af5522412410ee53d1b20e0"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/launcher.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "2272232dbe6c362eddb23ad903987fd4b8e0ca1eb94dbe93b66b3e785e7d0712",
|
||||
"sha256": "d8a870d8eb8254adfd576688696705359fefbf517b40e5d7482500bf27941022"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/launcher.test.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "38fb51c15764333642d75db7fb358d611e448049cf894b24686ea6cf2cf169c4",
|
||||
"sha256": "99234f247e8414120d2fd214efd590e9d573eca86180d7b775cb506ac1c12c78"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release-fixture.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "86a3c15446d4c119206097c754cd15f5bef7b7e93c9f16e9d8696ec8c475eea9",
|
||||
"sha256": "86a3c15446d4c119206097c754cd15f5bef7b7e93c9f16e9d8696ec8c475eea9"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "aa63fadca8b3a51e7af1ff7560fd2645f3ef56bf4e5625b2d5a5f6946db40996",
|
||||
"sha256": "aa63fadca8b3a51e7af1ff7560fd2645f3ef56bf4e5625b2d5a5f6946db40996"
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/trackers-boot.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "c90493e45bfa09bf0b01600aaf04d6ecd79d939357beacc1a9cd65f958bb7c22",
|
||||
"sha256": "c90493e45bfa09bf0b01600aaf04d6ecd79d939357beacc1a9cd65f958bb7c22"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/index.mjs",
|
||||
"merged": true,
|
||||
"sameAsEarlyTree": false,
|
||||
"earlySha256": "b80e6c27daf908a0e71fcc1e5e8c91d05e857790bd77d92e06ff086ab3623306",
|
||||
"sha256": "ecda99dea46390b81fffa6f414d56a13737233e01d883b82cd186e0e21b6c4d1"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/mirror.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "75ce08fba0956c846f2ca9ab1b565974657925f94ac952c720e7308783946480",
|
||||
"sha256": "75ce08fba0956c846f2ca9ab1b565974657925f94ac952c720e7308783946480"
|
||||
},
|
||||
{
|
||||
"path": "packages/library/tests/mirror.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "e96473be70ece8c8232ce5325822244b593f273371b74b4126920654cde9d72c",
|
||||
"sha256": "e96473be70ece8c8232ce5325822244b593f273371b74b4126920654cde9d72c"
|
||||
},
|
||||
{
|
||||
"path": "packages/project/src/paths.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9",
|
||||
"sha256": "bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"
|
||||
},
|
||||
{
|
||||
"path": "packages/project/tests/project.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "0ebe1862ce70f26c4a6a44304182327f9a6944d16cc87f674fbb1d32e08ac602",
|
||||
"sha256": "0ebe1862ce70f26c4a6a44304182327f9a6944d16cc87f674fbb1d32e08ac602"
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/src/checkout.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "859201bd192522e51c33b86ef45f73487b27cdfc48ea7e4e09870e26d056048a",
|
||||
"sha256": "859201bd192522e51c33b86ef45f73487b27cdfc48ea7e4e09870e26d056048a"
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/tests/checkout.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "663040d7c737aba6403e6397bacf1325b558cc14df3e5677f0a28f9499c45127",
|
||||
"sha256": "663040d7c737aba6403e6397bacf1325b558cc14df3e5677f0a28f9499c45127"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/src/cli.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "e98fd2fe4e621d5b4fa1ed95c4d4585469e7ab7a11dd379dc541dddb1b1a1f02",
|
||||
"sha256": "e98fd2fe4e621d5b4fa1ed95c4d4585469e7ab7a11dd379dc541dddb1b1a1f02"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/tests/library-cli.test.mjs",
|
||||
"merged": false,
|
||||
"sameAsEarlyTree": true,
|
||||
"earlySha256": "1983912b76f01f8e6d0c564e3bbcd763c0b2c44044988b192ef827446f98556c",
|
||||
"sha256": "1983912b76f01f8e6d0c564e3bbcd763c0b2c44044988b192ef827446f98556c"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index 3baa709f9..512d57519 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -90,0 +91 @@ export const PROJECT_FILE_VERBS = Object.freeze(['project.files', 'project.file'
|
||||
+export const LIBRARY_VERBS = Object.freeze(['library.file', 'library.status']);
|
||||
@@ -281,0 +283 @@ export class Broker {
|
||||
+ #library;
|
||||
@@ -297 +299 @@ export class Broker {
|
||||
- constructor({ store, businesses, secretCheck = () => {}, credentialStatus = () => [], organization = null, project = null, usage = null, limits = null, harnessOn = null, credentialVerbs = null, hostGrant = null, hostKeys = null }) {
|
||||
+ constructor({ store, businesses, secretCheck = () => {}, credentialStatus = () => [], organization = null, project = null, library = null, usage = null, limits = null, harnessOn = null, credentialVerbs = null, hostGrant = null, hostKeys = null }) {
|
||||
@@ -308,0 +311 @@ export class Broker {
|
||||
+ this.#library = library;
|
||||
@@ -2189,0 +2193,2 @@ export class Broker {
|
||||
+ if (LIBRARY_VERBS.includes(request.verb))
|
||||
+ return this.#requestLibrary(s, { verb: request.verb, args: structuredClone(args) });
|
||||
@@ -2438,0 +2444,20 @@ export class Broker {
|
||||
+ // C2-04 M4: only a verified human reads library text or status. Host Git
|
||||
+ // functions stay injected, preserving this module's sandbox import closure.
|
||||
+ async #requestLibrary(s, request) {
|
||||
+ const { verb, args } = request;
|
||||
+ try {
|
||||
+ this.#human(s);
|
||||
+ const fields = verb === 'library.file' ? ['project', 'path'] : ['project'];
|
||||
+ keys(args, fields, fields);
|
||||
+ if (!this.#library?.readFile || !this.#library?.status) fail('project-not-configured');
|
||||
+ const context = { business: this.#business(s.business), project: args.project };
|
||||
+ const result = verb === 'library.file'
|
||||
+ ? await this.#library.readFile({ ...context, path: args.path })
|
||||
+ : await this.#library.status(context);
|
||||
+ this.#secretCheck(result);
|
||||
+ return result;
|
||||
+ } catch (error) {
|
||||
+ const Failure = this.#library?.LibraryError;
|
||||
+ throw this.#refused(s, Failure && error instanceof Failure ? new BusError(error.code) : error, request);
|
||||
+ }
|
||||
+ }
|
||||
diff --git a/packages/bus/src/runtime.mjs b/packages/bus/src/runtime.mjs
|
||||
index f81f956f2..e265ff5d1 100644
|
||||
--- a/packages/bus/src/runtime.mjs
|
||||
+++ b/packages/bus/src/runtime.mjs
|
||||
@@ -5,0 +6 @@ import * as projectModule from '../../project/src/index.mjs';
|
||||
+import * as libraryModule from '../../library/src/index.mjs';
|
||||
@@ -95 +96 @@ export async function startBroker({
|
||||
- ...Object.values(businesses).flatMap((b) => Object.values(b.projects ?? {}).map((p) => p.root)),
|
||||
+ ...Object.values(businesses).flatMap((b) => Object.values(b.projects ?? {}).filter(p => p.kind !== 'library').map((p) => p.root)),
|
||||
@@ -130,0 +132,5 @@ export async function startBroker({
|
||||
+ // C2-04: mirrors are host state, never session checkouts. An unsafe
|
||||
+ // existing mirror refuses startup before a socket can become ready.
|
||||
+ for (const business of Object.values(businesses))
|
||||
+ for (const [project, entry] of Object.entries(business.projects ?? {}))
|
||||
+ if (entry.kind === 'library') await libraryModule.ensureMirror({ business, project, dataRoot });
|
||||
@@ -138,0 +145,5 @@ export async function startBroker({
|
||||
+ library: {
|
||||
+ readFile: context => libraryModule.readLibraryFile({ ...context, dataRoot }),
|
||||
+ status: context => libraryModule.libraryStatus({ ...context, dataRoot }),
|
||||
+ LibraryError: libraryModule.LibraryError,
|
||||
+ },
|
||||
diff --git a/packages/business/src/business.mjs b/packages/business/src/business.mjs
|
||||
index d08a4f52e..e8337ea2b 100644
|
||||
--- a/packages/business/src/business.mjs
|
||||
+++ b/packages/business/src/business.mjs
|
||||
@@ -12,0 +13 @@ import { checkPlugins } from "../../plugins/src/kinds.mjs";
|
||||
+import { checkMapping } from "../../library/src/mapping.mjs";
|
||||
@@ -241,0 +243,4 @@ export function validateBusinessDocument(document, file, { rolesDir }) {
|
||||
+ if (entry.kind === 'library') {
|
||||
+ projects[id] = checkMapping(entry, `${file} projects.${id}`, { fail: (code, message) => refuse(`${code}: ${message}`) });
|
||||
+ continue;
|
||||
+ }
|
||||
@@ -257,0 +263 @@ export function validateBusinessDocument(document, file, { rolesDir }) {
|
||||
+ if (projects[project].kind === 'library') refuse(`${file} roles.${instance}.publish names library project ${project}; library repositories cannot be published by agents`);
|
||||
diff --git a/packages/business/src/instance-settings.mjs b/packages/business/src/instance-settings.mjs
|
||||
index ff3a6d9d3..50cc36edc 100644
|
||||
--- a/packages/business/src/instance-settings.mjs
|
||||
+++ b/packages/business/src/instance-settings.mjs
|
||||
@@ -149,0 +150 @@ export function instanceSettings({ dir, rolesDir, system, levels = () => null })
|
||||
+ if (entry.kind === 'library') continue;
|
||||
diff --git a/packages/business/tests/business.test.mjs b/packages/business/tests/business.test.mjs
|
||||
index b64659fa1..0f214a005 100644
|
||||
--- a/packages/business/tests/business.test.mjs
|
||||
+++ b/packages/business/tests/business.test.mjs
|
||||
@@ -10,0 +11,30 @@ import { launchDoc, businessDoc, REPO, REPO_ROLES, rolesCopy, tmp, writeJson } f
|
||||
+test('C2-04: library mappings load without roots, remain frozen, and retain mapping refusals', async t => {
|
||||
+ const { mappingEntry } = await import('../../library/tests/helpers.mjs');
|
||||
+ const { rmSync } = await import('node:fs');
|
||||
+ const root = tmp(); t.after(() => rmSync(root, { recursive: true, force: true }));
|
||||
+ const doc = businessDoc(root), file = join(root, 'businesses/acme.json');
|
||||
+ doc.projects = { books: mappingEntry(), ...doc.projects };
|
||||
+ const loaded = validateBusinessDocument(doc, file, { rolesDir: REPO_ROLES });
|
||||
+ const { checkMapping } = await import('../../library/src/mapping.mjs');
|
||||
+ assert.deepEqual(loaded.projects.books, checkMapping(mappingEntry()));
|
||||
+ assert.equal(loaded.projects.books.root, undefined);
|
||||
+ assert.ok(Object.isFrozen(loaded.projects.books.universes.harbor.books));
|
||||
+ const only = structuredClone(doc); delete only.projects.stack;
|
||||
+ assert.deepEqual(Object.keys(validateBusinessDocument(only, file, { rolesDir: REPO_ROLES }).projects), ['books']);
|
||||
+ doc.projects.books.universes.harbor.playground = ['Elsewhere/Playground/'];
|
||||
+ refuses(() => validateBusinessDocument(doc, file, { rolesDir: REPO_ROLES }), /library-playground-outside-book/);
|
||||
+ doc.projects.books = { ...mappingEntry(), root: '/forbidden' };
|
||||
+ refuses(() => validateBusinessDocument(doc, file, { rolesDir: REPO_ROLES }), /library-mapping-invalid/);
|
||||
+});
|
||||
+
|
||||
+test('C2-04: an otherwise valid publish grant cannot name a library repo', async t => {
|
||||
+ const { mappingEntry } = await import('../../library/tests/helpers.mjs');
|
||||
+ const { rmSync } = await import('node:fs');
|
||||
+ const root = tmp(); t.after(() => rmSync(root, { recursive: true, force: true }));
|
||||
+ const doc = businessDoc(root);
|
||||
+ doc.projects.books = { ...mappingEntry(), remote: 'https://git.example/writer/books' };
|
||||
+ doc.roles.coder.identity = { name: 'Coder', email: '[email protected]', gitea: { url: 'https://git.example', user: 'acme-coder' } };
|
||||
+ doc.roles.coder.publish = ['books'];
|
||||
+ refuses(() => validateBusinessDocument(doc, join(root, 'businesses/acme.json'), { rolesDir: REPO_ROLES }), /publish.*library/);
|
||||
+});
|
||||
+
|
||||
diff --git a/packages/business/tests/instance-settings.test.mjs b/packages/business/tests/instance-settings.test.mjs
|
||||
index 6b19f9e89..a6c8fe665 100644
|
||||
--- a/packages/business/tests/instance-settings.test.mjs
|
||||
+++ b/packages/business/tests/instance-settings.test.mjs
|
||||
@@ -22,0 +23,10 @@ const LEVELS = { pi: ["off", "minimal", "low", "medium", "high", "xhigh", "max"]
|
||||
+test('C2-04: instance settings skip a library while checking a later code project', async () => {
|
||||
+ const { mappingEntry } = await import('../../library/tests/helpers.mjs');
|
||||
+ const f = fixture(doc => { doc.projects = { books: mappingEntry(), ...doc.projects }; });
|
||||
+ writeJson(projectFilePath(f.doc.projects.stack.root), { projectVersion: 1, id: 'stack', vars: { 'tracker.project': 3 } });
|
||||
+ const before = f.settings.read('acme');
|
||||
+ f.settings.set('acme', { revision: before.revision, instance: 'gate-215', op: 'add', definition: 'merge-gate' }, 'jason');
|
||||
+ assert.deepEqual(JSON.parse(readFileSync(f.file, 'utf8')).projects.books, mappingEntry());
|
||||
+ assert.ok(f.settings.read('acme').instances['gate-215']);
|
||||
+});
|
||||
+
|
||||
diff --git a/packages/cli/src/launcher.mjs b/packages/cli/src/launcher.mjs
|
||||
index 604cef203..c721ee9e8 100644
|
||||
--- a/packages/cli/src/launcher.mjs
|
||||
+++ b/packages/cli/src/launcher.mjs
|
||||
@@ -354 +354 @@ export function createLauncher({
|
||||
- checkouts = await ensureCheckouts({ workspace, projects: b.projects, env });
|
||||
+ checkouts = await ensureCheckouts({ workspace, projects: Object.fromEntries(Object.entries(b.projects).filter(([, entry]) => entry.kind !== 'library')), env });
|
||||
diff --git a/packages/cli/tests/launcher.test.mjs b/packages/cli/tests/launcher.test.mjs
|
||||
index 3b663ba94..4636df3de 100644
|
||||
--- a/packages/cli/tests/launcher.test.mjs
|
||||
+++ b/packages/cli/tests/launcher.test.mjs
|
||||
@@ -32,0 +33,10 @@ const skip = sandboxProblem() ?? false;
|
||||
+test('C2-04: launcher workspace clones code but never the library', { skip, timeout: 30000 }, async t => {
|
||||
+ const { mappingEntry } = await import('../../library/tests/helpers.mjs');
|
||||
+ const f = await setup(t, doc => { doc.projects = { books: mappingEntry(), ...doc.projects }; return doc; });
|
||||
+ await f.launcher.launchPm();
|
||||
+ const workspace = workspaceDir(f.f.dataRoot, 'acme', 'chief');
|
||||
+ assert.equal(existsSync(join(workspace, 'stack', '.git')), true);
|
||||
+ assert.equal(existsSync(join(workspace, 'books')), false);
|
||||
+ assert.equal(await f.close(), 0);
|
||||
+});
|
||||
+
|
||||
diff --git a/packages/library/src/index.mjs b/packages/library/src/index.mjs
|
||||
index f64d77860..53ce5cb43 100644
|
||||
--- a/packages/library/src/index.mjs
|
||||
+++ b/packages/library/src/index.mjs
|
||||
@@ -8,0 +9 @@ export { survey, formatSurvey, surveyMain } from './survey.mjs';
|
||||
+export { SYNC_STATE_FILE, mirrorPath, ensureMirror, withLibraryLock, servedCommit, readSyncState, libraryStatus, readLibraryFile } from './mirror.mjs';
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-04 M4: both verbs reject every agent before arguments or adapter access (30.144386ms)
|
||||
✔ C2-04 bus: human reads validate keys and return adapter results without path leakage (11.434614ms)
|
||||
✔ C2-04 socket: each async library verb resolves its result rather than serializing {} (17.684117ms)
|
||||
✔ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (45.253455ms)
|
||||
✔ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (23.246812ms)
|
||||
✔ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (107.052077ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 359.869493
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
✔ Broker keeps the sandbox client import closure: only the listed imports, no lazy project import (2.265255ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (57.448982ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (102.784823ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 312.717335
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
✔ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (12.852402ms)
|
||||
✔ C2-04: an otherwise valid publish grant cannot name a library repo (2.693014ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (0.229245ms)
|
||||
✔ the fixture business validates and comes back frozen (1.006969ms)
|
||||
✔ two instances may share a definition (0.94271ms)
|
||||
✔ top-level refusals (3.474817ms)
|
||||
✔ arbiters and projects (5.543282ms)
|
||||
✔ role instances (2.7386ms)
|
||||
✔ Vikunja bots (6.181044ms)
|
||||
✔ a role without Vikunja takes no tracker block (5.900981ms)
|
||||
✔ credential references match the definition's services (3.012597ms)
|
||||
✔ launch (8.561546ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (6.420869ms)
|
||||
✔ loadBusiness: file checks (2.241353ms)
|
||||
✔ loadBusiness: not a regular file (46.573969ms)
|
||||
✔ loading writes nothing (2.802338ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (3.291238ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (1.195924ms)
|
||||
✔ persona vars: agent layer, creative definition only, both or neither (9.0736ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 19
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 199.91256
|
||||
@@ -1,18 +0,0 @@
|
||||
✔ C2-04: business validate and resolve skip a library before code projects and credential checks (235.663956ms)
|
||||
✔ usage errors exit 4 (325.805811ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (69.331646ms)
|
||||
✔ validate: project files (344.919464ms)
|
||||
✔ validate: missing files and a broken system config (252.779029ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (66.663076ms)
|
||||
✔ validate: a token file inside the repository is refused (78.714732ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (201.487424ms)
|
||||
✔ resolve: prints one instance's record (281.684478ms)
|
||||
✔ resolve: refusals (454.610462ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 10
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2381.258516
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
✔ C2-04: instance settings skip a library while checking a later code project (32.527878ms)
|
||||
✔ row 165 read lists each instance and the definitions add accepts (3.218296ms)
|
||||
✔ row 165 add: two instances join, validate exits 0, the log names the human, and the bus restart is reported (93.702292ms)
|
||||
✔ row 165 change: definition, vars and launch membership log before and after; only a definition change asks for a restart (99.793939ms)
|
||||
✔ row 165 refuses each validation failure and leaves the file's bytes alone (33.820979ms)
|
||||
✔ row 165 refuses an added instance whose definition declares credentials, and says why (5.999086ms)
|
||||
✔ row 165 refuses a definition change to or from one that declares credentials (6.767714ms)
|
||||
✔ row 165 a vars or launch change on an instance with its binding succeeds and keeps the binding (89.83786ms)
|
||||
✔ row 165 refuses an END_PROTECTED definition and every change to a protected instance (9.793219ms)
|
||||
✔ row 165 refuses while a project file doesn't resolve, as validate would (15.487298ms)
|
||||
✔ row 165 refuses a stale revision and leaves the file's bytes alone (10.871014ms)
|
||||
✔ row 65 an instance write refuses harness-off, thinking-unsupported, an unknown model and a partial fallback (38.02395ms)
|
||||
✔ row 213 a creative instance is the human's: add, vars and definition changes, persona digest only (90.045141ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 608.08011
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
✔ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (23.242034ms)
|
||||
✔ C2-04 M9: code projects, additions, deletions and array changes are protected too (15.756145ms)
|
||||
✔ C2-04 M9: canonical key order is allowed and a non-project setter still records its change (17.060499ms)
|
||||
✔ C2-04 M9: a serialization hook cannot change projects after the canonical comparison (9.833495ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 118.54831
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
✔ C2-04: a library first in projects does not hide a later project layer (9.584516ms)
|
||||
✔ systemVars flattens the validated config (1.063324ms)
|
||||
✔ precedence: system, business, project, project role, agent (2.001802ms)
|
||||
✔ limits narrow the definition and never widen it (2.563505ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (5.04696ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (2.106162ms)
|
||||
✔ limits.authority narrows cross-role actions too (1.098761ms)
|
||||
✔ classify (1.065895ms)
|
||||
✔ the record carries what the broker and launcher need (0.966677ms)
|
||||
✔ digest: key order doesn't matter, any value change does (7.43546ms)
|
||||
✔ refusals (2.150825ms)
|
||||
ℹ tests 11
|
||||
ℹ suites 0
|
||||
ℹ pass 11
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 94.022587
|
||||
@@ -1,54 +0,0 @@
|
||||
✔ C2-04: launcher workspace clones code but never the library (1298.398732ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1264.618734ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4accc4841d41","instance":"chief","turn":"81814ac7-9330-484a-95f8-cc2f80a9aeef","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r0719029c31b1","instance":"coder","turn":"fd2dfc33-9ab6-4d4d-9eef-ba46b6d7a510","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (657.713119ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4b37f983290f","instance":"chief","turn":"6c8768d3-4742-4ae2-87c6-4653182c8520","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r7bc8dc8db66c","instance":"pm","turn":"4b196787-1bf9-4702-82d2-397c84ab1e3c","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4b37f983290f","instance":"chief","turn":"1c6ec26d-97da-43b6-8cd8-91994e6c7c7b","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r7bc8dc8db66c","instance":"pm","turn":"a12fdeb9-e25d-45a4-bd25-e048621a3557","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r7bc8dc8db66c","instance":"pm","turn":"ad419687-0675-48a8-9932-90b2da5333ef","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4b37f983290f","instance":"chief","turn":"0d54926f-f5b8-4dbb-b38a-8ea23fdd5cb5","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r7bc8dc8db66c","instance":"pm","turn":"6891e20c-472e-4e67-815e-88728024acf4","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4b37f983290f","instance":"chief","turn":"9ac6fe37-9044-4f54-bae0-826a6c84c15b","source":"@none","code":"baseline-unknown"}
|
||||
✔ a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold (1202.248105ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3926.301471ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (593.731622ms)
|
||||
✔ REQ-LAUNCH-1 the tick starts a listed merge decision holder once, with land_work, the Landing line and its landing turn; an unlisted holder starts nothing (755.589469ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf7ecf1ef2b65","instance":"coder","turn":"744cb116-e163-4b18-831e-556df7e7bfd9","source":"@none","code":"baseline-unknown"}
|
||||
✔ a holder running since before the resolution is stopped once the broker releases it, land-relaunch, and the next tick starts it: landing turn first, then the message that waited (739.551352ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (564.790867ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (883.94802ms)
|
||||
✔ a refused landing start is logged once per code with its decision, isn't a start, and the next tick with room starts the holder (595.491854ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (250.651304ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (336.620423ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (172.971844ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (287.021469ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row215-on-f827/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row215-on-f827/packages/plugins/harness/down is missing","kept":[]}
|
||||
✔ row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason (327.373038ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (381.927989ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (198.778768ms)
|
||||
✔ row 64 a role skill that isn't enabled refuses skill-not-enabled, and one that isn't a plain directory skill-refused, before anything starts (184.44803ms)
|
||||
✔ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (239.197527ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (230.64829ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r800039251a09","instance":"chief","turn":"f2e6a1ad-767e-4316-be90-6194b840e2ef","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rfeeb081c2983","instance":"coder","turn":"1abdb906-521d-4100-897b-f5eba12663cf","source":"@none","code":"baseline-unknown"}
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1612.164523ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (909.716449ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3844.434582ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (224.265713ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (193.925449ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1181.783938ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (166.842635ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (171.101521ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (170.266667ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1305.753454ms)
|
||||
ℹ tests 31
|
||||
ℹ suites 0
|
||||
ℹ pass 31
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 24989.261794
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
✔ row 232: confirm, revert, gate, --to and --expect-from need --units external; the user-only flags are usage under it (1129.148785ms)
|
||||
✔ row 232: pm-on and activate --pm-after-harness refuse external-pm (1112.631619ms)
|
||||
✔ row 232: units-running (N4) refuses while a unit is active and leaves the store, the log and TAKEN; failed counts as down (2301.278572ms)
|
||||
✔ row 232: activate stages: the pointer stays, AWAITING-UNITS names TO, a backup of the stopped store, no directory in the set, no --user, no journal (2229.906955ms)
|
||||
✔ row 232: A3 order: capture-failed and marker-failed refuse with exit 3 and leave no marker or FAILED (1913.7476ms)
|
||||
✔ row 232: confirm and revert refuse open-activation with no marker, two, the wrong copy, or one the log holds closed; refusals name no activation (3892.845676ms)
|
||||
✔ row 232: confirm polls: bus status good after 3 s fails with --timeout 1, writes FAILED and leaves the rest; FAILED then refuses activation-failed (3703.021367ms)
|
||||
✔ row 232: confirm polls to a pass with --timeout 10: the pointer, an ok line that reads as the started run, no marker (6350.955178ms)
|
||||
✔ row 232: stale-start: @1792540799 fails a start floor of 1792540800 with stale-start (3365.187863ms)
|
||||
✔ row 232: stale-start is a gate code: an enter time that turns to @1792540800 after 2 s passes with --timeout 10 (4713.287991ms)
|
||||
✔ row 232: gate (N2, A2f): --since 1792540800 passes @1792540800 and fails @1792540799; it writes nothing (3014.18649ms)
|
||||
✔ row 232: the external PM check reads launches list: one live run of launch.by since the start passes (7715.019003ms)
|
||||
✔ row 232: revert puts the wrapper back and leaves the store when nothing migrated (1540.240269ms)
|
||||
✔ row 232: confirm --rollback refuses rollback-mismatch, and logs rollback-failed with exit 2 when OLD fails its gate (3838.859298ms)
|
||||
✔ row 232: confirm --rollback after a --restore swap logs rollbackCode not-attempted; rollback --restore finds an external backup (4385.316411ms)
|
||||
✔ row 232: sequence 1: activate, confirm times out, revert, confirm --rollback --cause A5: gate-failed rollback ok (5668.17255ms)
|
||||
✔ row 232: sequence 2: activate --migrate, the wrapper install fails, revert restores TAKEN, confirm --rollback --cause A3 (3356.512703ms)
|
||||
✔ row 232: sequence 3: activate, root's A4 fails, revert, confirm --rollback --cause A4: failed code units-start (3090.998502ms)
|
||||
✔ row 232: sequence 4: a capture failure leaves nothing open, then A2f's gate OLD writes nothing (2006.820211ms)
|
||||
✔ row 232: sequence 5: a confirm of the wrong copy is refused, and revert and confirm --rollback still close the activation (3716.790879ms)
|
||||
✔ row 232: sequence 6: a revert that fails leaves the activation open, and the next --plan refuses interrupted-run (2084.865556ms)
|
||||
✔ row 232: sequence 7: adopt, two confirmed activates, rollback --to the previous copy, confirmed, logs op rollback (8859.407093ms)
|
||||
✔ row 232: sequence 8: a migration that writes and fails: revert restores the backup byte for byte, confirm --rollback --cause A3 (4066.89509ms)
|
||||
✔ row 232: user mode: every systemctl call carries --user, and activate, rollback and check make the base's calls (8472.325246ms)
|
||||
✔ row 232: user mode: a default activate --plan prints the base's bytes (2725.266801ms)
|
||||
ℹ tests 25
|
||||
ℹ suites 0
|
||||
ℹ pass 25
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 96332.465778
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
✔ T1 adopt writes the pointer from the units once; a failing check refuses check-failed (1604.406515ms)
|
||||
✔ T2 activate installs exactly the pointer's pm, claude and Console flags (2285.234425ms)
|
||||
▶ T3 a hand-edited unit refuses unit-flags-drift, names the difference and changes nothing
|
||||
✔ pm (1074.84155ms)
|
||||
✔ claude (1048.597035ms)
|
||||
✔ console (1069.472197ms)
|
||||
✔ T3 a hand-edited unit refuses unit-flags-drift, names the difference and changes nothing (3193.872973ms)
|
||||
▶ T4 each item 3 refusal changes nothing and logs one line with its code
|
||||
✔ copy-missing (970.101799ms)
|
||||
✔ copy-unreachable (976.867501ms)
|
||||
✔ copy-schema-unknown (942.411453ms)
|
||||
✔ already-active (966.01391ms)
|
||||
✔ instance-busy (another business active) (1033.865857ms)
|
||||
✔ instance-busy (this business activating) (989.106934ms)
|
||||
✔ drop-in-override (1051.252734ms)
|
||||
✔ no-pointer (535.256184ms)
|
||||
✔ T4 each item 3 refusal changes nothing and logs one line with its code (7466.71817ms)
|
||||
✔ T5 an activate with no migration stops the Console then the bus, installs, starts the bus then the Console (2298.616234ms)
|
||||
✔ T6 a migration without --migrate rolls back with migration-needs-flag (2085.91559ms)
|
||||
✔ T7 --migrate takes the backup before the migration runs (2415.592569ms)
|
||||
✔ T8 a failed migration restores the backup and keeps the store it replaced (2571.261148ms)
|
||||
✔ T9 a store outside the target's chain rolls back with store-newer (2405.058696ms)
|
||||
▶ T10 each gate check failing alone rolls back and puts every file back
|
||||
✔ units-inactive (5907.690999ms)
|
||||
✔ bus-status (6093.058453ms)
|
||||
✔ healthz (6393.330472ms)
|
||||
✔ copy-check (5442.480521ms)
|
||||
✔ pm-launch-unconfirmed (5607.705975ms)
|
||||
✔ T10 each gate check failing alone rolls back and puts every file back (29445.44482ms)
|
||||
▶ T10b the PM check needs exactly one launched line for a live run of this start
|
||||
✔ no launched line (5534.978468ms)
|
||||
✔ two lines (5372.975087ms)
|
||||
✔ a changed word (5420.826895ms)
|
||||
✔ run not in launches list (5601.520776ms)
|
||||
✔ run started before the start (5448.208485ms)
|
||||
✔ a human launch with no journal line (5346.70067ms)
|
||||
✔ run for another business (5684.948726ms)
|
||||
✔ run not live (5860.307931ms)
|
||||
✔ one well-formed line and a live run pass (2078.4402ms)
|
||||
✔ T10b the PM check needs exactly one launched line for a live run of this start (46350.52861ms)
|
||||
✔ T11 a rollback whose gate fails too: rollback-failed, exit 2, both units stopped, no retry (7145.208417ms)
|
||||
✔ T12 rollback takes the previous copy from the log (3164.021139ms)
|
||||
✔ T13 a rollback across a migration needs --restore, then restores and goes live (3796.056873ms)
|
||||
✔ T14 events written after the backup need --events N with the right N (4384.802883ms)
|
||||
✔ T14b a rollback --restore whose gate fails stops both units and skips item 6 (5813.087127ms)
|
||||
✔ T14c a rollback without --restore whose gate fails runs item 6 (6237.609182ms)
|
||||
✔ T15 --plan names the migration and the restore and changes nothing (2849.139286ms)
|
||||
✔ T26 --plan lists the commits an activate adds, after the migration lines (1481.868533ms)
|
||||
✔ T27 --plan names each migration step, or says the steps cannot be read (1173.748951ms)
|
||||
✔ T25 --plan refuses copies-unrelated when neither copy is an ancestor of the other (569.344968ms)
|
||||
▶ T23 --plan reads the store without changing a file, stopped or held
|
||||
✔ stopped store (721.626407ms)
|
||||
✔ held store (690.820461ms)
|
||||
✔ T23 --plan reads the store without changing a file, stopped or held (1413.175682ms)
|
||||
✔ T24 business-mismatch and capture-failed refuse with exit 3; a short id is a usage error (1463.46361ms)
|
||||
✔ T16 status prints the pointer, the log, the check, bus status and drift, and writes nothing (910.07629ms)
|
||||
✔ T19 a started line with no final line: status shows it and every changing verb refuses (1271.59212ms)
|
||||
✔ T20 a held run lock refuses run-locked without a log line; status and --plan still run (1515.929929ms)
|
||||
✔ T21 a bus unit with no MOSAIC_CLAUDE_BIN: adopt and activate refuse no-claude-pin (1789.2511ms)
|
||||
▶ T22 the stopped store read: a -wal or -shm refuses store-unclean and is left alone; a clean read adds no file
|
||||
✔ bus.sqlite-wal (1954.988144ms)
|
||||
✔ bus.sqlite-shm (2042.456191ms)
|
||||
✔ clean (2209.768749ms)
|
||||
✔ T22 the stopped store read: a -wal or -shm refuses store-unclean and is left alone; a clean read adds no file (6208.13226ms)
|
||||
▶ T28 a unit path, drop-in directory or drop-in file that cannot be read, or a relative unit path, refuses drop-in-override before any stop
|
||||
✔ unit path (938.058563ms)
|
||||
✔ drop-in directory (934.896589ms)
|
||||
✔ drop-in file (958.129787ms)
|
||||
✔ relative unit path (943.563721ms)
|
||||
✔ T28 a unit path, drop-in directory or drop-in file that cannot be read, or a relative unit path, refuses drop-in-override before any stop (3775.662901ms)
|
||||
▶ T29 a bus that stops during the held-store read: --plan says so, rollback --restore refuses restore-mismatch
|
||||
✔ --plan (932.393863ms)
|
||||
✔ rollback --restore (2879.958858ms)
|
||||
✔ T29 a bus that stops during the held-store read: --plan says so, rollback --restore refuses restore-mismatch (3812.923223ms)
|
||||
✔ T30 a copy check that agrees on another copy fails the gate with copy-check and rolls back (6646.085499ms)
|
||||
▶ T31 a quoted or escaped Environment= or ExecStart= is unreadable: refusals by name, nothing read from /a
|
||||
✔ Environment double quotes (1976.227811ms)
|
||||
✔ Environment single quotes (2063.211816ms)
|
||||
✔ Environment backslash (2038.183771ms)
|
||||
✔ ExecStart quotes (1984.451614ms)
|
||||
✔ Console ExecStart quotes (1980.466835ms)
|
||||
✔ T31 a quoted or escaped Environment= or ExecStart= is unreadable: refusals by name, nothing read from /a (10043.710809ms)
|
||||
▶ T32 item 1: --pm-after-harness refuses a target without harness or a file that sets it, and passes without the PM
|
||||
✔ usage: not with --pm, and only for activate (721.955423ms)
|
||||
✔ pm-after-harness-target (1015.757752ms)
|
||||
✔ pm-after-harness-set (1371.242025ms)
|
||||
✔ a pointer without pm (841.537689ms)
|
||||
✔ phase 1 installs without --pm, skips pm_launched and writes the pending pointer (1915.010297ms)
|
||||
✔ T32 item 1: --pm-after-harness refuses a target without harness or a file that sets it, and passes without the PM (5866.555622ms)
|
||||
▶ T33 item 2: read_pointer takes pmPending only as true beside pm false; a pending pointer refuses activate and shows in status
|
||||
✔ read_pointer (1570.154285ms)
|
||||
✔ pm-pending, already-adopted and the status line (3037.065347ms)
|
||||
✔ T33 item 2: read_pointer takes pmPending only as true beside pm false; a pending pointer refuses activate and shows in status (4607.778248ms)
|
||||
▶ T34 item 3: pm-on refuses before any stop, passes with the PM, or puts the phase-1 bus back
|
||||
✔ not-pending (719.010856ms)
|
||||
✔ harness-unset (2272.485716ms)
|
||||
✔ a launched line passes: the bus alone restarts with --pm (3276.598137ms)
|
||||
✔ a failed pm_launched puts the phase-1 unit back: exit 1, still pending (6693.543553ms)
|
||||
✔ a failed phase-1 gate too: pm-on-down, exit 2, both units stopped (8141.636634ms)
|
||||
✔ T34 item 3: pm-on refuses before any stop, passes with the PM, or puts the phase-1 bus back (21104.286659ms)
|
||||
▶ T35 item 4: rollback from pending installs --pm; a plug-in kind the target lacks refuses by name
|
||||
✔ rollback from pending gates pm_launched on the old copy (3372.092831ms)
|
||||
✔ after the harness set, rollback refuses until harness is gone (5046.857905ms)
|
||||
✔ activate names every kind the target lacks (1244.308621ms)
|
||||
✔ T35 item 4: rollback from pending installs --pm; a plug-in kind the target lacks refuses by name (9663.997607ms)
|
||||
✔ T36 --plan shows the pending state and lists the row 169 refusals it can see (3695.067003ms)
|
||||
✔ T37 tester-port activate writes pointer and unit, replaces the port, and supported re-pin and rollback keep it (6897.072525ms)
|
||||
✔ T38 tester-port rollback to unsupported target drops flag in plan, steps, unit and pointer (3812.546819ms)
|
||||
✔ T39 tester-port explicit unsupported target reads target copy and refuses before stopping either unit (904.276249ms)
|
||||
✔ T40 tester-port invalid values refuse exit 4 before stopping, including tunnel and main ports (819.160889ms)
|
||||
✔ T41 tester-port inherited activate to unsupported target drops it and retains drift refusal and failed-run recovery (8462.827367ms)
|
||||
✔ T42 tester-port pm-on preserves pointer Console flags (3200.83272ms)
|
||||
▶ T43 row 180 item 1: runs in one second get distinct activation ids, rollback sets and post-attempt stores
|
||||
✔ activate then pm-on on the same copy (3520.417628ms)
|
||||
✔ two restores: an old-form id and a suffixed one, each with its own post-attempt store (6507.524064ms)
|
||||
✔ adopt takes the next free id too (703.050442ms)
|
||||
✔ all ten names taken: capture-failed before anything stops, and the log line names no activation (956.29941ms)
|
||||
✔ --restore takes an id with or without -1 to -9 and nothing else (971.565868ms)
|
||||
✔ T43 row 180 item 1: runs in one second get distinct activation ids, rollback sets and post-attempt stores (12659.952034ms)
|
||||
▶ T44 row 180 item 2: --plan lists tester-port-invalid and tester-port-target with its other refusals
|
||||
✔ a bad tester port (1970.260005ms)
|
||||
✔ without --plan a bad port is usage before any pointer read (650.605696ms)
|
||||
✔ a target Console without --tester-port (1005.8136ms)
|
||||
✔ T44 row 180 item 2: --plan lists tester-port-invalid and tester-port-target with its other refusals (3627.354723ms)
|
||||
▶ T45 row 181 items 2 and 3: the restore guard counts events and every COUNTED table
|
||||
✔ both modes count events and each listed table, and a table the store lacks counts 0 (817.850391ms)
|
||||
✔ one instance_names row and no event refuses before any stop; --events 1 restores (4258.491111ms)
|
||||
✔ one usage_records row and no event refuses before any stop; --events 1 restores (4200.77682ms)
|
||||
✔ a listed table that cannot be read refuses restore-mismatch before any stop (2308.610496ms)
|
||||
✔ the in-run recount counts the listed tables too (3113.596786ms)
|
||||
✔ T45 row 181 items 2 and 3: the restore guard counts events and every COUNTED table (14700.29833ms)
|
||||
✔ T46 row 181 item 4: every table in the bus schema is in exactly one of four lists (3.037176ms)
|
||||
✔ T47 row 185 test 1: a same-schema activate leaves a whole backup and the log line names it (1868.973993ms)
|
||||
✔ T48 row 185 test 2: a gate failure on a same-schema activate rolls back without a restore (5804.760552ms)
|
||||
▶ T49 row 185 test 3: a same-schema rollback --restore restores, or refuses rows written after STAMP
|
||||
✔ no rows after STAMP: restores and goes live (3320.288695ms)
|
||||
✔ one instance_names row after STAMP refuses post-backup-events; --events 1 restores (3651.108762ms)
|
||||
✔ T49 row 185 test 3: a same-schema rollback --restore restores, or refuses rows written after STAMP (6972.06843ms)
|
||||
✔ T50 row 185 test 4: activate --plan prints the backup line and writes nothing (2352.202566ms)
|
||||
✔ T51 row 185 test 5: an activate with no store file takes no backup (2180.71818ms)
|
||||
▶ T52 row 186: the activate plan's backup line says what the run will do
|
||||
✔ same schema (2482.119077ms)
|
||||
✔ same schema with --migrate (2194.383877ms)
|
||||
✔ in chain with --migrate (2161.378827ms)
|
||||
✔ in chain without --migrate (1945.096692ms)
|
||||
✔ outside the chain (1933.991036ms)
|
||||
✔ outside the chain with --migrate (1982.219098ms)
|
||||
✔ T52 row 186: the activate plan's backup line says what the run will do (12700.35568ms)
|
||||
✔ T178 proxy proof header and path survive re-pin and rollback unchanged in the pointer and unit (3084.56264ms)
|
||||
✔ T178 proxy proof pair survives a tester-port replacement as well (1871.352274ms)
|
||||
▶ T53 row 187: activate sets, carries and drops the proof pair
|
||||
✔ tests 1 and 9: the pair goes after the preview flags, before --send and the kept --tester-port, as the unit renders it; a new pair replaces it (5957.458612ms)
|
||||
✔ tests 2 and 3: an activate of the live copy writes the pair; a later activate and a rollback carry it (4748.919152ms)
|
||||
✔ test 2: only a pair change may name the live copy; the log keeps from and to, and rollback still goes to the earlier copy (6348.550383ms)
|
||||
✔ test 2: a live-copy activate says only the Console flags change, and backs up the stopped store before it installs (3766.45236ms)
|
||||
✔ test 3: pm-on keeps the pair (2959.180793ms)
|
||||
✔ test 4: --no-proof drops the pair from the pointer and the unit and says so; with no pair it says so and passes (5233.036939ms)
|
||||
✔ test 5: each refusal exits 3 before anything stops (3649.68534ms)
|
||||
✔ tests 5 and 9: --plan lists every proof refusal with the others and writes nothing (836.025341ms)
|
||||
✔ test 6: usage errors (773.25631ms)
|
||||
✔ test 7: a rollback to a copy without proof support drops the pair and says so (3311.183201ms)
|
||||
✔ test 7: an activate to a copy without proof support refuses proof-target without --no-proof and passes with it (3616.1202ms)
|
||||
✔ T53 row 187: activate sets, carries and drops the proof pair (41201.876404ms)
|
||||
▶ T54 row 188: a carried pair gets the proof file checks, and a proof file inside the repository refuses
|
||||
✔ test 1: an activate that carries the pair refuses after chmod 644, in the plan and the run, before anything stops (2194.421439ms)
|
||||
✔ test 1: an activate that carries the pair refuses after a symlink to a mode-600 file, in the plan and the run, before anything stops (2189.529552ms)
|
||||
✔ test 1: an activate that carries the pair refuses after removal, in the plan and the run, before anything stops (2243.035352ms)
|
||||
✔ test 2: a rollback that carries the pair refuses after chmod 644, in the plan and the run, before anything stops (2336.000835ms)
|
||||
✔ test 3: a proof file inside the repository refuses, in the plan and the run, before anything stops (1105.046097ms)
|
||||
✔ test 4: a path outside the repository through a directory symlink into it refuses on its realpath (1150.666433ms)
|
||||
✔ T54 row 188: a carried pair gets the proof file checks, and a proof file inside the repository refuses (11219.876632ms)
|
||||
▶ T55 row 189: activate --no-send drops --send, and rollback and pm-on carry it off
|
||||
✔ test 1: a live-copy --no-send drops --send from the pointer and the unit, keeps the rest in order, logs the step and backs up the stopped store (2274.3857ms)
|
||||
✔ test 2: a plain live-copy activate still refuses already-active, and so does --no-send once --send is gone (3110.763383ms)
|
||||
✔ test 3: --plan prints one send: line in each case, with the live-copy note on a same-copy run (4485.563548ms)
|
||||
✔ test 4: after --no-send, a rollback to the earlier copy leaves --send out of the pointer and the unit (3260.741012ms)
|
||||
✔ test 4: pm-on after --no-send keeps --send off (3151.996202ms)
|
||||
✔ test 5: --no-send on rollback, pm-on, status, adopt or rehearse is a usage error (654.253174ms)
|
||||
✔ test 6: with both a pair and --send in the pointer, --no-send and --no-proof each drop what they name and keep the rest (9881.189087ms)
|
||||
✔ T55 row 189: activate --no-send drops --send, and rollback and pm-on carry it off (26820.278319ms)
|
||||
▶ T57 row 200: activate --sso, its refusals before any stop, and the rollback to a Console without --sso
|
||||
✔ item 1: --sso drops the preview set and the pair, puts --sso before --send and the tester port, and the plan names what it drops and carries (3703.052075ms)
|
||||
✔ item 1: --sso may re-pin the live copy once; later activates carry it; --no-send still drops --send (8819.731338ms)
|
||||
✔ item 1: --sso with a pair or --no-proof, or on any verb but activate, is a usage error (692.195455ms)
|
||||
✔ item 2: a target without --sso, a missing or bad console.sso, and each slot problem refuse before any stop (5662.393194ms)
|
||||
✔ item 3: a config whose console key the target loader refuses stops an activate or a rollback before any stop, naming the first step (4284.150525ms)
|
||||
✔ item 3: a rollback from --sso to a Console without it takes the flags from the set of the activation onto the copy, past a same-copy re-pin (sage-1389) (11448.283647ms)
|
||||
✔ item 3: a rollback set that is missing, fails its sums, holds no argv or already ran --sso refuses sso-rollback-flags (4548.577973ms)
|
||||
✔ round 2 (webby-0028 N1): run through a symlinked repository path, a slot or a proof file inside the repository still refuses (2401.295904ms)
|
||||
✔ round 2 (webby-0028 N2): a config.json that does not parse stops the run before anything is read or stopped (2172.272961ms)
|
||||
✔ round 3 (sage-1556): a named instance turns --sso on with its own config, slot and Console unit, and rolls back from its own set (4291.803296ms)
|
||||
✔ row 238 (#1744): on a named instance the sso-config first step names --instance NAME in both commands (1134.427878ms)
|
||||
✔ T57 row 200: activate --sso, its refusals before any stop, and the rollback to a Console without --sso (49160.357454ms)
|
||||
✔ R1 rehearse passes on the same schema; the scratch root holds its files and the live files stay byte-identical (3480.635997ms)
|
||||
✔ R2 rehearse runs the migration checks when the schema differs; the live store stays at 3g (3538.664935ms)
|
||||
✔ R3 a failing migration gives REHEARSAL_FAIL migrate and starts nothing (352.394887ms)
|
||||
✔ R4 a host that does not start, does not answer status, reports another pid, launches anyway, makes a launches directory or keeps its lock each fails by name (22497.071985ms)
|
||||
✔ R5 a host that ignores SIGTERM gets SIGKILL and FAIL host-stopped (4425.852712ms)
|
||||
✔ R6 a Console that does not answer /healthz gives REHEARSAL_FAIL healthz (5628.652507ms)
|
||||
✔ R7 a host on another copy fails copy-match (5626.942239ms)
|
||||
✔ R8 a scratch port in use or reserved refuses, and the rehearsal takes no other port (483.876429ms)
|
||||
✔ R9 mos-0963: a role reference left outside placeholders/, or left on an env variable, fails credential-ref-live before the host starts (737.183647ms)
|
||||
✔ R10 mos-0962: a scratch business that still sets a tracker fails tracker-configured (336.641991ms)
|
||||
✔ R11 mos-0961: a scratch config on the live data root or on any root but the scratch one, or a sessions.json naming a running pid, refuses by name (1329.146892ms)
|
||||
✔ R12 mos-0962: a notifier config with a binding fails notify-off (322.530573ms)
|
||||
✔ R13 the pre-checks: an old copy, a backup that fails its sums, a missing backup or pointer, and usage (467.892209ms)
|
||||
✔ R14 a host that writes the live config, the live business file or the backup fails the end check by name (9332.612807ms)
|
||||
✔ R15 a rehearsal stopped by TERM, INT or HUP fails signal and still stops the host and Console and runs the end checks (9980.867141ms)
|
||||
✔ row 233: --backup last takes the newest backup the log records; a later line with backup null does not hide it, and the store line names it (3438.884089ms)
|
||||
✔ row 233: --backup last with no backup in the log, or no log, exits 3 with no-backup and makes no rehearsal directory (190.873827ms)
|
||||
✔ row 233: --backup last refuses a newest backup that is not an activation id, with exit 1 (117.903969ms)
|
||||
▶ T56 row 190: named instances side by side on one unit directory, $BIN and set of stand-ins
|
||||
✔ T-I3 each instance renders its own config, session env and Description, and nothing of another (1497.847969ms)
|
||||
✔ T-I4 a Console port another installed Console takes refuses port-claimed, and a named instance keeps off the default ports (1995.198242ms)
|
||||
✔ T-I6 alpha's activate and rollback reach nothing of beta's (3765.448219ms)
|
||||
✔ T-I6 swapped: beta's reach nothing of alpha's (3738.069466ms)
|
||||
✔ T-I7 MOSAIC_CONFIG naming alpha's config with no flag refuses instance-root-mismatch and changes nothing (672.561735ms)
|
||||
✔ T-I9 another instance's bus active refuses nothing; one of this instance's does (5819.537565ms)
|
||||
✔ T56 row 190: named instances side by side on one unit directory, $BIN and set of stand-ins (17490.000329ms)
|
||||
ℹ tests 196
|
||||
ℹ suites 0
|
||||
ℹ pass 196
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 533493.817869
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
✔ row 233: sequence 1: confirm fails healthz, the driver reverts, renders the old copy and confirm --rollback --cause A5 passes: exit 1 (6210.373434ms)
|
||||
✔ row 233: sequence 2: activate --migrate fails at the wrapper, revert restores the store, confirm --rollback --cause A3: exit 1 (3236.556603ms)
|
||||
✔ row 233: sequence 3: root's render of the new copy fails, the driver rolls back with --cause A4, and holds the lock to the end: exit 1 (3088.506825ms)
|
||||
✔ row 233: sequence 4: a capture failure is exit 3 from the stage, and A2f restarts the old units and gates them: exit 1 (2296.722984ms)
|
||||
✔ row 233: N1: a bus that outlives A2's timeout keeps its old start, so A2f's gate fails stale-start: exit 2, both units stopped (7977.855045ms)
|
||||
✔ row 233: sequence 5: confirm of the wrong copy is refused, and the driver rolls back with --cause A5: exit 1 (3484.271196ms)
|
||||
✔ row 233: sequence 6: a revert that fails stops both units at exit 2, and the next run refuses at its --plan with nothing stopped (2709.834241ms)
|
||||
✔ row 233: sequence 7: two upgrades and a rollback --to the previous copy with --restore, the args file following each confirm (7481.097653ms)
|
||||
✔ row 240: I3 N1: a failed args move after A5 exits 5 args-failed, the new copy live and confirmed and both args files kept (2791.714439ms)
|
||||
✔ row 233: sequence 8: a migration that writes and fails: the driver reverts to the backup byte for byte, --cause A3: exit 1 (3155.287145ms)
|
||||
✔ row 233: a second run while the lock is held refuses upgrade-running with one log line and no call (659.849042ms)
|
||||
✔ row 233: A1 refuses open-activation on any AWAITING-UNITS file, through the stack's user's --plan, with nothing stopped (1064.03698ms)
|
||||
✔ row 233: a target that migrates refuses migrate-required without --migrate, with nothing stopped (1067.011634ms)
|
||||
✔ row 233: the rehearsal runs after the plan and before A2; a failed one refuses rehearsal-failed with nothing stopped (1099.022074ms)
|
||||
✔ row 233: the rehearsal's BACKUP_STORE line goes to the step log after a match, a malformed one as none, the rest of its output never (2918.095196ms)
|
||||
✔ row 233: a real rehearsal with no backup in the log refuses no-backup, and goes on only with --no-rehearsal, which logs the skip (3400.448853ms)
|
||||
✔ row 233: a real rehearsal after an upgrade names the log's newest backup; --no-rehearsal with a backup refuses rehearsal-required (3795.598553ms)
|
||||
✔ row 233: the args file must be the running user's, with no group or other write, one --copy, and the copy the units run (839.804685ms)
|
||||
✔ row 233: hostcheck (row 240): a nonzero --check or a missing file refuses profile-drift before the plan (962.315692ms)
|
||||
✔ row 233: the checkout must be at --sha (head-mismatch), and a commit the clone can't fast-forward to refuses fetch-failed (936.914531ms)
|
||||
✔ row 233: usage exits 4 before any log or lock (685.887579ms)
|
||||
ℹ tests 21
|
||||
ℹ suites 0
|
||||
ℹ pass 21
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 60456.446459
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
✔ C2-04: a library-only business with tracker.baseUrl boots without a project tracker (143.257728ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (274.054339ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 502.723687
|
||||
@@ -1,24 +0,0 @@
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (35.180686ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (28.575775ms)
|
||||
✔ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (100.935123ms)
|
||||
✔ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (11.206477ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (20.077192ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (32.816347ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (34.864084ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (97.291867ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (29.030379ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (71.409306ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (78.061049ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (230.30816ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5027.25259ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (52.471475ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (44.850141ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (19.645975ms)
|
||||
ℹ tests 16
|
||||
ℹ suites 0
|
||||
ℹ pass 16
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5963.543966
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
✔ C2-04: record APIs refuse a library before creating a repository (2.136303ms)
|
||||
✔ init creates a checked versioned layout, valid templates and human-authored local history (25.282114ms)
|
||||
✔ init honors repo, refuses a non-empty directory and an undeclared project without touching files (13.067957ms)
|
||||
✔ check reports every bad record, filename mismatch and unknown top-level path (11.851979ms)
|
||||
✔ one writer commits validated docs, requirements and decisions with the bound agent author (66.653ms)
|
||||
✔ writer refuses spec paths, bad schemas, mismatched IDs and invalid actor metadata before changing history (14.848593ms)
|
||||
✔ writer refuses human pending edits and remotes instead of absorbing or contacting them (18.544136ms)
|
||||
✔ links, repo/code overlap, identity mismatch and a busy writer refuse safely (17.705717ms)
|
||||
✔ schemas remain package-owned and reject invalid nested data and dates (0.249795ms)
|
||||
✔ git commit failure restores only the attempted record and leaves human history unchanged (36.217826ms)
|
||||
✔ git hooks and ambient git identity cannot alter the record writer or execute outside actions (25.483658ms)
|
||||
✔ project-local schemas cannot weaken checks; invalid UTF-8 and linked git directories refuse (14.206204ms)
|
||||
✔ schema constraints and layout omissions are reported independently (12.868115ms)
|
||||
✔ unsupported schema keywords, malformed contexts, ignored local config and nonempty markers refuse (18.523225ms)
|
||||
✔ a linked git directory is refused before a writer lock can touch its target (30.574055ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 355.86586
|
||||
@@ -1,91 +0,0 @@
|
||||
✔ C2-04: ensureCheckouts skips a library before a real clone and leaves no books path (22.355495ms)
|
||||
✔ a first launch clones the root at its branch, with the root's path as origin (23.522928ms)
|
||||
✔ the clone is not at its place until git clone has finished (19.304369ms)
|
||||
✔ a later launch fast-forwards a clean clone after a commit to the root, then finds it current (56.365259ms)
|
||||
✔ a clone ahead of the root keeps its commits and counts as current (35.573942ms)
|
||||
▶ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves
|
||||
✔ a modified file (41.519272ms)
|
||||
✔ an untracked file (42.31579ms)
|
||||
✔ a staged file (42.328417ms)
|
||||
✔ another branch (40.470049ms)
|
||||
✔ a detached HEAD (40.702516ms)
|
||||
✔ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves (208.344457ms)
|
||||
✔ a diverged clone gets the fetch into refs/remotes and is kept, not-fast-forward (42.026437ms)
|
||||
▶ a clone kept before the branch check, or for a failed status, gets no fetch
|
||||
✔ not-a-clone (22.404264ms)
|
||||
✔ hooks-present (23.073574ms)
|
||||
✔ submodule (30.027272ms)
|
||||
✔ config-changed (26.84014ms)
|
||||
✔ root-unreadable (27.464656ms)
|
||||
✔ root-detached (32.242501ms)
|
||||
✔ status-failed, on the root's branch and clean (35.760734ms)
|
||||
✔ status-failed, dirty (35.340017ms)
|
||||
✔ a clone kept before the branch check, or for a failed status, gets no fetch (234.251087ms)
|
||||
✔ a dirty clone whose fetch fails is kept, fetch-failed, exactly as it was (37.035833ms)
|
||||
✔ every git call the host makes, for a new clone and an existing one, carries maintenance.auto=false and gc.auto=0 (44.392371ms)
|
||||
✔ a clone with loose objects enough for gc --auto gets no maintenance or gc from the fetch and the merge (71.033894ms)
|
||||
▶ a clone with user.name or user.email in its config is kept, and git runs nothing in it
|
||||
✔ user.name (25.544784ms)
|
||||
✔ user.email (25.14754ms)
|
||||
✔ a clone with user.name or user.email in its config is kept, and git runs nothing in it (51.146879ms)
|
||||
✔ a commit git can't read after the fast-forward is null (45.746486ms)
|
||||
✔ a new clone whose commit can't be read refuses the launch and leaves nothing behind (18.576825ms)
|
||||
▶ a clone the session rigged is kept, and git runs nothing and writes nothing outside it
|
||||
✔ core.fsmonitor (33.120199ms)
|
||||
✔ core.hooksPath (33.027016ms)
|
||||
✔ a hook file (30.549575ms)
|
||||
✔ include.path (33.355749ms)
|
||||
✔ includeIf (33.915275ms)
|
||||
✔ a filter driver (34.236367ms)
|
||||
✔ origin moved (34.552998ms)
|
||||
✔ a second origin url (33.217597ms)
|
||||
✔ the origin url twice, both the root (34.870837ms)
|
||||
✔ an ext:: origin (33.6526ms)
|
||||
✔ a branch tracking another remote (33.582081ms)
|
||||
✔ a branch merging a tag (33.08648ms)
|
||||
✔ a fetch line onto local branches (34.366694ms)
|
||||
✔ no origin (33.938644ms)
|
||||
✔ a config file over the size cap (31.285987ms)
|
||||
✔ config a symlink to /dev/zero (31.094858ms)
|
||||
✔ the clone a symlink to the bait (32.754738ms)
|
||||
✔ the clone a file (31.24085ms)
|
||||
✔ the clone a plain directory (30.973366ms)
|
||||
✔ .git a gitdir: file (31.404094ms)
|
||||
✔ .git a symlink (30.769522ms)
|
||||
✔ .git/logs a symlink (30.883317ms)
|
||||
✔ .git/refs/heads a symlink (31.770074ms)
|
||||
✔ .git/objects a symlink (30.840803ms)
|
||||
✔ a reflog hard-linked to a file outside (30.322982ms)
|
||||
✔ HEAD a fifo (31.496048ms)
|
||||
✔ a commondir file (30.352537ms)
|
||||
✔ an alternates file (30.782307ms)
|
||||
✔ a gitlink staged, no .gitmodules (43.468245ms)
|
||||
✔ a gitlink and .gitmodules staged (44.893483ms)
|
||||
✔ a gitlink to a repository with its own gitlink (51.849481ms)
|
||||
✔ a gitlink and .gitmodules committed (47.718755ms)
|
||||
✔ a gitlink and submodule.active in config (44.861481ms)
|
||||
✔ a .git/modules with no gitlink (33.279554ms)
|
||||
✔ a clone the session rigged is kept, and git runs nothing and writes nothing outside it (1175.645437ms)
|
||||
▶ a root that can't be cloned refuses with the project id and leaves nothing behind
|
||||
✔ missing (10.161685ms)
|
||||
✔ not a repository (9.929001ms)
|
||||
✔ a plain directory inside another repository (14.613067ms)
|
||||
✔ unreadable (9.85915ms)
|
||||
✔ on no branch (11.8808ms)
|
||||
✔ missing an object (15.129485ms)
|
||||
✔ a root that can't be cloned refuses with the project id and leaves nothing behind (72.336456ms)
|
||||
✔ a clone whose root is on no branch, or gone, is kept and named (28.236024ms)
|
||||
✔ no credential or forge remote of the root reaches a clone (47.533999ms)
|
||||
✔ every project in the business file gets its own clone at its own branch (36.497038ms)
|
||||
✔ a clone past its time gets SIGTERM and refuses the launch, with nothing left in the workspace (513.397369ms)
|
||||
✔ a clone that ignores SIGTERM gets SIGKILL once the grace period is over (1018.126958ms)
|
||||
✔ a timeout signals git's process group, so a process git started dies with it (515.579592ms)
|
||||
✔ once a signalled git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (515.62296ms)
|
||||
ℹ tests 78
|
||||
ℹ suites 0
|
||||
ℹ pass 78
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 4880.907448
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
✔ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (109.519835ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 191.536271
|
||||
@@ -1 +0,0 @@
|
||||
{"processes": [], "removed": "/mnt/storage/scratch/gt-j5nm6iqn", "sourceHashesUnchanged": 29}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"base": "f8276c5eb",
|
||||
"tip": "8a04f4aa4aba493eb89e92aa9e0c34084be7058e",
|
||||
"overlap": []
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
2026-10-21T13:27:27.279728+00:00
|
||||
@@ -1,194 +0,0 @@
|
||||
[
|
||||
{
|
||||
"file": "packages/bus/tests/library.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "01-packages_bus_tests_library.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/bus/tests/project-runtime.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "02-packages_bus_tests_project-runtime.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/business.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 19,
|
||||
"pass": 19,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "03-packages_business_tests_business.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/cli.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 10,
|
||||
"pass": 10,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "04-packages_business_tests_cli.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/instance-settings.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "05-packages_business_tests_instance-settings.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "06-packages_business_tests_library-projects-protected.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/resolve.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 11,
|
||||
"pass": 11,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "07-packages_business_tests_resolve.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/launcher.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 31,
|
||||
"pass": 31,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "08-packages_cli_tests_launcher.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release-external.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 25,
|
||||
"pass": 25,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "09-packages_cli_tests_stack-release-external.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 196,
|
||||
"pass": 196,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "10-packages_cli_tests_stack-release.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-upgrade.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 21,
|
||||
"pass": 21,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "11-packages_cli_tests_stack-upgrade.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/trackers-boot.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 2,
|
||||
"pass": 2,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "12-packages_cli_tests_trackers-boot.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/library/tests/mirror.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 16,
|
||||
"pass": 16,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "13-packages_library_tests_mirror.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/project/tests/project.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 15,
|
||||
"pass": 15,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "14-packages_project_tests_project.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/seat/tests/checkout.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 78,
|
||||
"pass": 78,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "15-packages_seat_tests_checkout.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/webui/tests/library-cli.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "16-packages_webui_tests_library-cli.test.mjs.log"
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
/mnt/storage/scratch/gt-j5nm6iqn
|
||||
@@ -1 +0,0 @@
|
||||
2026-10-21T13:15:15.548778+00:00
|
||||
@@ -1 +0,0 @@
|
||||
{"tests": 451, "pass": 451, "fail": 0, "cancelled": 0, "skipped": 0}
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-04 M4: both verbs reject every agent before arguments or adapter access (31.111616ms)
|
||||
✔ C2-04 bus: human reads validate keys and return adapter results without path leakage (12.907709ms)
|
||||
✔ C2-04 socket: each async library verb resolves its result rather than serializing {} (14.631614ms)
|
||||
✔ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (42.32493ms)
|
||||
✔ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (20.701022ms)
|
||||
✔ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (82.322654ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 342.882774
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
✔ Broker keeps the sandbox client import closure: only the listed imports, no lazy project import (1.629219ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (43.976856ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (68.038516ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 209.393305
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
✔ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (9.717487ms)
|
||||
✔ C2-04: an otherwise valid publish grant cannot name a library repo (1.932435ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (0.219374ms)
|
||||
✔ the fixture business validates and comes back frozen (0.988926ms)
|
||||
✔ two instances may share a definition (0.940973ms)
|
||||
✔ top-level refusals (3.202519ms)
|
||||
✔ arbiters and projects (4.893652ms)
|
||||
✔ role instances (2.749701ms)
|
||||
✔ Vikunja bots (5.88131ms)
|
||||
✔ a role without Vikunja takes no tracker block (4.097438ms)
|
||||
✔ credential references match the definition's services (2.14689ms)
|
||||
✔ launch (7.492201ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (4.633228ms)
|
||||
✔ loadBusiness: file checks (1.761847ms)
|
||||
✔ loadBusiness: not a regular file (36.320112ms)
|
||||
✔ loading writes nothing (1.117059ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.898886ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.943369ms)
|
||||
ℹ tests 18
|
||||
ℹ suites 0
|
||||
ℹ pass 18
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 152.091247
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
✔ C2-04: business validate and resolve skip a library before code projects and credential checks (219.31729ms)
|
||||
✔ usage errors exit 4 (321.939555ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (76.14497ms)
|
||||
✔ validate: project files (353.409636ms)
|
||||
✔ validate: missing files and a broken system config (238.885921ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (72.187146ms)
|
||||
✔ validate: a token file inside the repository is refused (66.603163ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (212.341091ms)
|
||||
✔ resolve: prints one instance's record (340.865306ms)
|
||||
✔ resolve: refusals (526.732262ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 10
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2493.367293
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
✔ C2-04: instance settings skip a library while checking a later code project (33.384562ms)
|
||||
✔ row 165 read lists each instance and the definitions add accepts (2.667885ms)
|
||||
✔ row 165 add: two instances join, validate exits 0, the log names the human, and the bus restart is reported (87.186598ms)
|
||||
✔ row 165 change: definition, vars and launch membership log before and after; only a definition change asks for a restart (92.493768ms)
|
||||
✔ row 165 refuses each validation failure and leaves the file's bytes alone (29.566007ms)
|
||||
✔ row 165 refuses an added instance whose definition declares credentials, and says why (3.207564ms)
|
||||
✔ row 165 refuses a definition change to or from one that declares credentials (4.215516ms)
|
||||
✔ row 165 a vars or launch change on an instance with its binding succeeds and keeps the binding (72.107052ms)
|
||||
✔ row 165 refuses an END_PROTECTED definition and every change to a protected instance (7.281711ms)
|
||||
✔ row 165 refuses while a project file doesn't resolve, as validate would (13.645202ms)
|
||||
✔ row 165 refuses a stale revision and leaves the file's bytes alone (10.119096ms)
|
||||
✔ row 65 an instance write refuses harness-off, thinking-unsupported, an unknown model and a partial fallback (29.171515ms)
|
||||
ℹ tests 12
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 450.444507
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
✔ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (20.276877ms)
|
||||
✔ C2-04 M9: code projects, additions, deletions and array changes are protected too (16.209877ms)
|
||||
✔ C2-04 M9: canonical key order is allowed and a non-project setter still records its change (13.103686ms)
|
||||
✔ C2-04 M9: a serialization hook cannot change projects after the canonical comparison (12.598611ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 112.92317
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
✔ C2-04: a library first in projects does not hide a later project layer (6.304379ms)
|
||||
✔ systemVars flattens the validated config (0.828852ms)
|
||||
✔ precedence: system, business, project, project role, agent (1.532829ms)
|
||||
✔ limits narrow the definition and never widen it (2.353655ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (4.439921ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (1.815884ms)
|
||||
✔ limits.authority narrows cross-role actions too (0.827532ms)
|
||||
✔ classify (0.829892ms)
|
||||
✔ the record carries what the broker and launcher need (0.755977ms)
|
||||
✔ digest: key order doesn't matter, any value change does (5.452ms)
|
||||
✔ refusals (1.724971ms)
|
||||
ℹ tests 11
|
||||
ℹ suites 0
|
||||
ℹ pass 11
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 79.941483
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
✔ C2-04: launcher workspace clones code but never the library (1262.341325ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1237.473965ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4414332d2ef5","instance":"chief","turn":"382a782c-719a-48e8-a249-ec24caf5ad1e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"reaca93954ae7","instance":"coder","turn":"70bcac05-fbc1-41b2-85cb-725c15884a94","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (579.516254ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rb21267233555","instance":"chief","turn":"c228faeb-6e3c-4453-ba9b-b9a27b9790af","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r1fc01260daa7","instance":"pm","turn":"a5d09ce0-4208-4eb4-8178-6e06a1792ab9","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rb21267233555","instance":"chief","turn":"25722023-5270-4c50-a8a0-7c3645d08bd7","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r1fc01260daa7","instance":"pm","turn":"f4a76756-4300-4cdf-a64b-542fc075c137","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r1fc01260daa7","instance":"pm","turn":"99ea9441-ce4e-4aab-a56c-614a30c9f0da","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rb21267233555","instance":"chief","turn":"d85fa6e4-7557-4adf-b1f6-5e76455a1e51","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r1fc01260daa7","instance":"pm","turn":"87f4bf91-2ef2-4fe7-8e99-09fc8b14887e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rb21267233555","instance":"chief","turn":"6db9d009-2cb9-41ba-a07e-da13d92b8182","source":"@none","code":"baseline-unknown"}
|
||||
✔ a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold (917.244851ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3692.977114ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (439.559581ms)
|
||||
✔ REQ-LAUNCH-1 the tick starts a listed merge decision holder once, with land_work, the Landing line and its landing turn; an unlisted holder starts nothing (324.77099ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd33ea739f0c8","instance":"coder","turn":"434622cc-98ff-44b4-99c9-58a8c92f32af","source":"@none","code":"baseline-unknown"}
|
||||
✔ a holder running since before the resolution is stopped once the broker releases it, land-relaunch, and the next tick starts it: landing turn first, then the message that waited (502.385034ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (453.667705ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (654.880099ms)
|
||||
✔ a refused landing start is logged once per code with its decision, isn't a start, and the next tick with room starts the holder (498.662638ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (208.782448ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (261.153743ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (143.737058ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (239.874115ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row215-on212/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row215-on212/packages/plugins/harness/down is missing","kept":[]}
|
||||
✔ row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason (281.577833ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (297.263791ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (151.327191ms)
|
||||
✔ row 64 a role skill that isn't enabled refuses skill-not-enabled, and one that isn't a plain directory skill-refused, before anything starts (151.537445ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (166.552674ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rc42c73baf400","instance":"chief","turn":"e62acc78-0ddd-4cd3-bb90-c828cf5dc76e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r9fac1139247f","instance":"coder","turn":"e634dd74-b64a-4c8d-8e8d-90244a1070d4","source":"@none","code":"baseline-unknown"}
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1685.572916ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (791.200293ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3731.707174ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (196.993732ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (159.584006ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1086.093241ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (132.916552ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (143.651083ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (144.715063ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1275.914847ms)
|
||||
ℹ tests 30
|
||||
ℹ suites 0
|
||||
ℹ pass 30
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 21918.233853
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
✔ row 232: confirm, revert, gate, --to and --expect-from need --units external; the user-only flags are usage under it (832.842347ms)
|
||||
✔ row 232: pm-on and activate --pm-after-harness refuse external-pm (934.889182ms)
|
||||
✔ row 232: units-running (N4) refuses while a unit is active and leaves the store, the log and TAKEN; failed counts as down (2121.604528ms)
|
||||
✔ row 232: activate stages: the pointer stays, AWAITING-UNITS names TO, a backup of the stopped store, no directory in the set, no --user, no journal (1777.227274ms)
|
||||
✔ row 232: A3 order: capture-failed and marker-failed refuse with exit 3 and leave no marker or FAILED (1712.692045ms)
|
||||
✔ row 232: confirm and revert refuse open-activation with no marker, two, the wrong copy, or one the log holds closed; refusals name no activation (3642.165244ms)
|
||||
✔ row 232: confirm polls: bus status good after 3 s fails with --timeout 1, writes FAILED and leaves the rest; FAILED then refuses activation-failed (3522.196896ms)
|
||||
✔ row 232: confirm polls to a pass with --timeout 10: the pointer, an ok line that reads as the started run, no marker (5641.501857ms)
|
||||
✔ row 232: stale-start: @1792540799 fails a start floor of 1792540800 with stale-start (3076.294408ms)
|
||||
✔ row 232: stale-start is a gate code: an enter time that turns to @1792540800 after 2 s passes with --timeout 10 (4471.752137ms)
|
||||
✔ row 232: gate (N2, A2f): --since 1792540800 passes @1792540800 and fails @1792540799; it writes nothing (2692.190142ms)
|
||||
✔ row 232: the external PM check reads launches list: one live run of launch.by since the start passes (9781.807961ms)
|
||||
✔ row 232: revert puts the wrapper back and leaves the store when nothing migrated (1409.775029ms)
|
||||
✔ row 232: confirm --rollback refuses rollback-mismatch, and logs rollback-failed with exit 2 when OLD fails its gate (3556.739549ms)
|
||||
✔ row 232: confirm --rollback after a --restore swap logs rollbackCode not-attempted; rollback --restore finds an external backup (3258.873111ms)
|
||||
✔ row 232: sequence 1: activate, confirm times out, revert, confirm --rollback --cause A5: gate-failed rollback ok (4878.560819ms)
|
||||
✔ row 232: sequence 2: activate --migrate, the wrapper install fails, revert restores TAKEN, confirm --rollback --cause A3 (3203.155908ms)
|
||||
✔ row 232: sequence 3: activate, root's A4 fails, revert, confirm --rollback --cause A4: failed code units-start (2844.170694ms)
|
||||
✔ row 232: sequence 4: a capture failure leaves nothing open, then A2f's gate OLD writes nothing (1940.493148ms)
|
||||
✔ row 232: sequence 5: a confirm of the wrong copy is refused, and revert and confirm --rollback still close the activation (3423.561744ms)
|
||||
✔ row 232: sequence 6: a revert that fails leaves the activation open, and the next --plan refuses interrupted-run (1732.106092ms)
|
||||
✔ row 232: sequence 7: adopt, two confirmed activates, rollback --to the previous copy, confirmed, logs op rollback (8298.40004ms)
|
||||
✔ row 232: sequence 8: a migration that writes and fails: revert restores the backup byte for byte, confirm --rollback --cause A3 (3658.849346ms)
|
||||
✔ row 232: user mode: every systemctl call carries --user, and activate, rollback and check make the base's calls (7450.661653ms)
|
||||
✔ row 232: user mode: a default activate --plan prints the base's bytes (2572.062595ms)
|
||||
ℹ tests 25
|
||||
ℹ suites 0
|
||||
ℹ pass 25
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 89317.249955
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
✔ T1 adopt writes the pointer from the units once; a failing check refuses check-failed (1372.806902ms)
|
||||
✔ T2 activate installs exactly the pointer's pm, claude and Console flags (2175.278069ms)
|
||||
▶ T3 a hand-edited unit refuses unit-flags-drift, names the difference and changes nothing
|
||||
✔ pm (940.434448ms)
|
||||
✔ claude (905.331444ms)
|
||||
✔ console (953.801488ms)
|
||||
✔ T3 a hand-edited unit refuses unit-flags-drift, names the difference and changes nothing (2800.414725ms)
|
||||
▶ T4 each item 3 refusal changes nothing and logs one line with its code
|
||||
✔ copy-missing (828.258816ms)
|
||||
✔ copy-unreachable (750.040135ms)
|
||||
✔ copy-schema-unknown (804.784952ms)
|
||||
✔ already-active (767.83377ms)
|
||||
✔ instance-busy (another business active) (836.742584ms)
|
||||
✔ instance-busy (this business activating) (824.181046ms)
|
||||
✔ drop-in-override (819.802212ms)
|
||||
✔ no-pointer (432.597537ms)
|
||||
✔ T4 each item 3 refusal changes nothing and logs one line with its code (6065.707472ms)
|
||||
✔ T5 an activate with no migration stops the Console then the bus, installs, starts the bus then the Console (1974.205406ms)
|
||||
✔ T6 a migration without --migrate rolls back with migration-needs-flag (1689.71261ms)
|
||||
✔ T7 --migrate takes the backup before the migration runs (1874.080499ms)
|
||||
✔ T8 a failed migration restores the backup and keeps the store it replaced (1879.088438ms)
|
||||
✔ T9 a store outside the target's chain rolls back with store-newer (1695.743767ms)
|
||||
▶ T10 each gate check failing alone rolls back and puts every file back
|
||||
✔ units-inactive (5145.320966ms)
|
||||
✔ bus-status (5504.739824ms)
|
||||
✔ healthz (4630.494167ms)
|
||||
✔ copy-check (4953.814776ms)
|
||||
✔ pm-launch-unconfirmed (5175.714883ms)
|
||||
✔ T10 each gate check failing alone rolls back and puts every file back (25411.164743ms)
|
||||
▶ T10b the PM check needs exactly one launched line for a live run of this start
|
||||
✔ no launched line (5309.620588ms)
|
||||
✔ two lines (5271.450965ms)
|
||||
✔ a changed word (5207.189363ms)
|
||||
✔ run not in launches list (5249.94294ms)
|
||||
✔ run started before the start (5297.104798ms)
|
||||
✔ a human launch with no journal line (5012.384828ms)
|
||||
✔ run for another business (5255.258408ms)
|
||||
✔ run not live (5155.194619ms)
|
||||
✔ one well-formed line and a live run pass (1936.667118ms)
|
||||
✔ T10b the PM check needs exactly one launched line for a live run of this start (43696.539474ms)
|
||||
✔ T11 a rollback whose gate fails too: rollback-failed, exit 2, both units stopped, no retry (9445.48752ms)
|
||||
✔ T12 rollback takes the previous copy from the log (3164.86878ms)
|
||||
✔ T13 a rollback across a migration needs --restore, then restores and goes live (3832.433037ms)
|
||||
✔ T14 events written after the backup need --events N with the right N (4300.182861ms)
|
||||
✔ T14b a rollback --restore whose gate fails stops both units and skips item 6 (5706.078353ms)
|
||||
✔ T14c a rollback without --restore whose gate fails runs item 6 (7364.684709ms)
|
||||
✔ T15 --plan names the migration and the restore and changes nothing (2976.558ms)
|
||||
✔ T26 --plan lists the commits an activate adds, after the migration lines (1448.921448ms)
|
||||
✔ T27 --plan names each migration step, or says the steps cannot be read (1074.961775ms)
|
||||
✔ T25 --plan refuses copies-unrelated when neither copy is an ancestor of the other (504.611631ms)
|
||||
▶ T23 --plan reads the store without changing a file, stopped or held
|
||||
✔ stopped store (612.654192ms)
|
||||
✔ held store (615.45405ms)
|
||||
✔ T23 --plan reads the store without changing a file, stopped or held (1228.613968ms)
|
||||
✔ T24 business-mismatch and capture-failed refuse with exit 3; a short id is a usage error (1504.453363ms)
|
||||
✔ T16 status prints the pointer, the log, the check, bus status and drift, and writes nothing (969.540282ms)
|
||||
✔ T19 a started line with no final line: status shows it and every changing verb refuses (1272.112268ms)
|
||||
✔ T20 a held run lock refuses run-locked without a log line; status and --plan still run (1363.537596ms)
|
||||
✔ T21 a bus unit with no MOSAIC_CLAUDE_BIN: adopt and activate refuse no-claude-pin (1516.277233ms)
|
||||
▶ T22 the stopped store read: a -wal or -shm refuses store-unclean and is left alone; a clean read adds no file
|
||||
✔ bus.sqlite-wal (1776.498328ms)
|
||||
✔ bus.sqlite-shm (1805.948894ms)
|
||||
✔ clean (1860.970301ms)
|
||||
✔ T22 the stopped store read: a -wal or -shm refuses store-unclean and is left alone; a clean read adds no file (5444.145497ms)
|
||||
▶ T28 a unit path, drop-in directory or drop-in file that cannot be read, or a relative unit path, refuses drop-in-override before any stop
|
||||
✔ unit path (838.2428ms)
|
||||
✔ drop-in directory (770.669306ms)
|
||||
✔ drop-in file (787.861386ms)
|
||||
✔ relative unit path (799.918614ms)
|
||||
✔ T28 a unit path, drop-in directory or drop-in file that cannot be read, or a relative unit path, refuses drop-in-override before any stop (3197.49908ms)
|
||||
▶ T29 a bus that stops during the held-store read: --plan says so, rollback --restore refuses restore-mismatch
|
||||
✔ --plan (842.842612ms)
|
||||
✔ rollback --restore (2383.664939ms)
|
||||
✔ T29 a bus that stops during the held-store read: --plan says so, rollback --restore refuses restore-mismatch (3227.016275ms)
|
||||
✔ T30 a copy check that agrees on another copy fails the gate with copy-check and rolls back (4822.028878ms)
|
||||
▶ T31 a quoted or escaped Environment= or ExecStart= is unreadable: refusals by name, nothing read from /a
|
||||
✔ Environment double quotes (1747.115914ms)
|
||||
✔ Environment single quotes (1747.871141ms)
|
||||
✔ Environment backslash (1718.42505ms)
|
||||
✔ ExecStart quotes (1733.916441ms)
|
||||
✔ Console ExecStart quotes (1805.192313ms)
|
||||
✔ T31 a quoted or escaped Environment= or ExecStart= is unreadable: refusals by name, nothing read from /a (8753.514814ms)
|
||||
▶ T32 item 1: --pm-after-harness refuses a target without harness or a file that sets it, and passes without the PM
|
||||
✔ usage: not with --pm, and only for activate (630.81989ms)
|
||||
✔ pm-after-harness-target (949.989597ms)
|
||||
✔ pm-after-harness-set (1400.026643ms)
|
||||
✔ a pointer without pm (849.389257ms)
|
||||
✔ phase 1 installs without --pm, skips pm_launched and writes the pending pointer (2037.948918ms)
|
||||
✔ T32 item 1: --pm-after-harness refuses a target without harness or a file that sets it, and passes without the PM (5869.092521ms)
|
||||
▶ T33 item 2: read_pointer takes pmPending only as true beside pm false; a pending pointer refuses activate and shows in status
|
||||
✔ read_pointer (1646.25297ms)
|
||||
✔ pm-pending, already-adopted and the status line (2899.447167ms)
|
||||
✔ T33 item 2: read_pointer takes pmPending only as true beside pm false; a pending pointer refuses activate and shows in status (4546.229216ms)
|
||||
▶ T34 item 3: pm-on refuses before any stop, passes with the PM, or puts the phase-1 bus back
|
||||
✔ not-pending (781.816005ms)
|
||||
✔ harness-unset (2528.770078ms)
|
||||
✔ a launched line passes: the bus alone restarts with --pm (3635.97518ms)
|
||||
✔ a failed pm_launched puts the phase-1 unit back: exit 1, still pending (6129.763508ms)
|
||||
✔ a failed phase-1 gate too: pm-on-down, exit 2, both units stopped (10681.440065ms)
|
||||
✔ T34 item 3: pm-on refuses before any stop, passes with the PM, or puts the phase-1 bus back (23758.959718ms)
|
||||
▶ T35 item 4: rollback from pending installs --pm; a plug-in kind the target lacks refuses by name
|
||||
✔ rollback from pending gates pm_launched on the old copy (3432.493856ms)
|
||||
✔ after the harness set, rollback refuses until harness is gone (4814.40527ms)
|
||||
✔ activate names every kind the target lacks (1278.267995ms)
|
||||
✔ T35 item 4: rollback from pending installs --pm; a plug-in kind the target lacks refuses by name (9525.935986ms)
|
||||
✔ T36 --plan shows the pending state and lists the row 169 refusals it can see (3442.637109ms)
|
||||
✔ T37 tester-port activate writes pointer and unit, replaces the port, and supported re-pin and rollback keep it (6713.755862ms)
|
||||
✔ T38 tester-port rollback to unsupported target drops flag in plan, steps, unit and pointer (3556.909655ms)
|
||||
✔ T39 tester-port explicit unsupported target reads target copy and refuses before stopping either unit (816.518752ms)
|
||||
✔ T40 tester-port invalid values refuse exit 4 before stopping, including tunnel and main ports (798.151327ms)
|
||||
✔ T41 tester-port inherited activate to unsupported target drops it and retains drift refusal and failed-run recovery (8335.191178ms)
|
||||
✔ T42 tester-port pm-on preserves pointer Console flags (3045.995877ms)
|
||||
▶ T43 row 180 item 1: runs in one second get distinct activation ids, rollback sets and post-attempt stores
|
||||
✔ activate then pm-on on the same copy (3077.866023ms)
|
||||
✔ two restores: an old-form id and a suffixed one, each with its own post-attempt store (6478.022663ms)
|
||||
✔ adopt takes the next free id too (676.463788ms)
|
||||
✔ all ten names taken: capture-failed before anything stops, and the log line names no activation (927.509173ms)
|
||||
✔ --restore takes an id with or without -1 to -9 and nothing else (1026.017549ms)
|
||||
✔ T43 row 180 item 1: runs in one second get distinct activation ids, rollback sets and post-attempt stores (12186.978758ms)
|
||||
▶ T44 row 180 item 2: --plan lists tester-port-invalid and tester-port-target with its other refusals
|
||||
✔ a bad tester port (2101.036117ms)
|
||||
✔ without --plan a bad port is usage before any pointer read (417.577025ms)
|
||||
✔ a target Console without --tester-port (1050.997021ms)
|
||||
✔ T44 row 180 item 2: --plan lists tester-port-invalid and tester-port-target with its other refusals (3570.568101ms)
|
||||
▶ T45 row 181 items 2 and 3: the restore guard counts events and every COUNTED table
|
||||
✔ both modes count events and each listed table, and a table the store lacks counts 0 (819.811738ms)
|
||||
✔ one instance_names row and no event refuses before any stop; --events 1 restores (4281.220981ms)
|
||||
✔ one usage_records row and no event refuses before any stop; --events 1 restores (4339.553222ms)
|
||||
✔ a listed table that cannot be read refuses restore-mismatch before any stop (3011.194623ms)
|
||||
✔ the in-run recount counts the listed tables too (3456.814799ms)
|
||||
✔ T45 row 181 items 2 and 3: the restore guard counts events and every COUNTED table (15910.111456ms)
|
||||
✔ T46 row 181 item 4: every table in the bus schema is in exactly one of four lists (2.96277ms)
|
||||
✔ T47 row 185 test 1: a same-schema activate leaves a whole backup and the log line names it (1839.922479ms)
|
||||
✔ T48 row 185 test 2: a gate failure on a same-schema activate rolls back without a restore (5782.007105ms)
|
||||
▶ T49 row 185 test 3: a same-schema rollback --restore restores, or refuses rows written after STAMP
|
||||
✔ no rows after STAMP: restores and goes live (3276.614244ms)
|
||||
✔ one instance_names row after STAMP refuses post-backup-events; --events 1 restores (3603.193575ms)
|
||||
✔ T49 row 185 test 3: a same-schema rollback --restore restores, or refuses rows written after STAMP (6880.328466ms)
|
||||
✔ T50 row 185 test 4: activate --plan prints the backup line and writes nothing (2392.362463ms)
|
||||
✔ T51 row 185 test 5: an activate with no store file takes no backup (2055.74343ms)
|
||||
▶ T52 row 186: the activate plan's backup line says what the run will do
|
||||
✔ same schema (2076.652498ms)
|
||||
✔ same schema with --migrate (2103.728264ms)
|
||||
✔ in chain with --migrate (2343.740358ms)
|
||||
✔ in chain without --migrate (2172.44891ms)
|
||||
✔ outside the chain (2018.610199ms)
|
||||
✔ outside the chain with --migrate (2286.782735ms)
|
||||
✔ T52 row 186: the activate plan's backup line says what the run will do (13003.221353ms)
|
||||
✔ T178 proxy proof header and path survive re-pin and rollback unchanged in the pointer and unit (3428.609169ms)
|
||||
✔ T178 proxy proof pair survives a tester-port replacement as well (2005.665148ms)
|
||||
▶ T53 row 187: activate sets, carries and drops the proof pair
|
||||
✔ tests 1 and 9: the pair goes after the preview flags, before --send and the kept --tester-port, as the unit renders it; a new pair replaces it (5369.617405ms)
|
||||
✔ tests 2 and 3: an activate of the live copy writes the pair; a later activate and a rollback carry it (4877.926077ms)
|
||||
✔ test 2: only a pair change may name the live copy; the log keeps from and to, and rollback still goes to the earlier copy (6411.791056ms)
|
||||
✔ test 2: a live-copy activate says only the Console flags change, and backs up the stopped store before it installs (3823.440479ms)
|
||||
✔ test 3: pm-on keeps the pair (2929.528358ms)
|
||||
✔ test 4: --no-proof drops the pair from the pointer and the unit and says so; with no pair it says so and passes (6134.571168ms)
|
||||
✔ test 5: each refusal exits 3 before anything stops (4080.818538ms)
|
||||
✔ tests 5 and 9: --plan lists every proof refusal with the others and writes nothing (921.495619ms)
|
||||
✔ test 6: usage errors (791.940368ms)
|
||||
✔ test 7: a rollback to a copy without proof support drops the pair and says so (3569.742095ms)
|
||||
✔ test 7: an activate to a copy without proof support refuses proof-target without --no-proof and passes with it (4102.029003ms)
|
||||
✔ T53 row 187: activate sets, carries and drops the proof pair (43015.196531ms)
|
||||
▶ T54 row 188: a carried pair gets the proof file checks, and a proof file inside the repository refuses
|
||||
✔ test 1: an activate that carries the pair refuses after chmod 644, in the plan and the run, before anything stops (2443.927487ms)
|
||||
✔ test 1: an activate that carries the pair refuses after a symlink to a mode-600 file, in the plan and the run, before anything stops (2451.543098ms)
|
||||
✔ test 1: an activate that carries the pair refuses after removal, in the plan and the run, before anything stops (2371.886229ms)
|
||||
✔ test 2: a rollback that carries the pair refuses after chmod 644, in the plan and the run, before anything stops (2440.808004ms)
|
||||
✔ test 3: a proof file inside the repository refuses, in the plan and the run, before anything stops (1028.022624ms)
|
||||
✔ test 4: a path outside the repository through a directory symlink into it refuses on its realpath (1092.396277ms)
|
||||
✔ T54 row 188: a carried pair gets the proof file checks, and a proof file inside the repository refuses (11829.775747ms)
|
||||
▶ T55 row 189: activate --no-send drops --send, and rollback and pm-on carry it off
|
||||
✔ test 1: a live-copy --no-send drops --send from the pointer and the unit, keeps the rest in order, logs the step and backs up the stopped store (2297.315751ms)
|
||||
✔ test 2: a plain live-copy activate still refuses already-active, and so does --no-send once --send is gone (3372.219555ms)
|
||||
✔ test 3: --plan prints one send: line in each case, with the live-copy note on a same-copy run (4822.032599ms)
|
||||
✔ test 4: after --no-send, a rollback to the earlier copy leaves --send out of the pointer and the unit (3681.502406ms)
|
||||
✔ test 4: pm-on after --no-send keeps --send off (3384.224907ms)
|
||||
✔ test 5: --no-send on rollback, pm-on, status, adopt or rehearse is a usage error (646.332677ms)
|
||||
✔ test 6: with both a pair and --send in the pointer, --no-send and --no-proof each drop what they name and keep the rest (10576.556687ms)
|
||||
✔ T55 row 189: activate --no-send drops --send, and rollback and pm-on carry it off (28781.800109ms)
|
||||
▶ T57 row 200: activate --sso, its refusals before any stop, and the rollback to a Console without --sso
|
||||
✔ item 1: --sso drops the preview set and the pair, puts --sso before --send and the tester port, and the plan names what it drops and carries (3731.038851ms)
|
||||
✔ item 1: --sso may re-pin the live copy once; later activates carry it; --no-send still drops --send (9441.965146ms)
|
||||
✔ item 1: --sso with a pair or --no-proof, or on any verb but activate, is a usage error (804.681755ms)
|
||||
✔ item 2: a target without --sso, a missing or bad console.sso, and each slot problem refuse before any stop (6340.571003ms)
|
||||
✔ item 3: a config whose console key the target loader refuses stops an activate or a rollback before any stop, naming the first step (4474.330517ms)
|
||||
✔ item 3: a rollback from --sso to a Console without it takes the flags from the set of the activation onto the copy, past a same-copy re-pin (sage-1389) (11258.382547ms)
|
||||
✔ item 3: a rollback set that is missing, fails its sums, holds no argv or already ran --sso refuses sso-rollback-flags (4811.481384ms)
|
||||
✔ round 2 (webby-0028 N1): run through a symlinked repository path, a slot or a proof file inside the repository still refuses (2548.588058ms)
|
||||
✔ round 2 (webby-0028 N2): a config.json that does not parse stops the run before anything is read or stopped (2148.082108ms)
|
||||
✔ round 3 (sage-1556): a named instance turns --sso on with its own config, slot and Console unit, and rolls back from its own set (4427.346674ms)
|
||||
✔ row 238 (#1744): on a named instance the sso-config first step names --instance NAME in both commands (1072.216503ms)
|
||||
✔ T57 row 200: activate --sso, its refusals before any stop, and the rollback to a Console without --sso (51060.894572ms)
|
||||
✔ R1 rehearse passes on the same schema; the scratch root holds its files and the live files stay byte-identical (3501.665564ms)
|
||||
✔ R2 rehearse runs the migration checks when the schema differs; the live store stays at 3g (2615.765886ms)
|
||||
✔ R3 a failing migration gives REHEARSAL_FAIL migrate and starts nothing (406.432761ms)
|
||||
✔ R4 a host that does not start, does not answer status, reports another pid, launches anyway, makes a launches directory or keeps its lock each fails by name (23643.921414ms)
|
||||
✔ R5 a host that ignores SIGTERM gets SIGKILL and FAIL host-stopped (4522.753011ms)
|
||||
✔ R6 a Console that does not answer /healthz gives REHEARSAL_FAIL healthz (5695.642056ms)
|
||||
✔ R7 a host on another copy fails copy-match (5707.109175ms)
|
||||
✔ R8 a scratch port in use or reserved refuses, and the rehearsal takes no other port (564.078959ms)
|
||||
✔ R9 mos-0963: a role reference left outside placeholders/, or left on an env variable, fails credential-ref-live before the host starts (739.463019ms)
|
||||
✔ R10 mos-0962: a scratch business that still sets a tracker fails tracker-configured (356.527698ms)
|
||||
✔ R11 mos-0961: a scratch config on the live data root or on any root but the scratch one, or a sessions.json naming a running pid, refuses by name (1415.617777ms)
|
||||
✔ R12 mos-0962: a notifier config with a binding fails notify-off (346.615997ms)
|
||||
✔ R13 the pre-checks: an old copy, a backup that fails its sums, a missing backup or pointer, and usage (495.179039ms)
|
||||
✔ R14 a host that writes the live config, the live business file or the backup fails the end check by name (10325.286968ms)
|
||||
✔ R15 a rehearsal stopped by TERM, INT or HUP fails signal and still stops the host and Console and runs the end checks (9991.220342ms)
|
||||
✔ row 233: --backup last takes the newest backup the log records; a later line with backup null does not hide it, and the store line names it (3454.052038ms)
|
||||
✔ row 233: --backup last with no backup in the log, or no log, exits 3 with no-backup and makes no rehearsal directory (203.934243ms)
|
||||
✔ row 233: --backup last refuses a newest backup that is not an activation id, with exit 1 (127.433768ms)
|
||||
▶ T56 row 190: named instances side by side on one unit directory, $BIN and set of stand-ins
|
||||
✔ T-I3 each instance renders its own config, session env and Description, and nothing of another (1595.173571ms)
|
||||
✔ T-I4 a Console port another installed Console takes refuses port-claimed, and a named instance keeps off the default ports (1992.011586ms)
|
||||
✔ T-I6 alpha's activate and rollback reach nothing of beta's (3927.69359ms)
|
||||
✔ T-I6 swapped: beta's reach nothing of alpha's (4046.222781ms)
|
||||
✔ T-I7 MOSAIC_CONFIG naming alpha's config with no flag refuses instance-root-mismatch and changes nothing (707.673985ms)
|
||||
✔ T-I9 another instance's bus active refuses nothing; one of this instance's does (6093.674502ms)
|
||||
✔ T56 row 190: named instances side by side on one unit directory, $BIN and set of stand-ins (18364.096442ms)
|
||||
ℹ tests 196
|
||||
ℹ suites 0
|
||||
ℹ pass 196
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 530980.947325
|
||||
@@ -1 +0,0 @@
|
||||
{"processes": [], "removed": "/mnt/storage/scratch/gt-t2e8hpyu", "trees": ["/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row215-on212", "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197-r8"]}
|
||||
@@ -1 +0,0 @@
|
||||
{"pid": 765123, "reason": "sage-1983 stop after file10; do not start file11"}
|
||||
@@ -1,122 +0,0 @@
|
||||
[
|
||||
{
|
||||
"file": "packages/bus/tests/library.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "01-packages_bus_tests_library.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/bus/tests/project-runtime.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "02-packages_bus_tests_project-runtime.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/business.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 18,
|
||||
"pass": 18,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "03-packages_business_tests_business.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/cli.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 10,
|
||||
"pass": 10,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "04-packages_business_tests_cli.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/instance-settings.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 12,
|
||||
"pass": 12,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "05-packages_business_tests_instance-settings.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "06-packages_business_tests_library-projects-protected.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/business/tests/resolve.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 11,
|
||||
"pass": 11,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "07-packages_business_tests_resolve.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/launcher.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 30,
|
||||
"pass": 30,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "08-packages_cli_tests_launcher.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release-external.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 25,
|
||||
"pass": 25,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "09-packages_cli_tests_stack-release-external.test.mjs.log"
|
||||
},
|
||||
{
|
||||
"file": "packages/cli/tests/stack-release.test.mjs",
|
||||
"rc": 0,
|
||||
"counts": {
|
||||
"tests": 196,
|
||||
"pass": 196,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"log": "10-packages_cli_tests_stack-release.test.mjs.log"
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
/mnt/storage/scratch/gt-t2e8hpyu
|
||||
@@ -1 +0,0 @@
|
||||
2026-10-21T11:56:56.177608+00:00
|
||||
@@ -1,10 +0,0 @@
|
||||
✔ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (9.004507ms)
|
||||
✔ C2-04: an otherwise valid publish grant cannot name a library repo (1.807264ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 67.488189
|
||||
@@ -1,23 +0,0 @@
|
||||
✖ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (5.192384ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 54.487487
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/business.test.mjs:11:1
|
||||
✖ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (5.192384ms)
|
||||
Error [BusinessError]: unsupported /mnt/storage/scratch/gt-PvGtsQ/mosaic-business-4vAhxB/businesses/acme.json projects.books key: "kind"
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/src/errors.mjs:12:9)
|
||||
at rejectUnknownKeys (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/src/util.mjs:17:33)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/src/business.mjs:232:5)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/tests/business.test.mjs:17:18)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: ensureCheckouts skips a library before a real clone and leaves no books path (24.411494ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 72.211367
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"at": "2026-10-21T08:51:07Z",
|
||||
"tempRoot": "/mnt/storage/scratch/gt-PvGtsQ",
|
||||
"fixtureCwdOrArgv": [],
|
||||
"testProcesses": [],
|
||||
"excluded": "current scan process and its ancestors",
|
||||
"tempRootRemoved": true
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: business validate and resolve skip a library before code projects and credential checks (206.597157ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 260.97412
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: instance settings skip a library while checking a later code project (22.656666ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 79.494698
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: launcher workspace clones code but never the library (1241.43402ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1338.915726
|
||||
@@ -1,12 +0,0 @@
|
||||
✔ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (21.916712ms)
|
||||
✔ C2-04 M9: code projects, additions, deletions and array changes are protected too (17.081275ms)
|
||||
✔ C2-04 M9: canonical key order is allowed and a non-project setter still records its change (14.304068ms)
|
||||
✔ C2-04 M9: a serialization hook cannot change projects after the canonical comparison (9.595281ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 116.250811
|
||||
@@ -1,28 +0,0 @@
|
||||
✖ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (21.728048ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 71.097427
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/library-projects-protected.test.mjs:35:1
|
||||
✖ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (21.728048ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at protectedWrite (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/tests/library-projects-protected.test.mjs:29:10)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/business/tests/library-projects-protected.test.mjs:37:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-projects-protected' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: record APIs refuse a library before creating a repository (3.426617ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 61.266328
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04: a library first in projects does not hide a later project layer (6.517821ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 62.270511
|
||||
@@ -1,90 +0,0 @@
|
||||
[
|
||||
{
|
||||
"file": "business-green.log",
|
||||
"tests": 2,
|
||||
"pass": 2,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "business-red.log",
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "checkout-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "cli-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "instance-settings-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "launcher-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "m9-green.log",
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "m9-red.log",
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "project-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "resolve-green.log",
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
{
|
||||
"file": "trackers-boot-green.log",
|
||||
"tests": 2,
|
||||
"pass": 2,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
2026-10-21T08:48:14Z
|
||||
@@ -1 +0,0 @@
|
||||
/mnt/storage/scratch/gt-PvGtsQ
|
||||
@@ -1,12 +0,0 @@
|
||||
✔ C2-04: a library-only business with tracker.baseUrl boots without a project tracker (132.133246ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (261.808635ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 480.083569
|
||||
@@ -1 +0,0 @@
|
||||
{"processes": [], "removed": "/mnt/storage/scratch/gt-iwfcrf5s"}
|
||||
@@ -1 +0,0 @@
|
||||
["packages/library/tests/mirror.test.mjs", "packages/bus/tests/library.test.mjs", "packages/webui/tests/library-cli.test.mjs", "packages/bus/tests/project-runtime.test.mjs"]
|
||||
@@ -1,31 +0,0 @@
|
||||
✖ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (140.263767ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 244.49705
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/library-cli.test.mjs:10:1
|
||||
✖ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (140.263767ms)
|
||||
AssertionError [ERR_ASSERTION]: refused: missing library callbacks
|
||||
|
||||
|
||||
2 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/webui/tests/library-cli.test.mjs:27:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 2,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
✖ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (31.496523ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 122.065824
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/library-cli.test.mjs:10:1
|
||||
✖ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (31.496523ms)
|
||||
AssertionError [ERR_ASSERTION]: file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/webui/src/bus.mjs:1
|
||||
import {appendFileSync} from 'node:fs';export class BusReadError extends Error{};export const busCaller=o=>async(verb,args)=>{appendFileSync("/mnt/storage/scratch/gt-iwfcrf5s/library-cli-1eUPUX/calls.jsonl",JSON.stringify({verb,args,cli:o.cli??"/mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/human-cli.mjs"})+'
|
||||
^
|
||||
|
||||
SyntaxError: Invalid or unexpected token
|
||||
at compileSourceTextModule (node:internal/modules/esm/utils:355:16)
|
||||
at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:93:18)
|
||||
at #translate (node:internal/modules/esm/loader:441:20)
|
||||
at afterLoad (node:internal/modules/esm/loader:509:29)
|
||||
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:514:12)
|
||||
at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:567:36)
|
||||
at afterResolve (node:internal/modules/esm/loader:614:52)
|
||||
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:620:12)
|
||||
at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)
|
||||
at ModuleJob.link (node:internal/modules/esm/module_job:389:17)
|
||||
|
||||
Node.js v26.8.1
|
||||
|
||||
|
||||
1 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/webui/tests/library-cli.test.mjs:27:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 1,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (110.620217ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 194.067409
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (107.138425ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 193.527058
|
||||
@@ -1,71 +0,0 @@
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (14.387463ms)
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (8.808227ms)
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (15.107055ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 125.805576
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:28:1
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (14.387463ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'unknown-verb'
|
||||
- code: 'human-required'
|
||||
}
|
||||
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:32:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: unknown-verb
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at #dispatch (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:3098:9)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1810:38
|
||||
at Store.transaction (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/store.mjs:263:22)
|
||||
at Broker.request (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1801:26)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:24:78
|
||||
at async waitForActual (node:assert:615:5)
|
||||
at async strict.rejects (node:assert:738:25)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:32:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7),
|
||||
expected: { code: 'human-required' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:45:1
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (8.808227ms)
|
||||
Error: unknown-verb
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at #dispatch (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:3098:9)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1810:38
|
||||
at Store.transaction (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/store.mjs:263:22)
|
||||
at Broker.request (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1801:26)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:24:78
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:49:17)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
code: 'unknown-verb'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:56:1
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (15.107055ms)
|
||||
Error: unknown-verb
|
||||
at Socket.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/client.mjs:42:17)
|
||||
at Socket.emit (node:events:514:20)
|
||||
at addChunk (node:internal/streams/readable:575:12)
|
||||
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
|
||||
at Readable.push (node:internal/streams/readable:406:5)
|
||||
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23) {
|
||||
code: 'unknown-verb'
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (16.66162ms)
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (9.880605ms)
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (17.417761ms)
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (27.11473ms)
|
||||
✖ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (21.990752ms)
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (21.295513ms)
|
||||
|
||||
Interrupted while running:
|
||||
|
||||
⚠ packages/bus/tests/library.test.mjs (packages/bus/tests/library.test.mjs:1:1)
|
||||
✖ packages/bus/tests/library.test.mjs (34335.85978ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 6
|
||||
ℹ cancelled 1
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 34341.308382
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:28:1
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (16.66162ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'unknown-verb'
|
||||
- code: 'human-required'
|
||||
}
|
||||
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:32:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: unknown-verb
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at #dispatch (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:3098:9)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1810:38
|
||||
at Store.transaction (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/store.mjs:263:22)
|
||||
at Broker.request (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1801:26)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:24:78
|
||||
at async waitForActual (node:assert:615:5)
|
||||
at async strict.rejects (node:assert:738:25)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:32:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7),
|
||||
expected: { code: 'human-required' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:45:1
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (9.880605ms)
|
||||
Error: unknown-verb
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at #dispatch (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:3098:9)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1810:38
|
||||
at Store.transaction (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/store.mjs:263:22)
|
||||
at Broker.request (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:1801:26)
|
||||
at file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:24:78
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:49:17)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
code: 'unknown-verb'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:56:1
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (17.417761ms)
|
||||
Error: unknown-verb
|
||||
at Socket.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/client.mjs:42:17)
|
||||
at Socket.emit (node:events:514:20)
|
||||
at addChunk (node:internal/streams/readable:575:12)
|
||||
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
|
||||
at Readable.push (node:internal/streams/readable:406:5)
|
||||
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23) {
|
||||
code: 'unknown-verb'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:67:1
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (27.11473ms)
|
||||
TypeError: library.mirrorPath is not a function
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:74:26)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:81:1
|
||||
✖ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (21.990752ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected rejection.
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:87:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'library-git' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:92:1
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (21.295513ms)
|
||||
Error: unknown-verb
|
||||
at Socket.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/client.mjs:42:17)
|
||||
at Socket.emit (node:events:514:20)
|
||||
at addChunk (node:internal/streams/readable:575:12)
|
||||
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
|
||||
at Readable.push (node:internal/streams/readable:406:5)
|
||||
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23) {
|
||||
code: 'unknown-verb'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:1:1
|
||||
✖ packages/bus/tests/library.test.mjs (34335.85978ms)
|
||||
'Promise resolution is still pending but the event loop has already resolved'
|
||||
@@ -1,126 +0,0 @@
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (24.976387ms)
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (7.097425ms)
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (6.894431ms)
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (34.318499ms)
|
||||
✖ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (21.188728ms)
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (11.406264ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 197.495962
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:28:1
|
||||
✖ C2-04 M4: both verbs reject every agent before arguments or adapter access (24.976387ms)
|
||||
Error: invalid-business
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at new Broker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:322:9)
|
||||
at world (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:30:13)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
code: 'invalid-business'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:45:1
|
||||
✖ C2-04 bus: human reads validate keys and return adapter results without path leakage (7.097425ms)
|
||||
Error: invalid-business
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at new Broker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:322:9)
|
||||
at world (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:47:13)
|
||||
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 async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
code: 'invalid-business'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:56:1
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (6.894431ms)
|
||||
Error: invalid-business
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at new Broker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:322:9)
|
||||
at world (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:57:13)
|
||||
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 async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
code: 'invalid-business'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:67:1
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (34.318499ms)
|
||||
Error: credential-format
|
||||
at deny (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/credentials.mjs:10:9)
|
||||
at #format (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/credentials.mjs:232:28)
|
||||
at #read (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/credentials.mjs:222:37)
|
||||
at new Credentials (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/credentials.mjs:145:35)
|
||||
at startBroker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/runtime.mjs:108:19)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:72:25)
|
||||
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) {
|
||||
code: 'credential-format'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:81:1
|
||||
✖ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (21.188728ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'invalid-business'
|
||||
- code: 'library-git'
|
||||
}
|
||||
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:86:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: invalid-business
|
||||
at fail (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:145:9)
|
||||
at new Broker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/broker.mjs:322:9)
|
||||
at startBroker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/runtime.mjs:126:20)
|
||||
at async waitForActual (node:assert:615:5)
|
||||
at async strict.rejects (node:assert:738:25)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:86:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
|
||||
expected: { code: 'library-git' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:91:1
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (11.406264ms)
|
||||
Error: ENOENT: no such file or directory, lstat '/mnt/storage/scratch/gt-iwfcrf5s/library-m65UFF/data'
|
||||
at lstatSync (node:fs:2138:25)
|
||||
at new Store (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/store.mjs:137:22)
|
||||
at startBroker (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/src/runtime.mjs:99:13)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/bus/tests/library.test.mjs:94:25)
|
||||
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 async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'lstat',
|
||||
path: '/mnt/storage/scratch/gt-iwfcrf5s/library-m65UFF/data'
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-04 M4: both verbs reject every agent before arguments or adapter access (28.309128ms)
|
||||
✔ C2-04 bus: human reads validate keys and return adapter results without path leakage (11.198339ms)
|
||||
✔ C2-04 socket: each async library verb resolves its result rather than serializing {} (14.717312ms)
|
||||
✔ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (42.066656ms)
|
||||
✔ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (23.773967ms)
|
||||
✔ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (89.925539ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 301.460553
|
||||
@@ -1,63 +0,0 @@
|
||||
✔ C2-04 M4: both verbs reject every agent before arguments or adapter access (27.706148ms)
|
||||
✔ C2-04 bus: human reads validate keys and return adapter results without path leakage (10.128912ms)
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (14.255977ms)
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (20.969978ms)
|
||||
✔ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (19.148653ms)
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (10.834076ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 192.486443
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:56:1
|
||||
✖ C2-04 socket: each async library verb resolves its result rather than serializing {} (14.255977ms)
|
||||
Error: unauthenticated
|
||||
at Socket.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/client.mjs:42:17)
|
||||
at Socket.emit (node:events:514:20)
|
||||
at addChunk (node:internal/streams/readable:575:12)
|
||||
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
|
||||
at Readable.push (node:internal/streams/readable:406:5)
|
||||
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23) {
|
||||
code: 'unauthenticated'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:67:1
|
||||
✖ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (20.969978ms)
|
||||
Error: credential-format
|
||||
at deny (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/credentials.mjs:10:9)
|
||||
at #format (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/credentials.mjs:232:28)
|
||||
at #read (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/credentials.mjs:222:37)
|
||||
at new Credentials (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/credentials.mjs:145:35)
|
||||
at startBroker (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/runtime.mjs:109:19)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/tests/library.test.mjs:72:25)
|
||||
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) {
|
||||
code: 'credential-format'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/library.test.mjs:91:1
|
||||
✖ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (10.834076ms)
|
||||
Error: ENOENT: no such file or directory, lstat '/mnt/storage/scratch/gt-iwfcrf5s/library-rRi0EP/data'
|
||||
at lstatSync (node:fs:2138:25)
|
||||
at new Store (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/store.mjs:137:22)
|
||||
at startBroker (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/src/runtime.mjs:100:13)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/bus/tests/library.test.mjs:94:25)
|
||||
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) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'lstat',
|
||||
path: '/mnt/storage/scratch/gt-iwfcrf5s/library-rRi0EP/data'
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-04 M4: both verbs reject every agent before arguments or adapter access (29.476748ms)
|
||||
✔ C2-04 bus: human reads validate keys and return adapter results without path leakage (11.765761ms)
|
||||
✔ C2-04 socket: each async library verb resolves its result rather than serializing {} (15.523467ms)
|
||||
✔ C2-04 runtime: protectedRoots skips library but retains real code-root credential protection (41.028545ms)
|
||||
✔ C2-04 runtime: unsafe existing mirror refuses boot and never publishes a socket (20.174444ms)
|
||||
✔ C2-04 runtime: real library adapters reach the socket and lock waits leave other bus reads responsive (89.276012ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 314.116154
|
||||
@@ -1,35 +0,0 @@
|
||||
node:internal/modules/esm/resolve:272
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
^
|
||||
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/src/mirror.mjs' imported from /mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/tests/mirror.test.mjs
|
||||
at finalizeResolution (node:internal/modules/esm/resolve:272:11)
|
||||
at moduleResolve (node:internal/modules/esm/resolve:879:10)
|
||||
at defaultResolve (node:internal/modules/esm/resolve:1006:11)
|
||||
at #cachedDefaultResolve (node:internal/modules/esm/loader:708:20)
|
||||
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:728:38)
|
||||
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:766:56)
|
||||
at #resolve (node:internal/modules/esm/loader:690:17)
|
||||
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:610:35)
|
||||
at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)
|
||||
at ModuleJob.link (node:internal/modules/esm/module_job:389:17) {
|
||||
code: 'ERR_MODULE_NOT_FOUND',
|
||||
url: 'file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/src/mirror.mjs'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ packages/library/tests/mirror.test.mjs (35.196517ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 41.636181
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/library/tests/mirror.test.mjs:1:1
|
||||
✖ packages/library/tests/mirror.test.mjs (35.196517ms)
|
||||
'test failed'
|
||||
@@ -1,35 +0,0 @@
|
||||
node:internal/modules/esm/resolve:272
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
^
|
||||
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/src/mirror.mjs' imported from /mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/tests/mirror.test.mjs
|
||||
at finalizeResolution (node:internal/modules/esm/resolve:272:11)
|
||||
at moduleResolve (node:internal/modules/esm/resolve:879:10)
|
||||
at defaultResolve (node:internal/modules/esm/resolve:1006:11)
|
||||
at #cachedDefaultResolve (node:internal/modules/esm/loader:708:20)
|
||||
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:728:38)
|
||||
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:766:56)
|
||||
at #resolve (node:internal/modules/esm/loader:690:17)
|
||||
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:610:35)
|
||||
at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)
|
||||
at ModuleJob.link (node:internal/modules/esm/module_job:389:17) {
|
||||
code: 'ERR_MODULE_NOT_FOUND',
|
||||
url: 'file:///mnt/storage/scratch/gt-iwfcrf5s/base/packages/library/src/mirror.mjs'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ packages/library/tests/mirror.test.mjs (29.912154ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 35.532092
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/library/tests/mirror.test.mjs:1:1
|
||||
✖ packages/library/tests/mirror.test.mjs (29.912154ms)
|
||||
'test failed'
|
||||
@@ -1,24 +0,0 @@
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (38.226069ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (28.230282ms)
|
||||
✔ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (102.534821ms)
|
||||
✔ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (13.3233ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (21.415494ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (35.194627ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (37.132264ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (99.673047ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (28.715976ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (71.638861ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (78.457144ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (228.356974ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5027.769608ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (52.875238ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (49.021765ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (20.779739ms)
|
||||
ℹ tests 16
|
||||
ℹ suites 0
|
||||
ℹ pass 16
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5980.465131
|
||||
@@ -1,30 +0,0 @@
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (42.294098ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (29.430204ms)
|
||||
✖ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (15050.820834ms)
|
||||
✔ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (13.507402ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (19.93202ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (33.088494ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (34.798253ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (96.144919ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (28.529103ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (71.331837ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (80.081788ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (232.208946ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5028.099129ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (55.474555ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (51.152959ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (21.006119ms)
|
||||
ℹ tests 16
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 1
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 20945.326932
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/library/tests/mirror.test.mjs:53:1
|
||||
✖ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (15050.820834ms)
|
||||
'test timed out after 15000ms'
|
||||
@@ -1,23 +0,0 @@
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (37.162857ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (28.538429ms)
|
||||
✔ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (10.987669ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (20.080027ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (33.757482ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (35.501927ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (96.276094ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (28.464199ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (72.087911ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (78.120774ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (230.905584ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5029.743303ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (51.842651ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (48.619585ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (19.747384ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5872.380072
|
||||
@@ -1,51 +0,0 @@
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (35.114121ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (28.344028ms)
|
||||
✖ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (11.29287ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (21.069667ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (33.576129ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (36.355449ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (98.678405ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (28.476513ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (72.613881ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (78.072657ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (230.109966ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5027.239374ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (53.970224ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (45.088532ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (19.793614ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 14
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5869.613351
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/library/tests/mirror.test.mjs:53:1
|
||||
✖ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (11.29287ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /overlap/. Input:
|
||||
|
||||
'Error: project-path: unsafe mirror path'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/tests/mirror.test.mjs:64:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: project-path: unsafe mirror path
|
||||
at Module.mirrorPath (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:40:25)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/tests/mirror.test.mjs:64:27
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/tests/mirror.test.mjs:64:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
|
||||
expected: /overlap/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
✖ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (56.393634ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 102.30317
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/library/tests/mirror.test.mjs:53:1
|
||||
✖ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (56.393634ms)
|
||||
Error: {"code":1,"stderr":"file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:18\nconst fail = (code, message = code) => { throw new LibraryError(code, message); };\n ^\n\nLibraryError: library-git: expected a private owned bare mirror\n at fail (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:18:48)\n at ownedRoot (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:49:13)\n at inspectMirrorUnchecked (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:57:3)\n at inspectMirror (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:94:15)\n at ensureMirror (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/src/mirror.mjs:128:11)\n at process.processTicksAndRejections (node:internal/process/task_queues:104:5)\n at async file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/[eval1]:7:149 {\n code: 'library-git'\n}\n\nNode.js v26.8.1\n"}
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/tests/mirror.test.mjs:65:108
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row197/packages/library/tests/mirror.test.mjs:65:22)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
@@ -1,11 +0,0 @@
|
||||
✔ Broker keeps the sandbox client import closure: only the listed imports, no lazy project import (1.794155ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (39.865453ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (65.643553ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 197.45826
|
||||
@@ -1,11 +0,0 @@
|
||||
✔ Broker keeps the sandbox client import closure: only the listed imports, no lazy project import (1.418597ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (34.510685ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (59.944824ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 183.05447
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"mirror.test-final-r2.log": {
|
||||
"tests": 16,
|
||||
"pass": 16,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"library.test-final.log": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"library-cli.test-final.log": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"project-runtime.test-final.log": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"library.test-baseline-focused.log": {
|
||||
"tests": 3,
|
||||
"pass": 0,
|
||||
"fail": 3,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"library-cli.test-baseline-r2.log": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"mirror.test-baseline-r2.log": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
/mnt/storage/scratch/gt-iwfcrf5s
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"base": "a2c72ac95",
|
||||
"landing": "fefd54e13",
|
||||
"overlaps": [
|
||||
"BUILD-LOG.md",
|
||||
"packages/cli/tests/stack-release.test.mjs"
|
||||
]
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
{
|
||||
"oldBase": "f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87",
|
||||
"oldSource": "e333af4dc7af3a9d3789c8c0db26a0df8bdddfee",
|
||||
"newBase": "a3652371338e60187d4e95cee4a0f30f3c8a8f06",
|
||||
"paths": [
|
||||
{
|
||||
"path": "BUILD-LOG.md",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/broker.mjs",
|
||||
"upstreamChanged": true,
|
||||
"matchesPriorBlob": false,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/src/server.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/bus/tests/library.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/business.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/cli.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/instance-settings.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/src/resolve.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/business.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/cli.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/instance-settings.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/library-projects-protected.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/business/tests/resolve.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/config.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/src/launcher.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/launcher.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release-fixture.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/stack-release.test.mjs",
|
||||
"upstreamChanged": true,
|
||||
"matchesPriorBlob": false,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/cli/tests/trackers-boot.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/index.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/library/src/mirror.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/library/tests/mirror.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/project/src/paths.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/project/tests/project.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/src/checkout.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/seat/tests/checkout.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/src/cli.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/tests/library-cli.test.mjs",
|
||||
"upstreamChanged": false,
|
||||
"matchesPriorBlob": true,
|
||||
"changeLinesIdentical": true
|
||||
}
|
||||
],
|
||||
"newSource": "a6101e21c596e2972ab5a7e3087736075899505e",
|
||||
"stablePatchId": "d191e7e9586cd3b7c18310daacdf0c1fdbc8be01"
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
packages/bus/tests/library.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/business/tests/business.test.mjs
|
||||
packages/business/tests/cli.test.mjs
|
||||
packages/business/tests/instance-settings.test.mjs
|
||||
packages/business/tests/library-projects-protected.test.mjs
|
||||
packages/business/tests/resolve.test.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/stack-release-external.test.mjs
|
||||
packages/cli/tests/stack-release.test.mjs
|
||||
packages/cli/tests/stack-upgrade.test.mjs
|
||||
packages/cli/tests/trackers-boot.test.mjs
|
||||
packages/library/tests/mirror.test.mjs
|
||||
packages/project/tests/project.test.mjs
|
||||
packages/seat/tests/checkout.test.mjs
|
||||
packages/webui/tests/library-cli.test.mjs
|
||||
packages/bus/tests/agents.test.mjs
|
||||
packages/bus/tests/approval-binding.test.mjs
|
||||
packages/bus/tests/broker.test.mjs
|
||||
packages/bus/tests/business.test.mjs
|
||||
packages/bus/tests/channel-proof.test.mjs
|
||||
packages/bus/tests/chief-of-staff.test.mjs
|
||||
packages/bus/tests/comment-cursors.test.mjs
|
||||
packages/bus/tests/creative.test.mjs
|
||||
packages/bus/tests/credential-claim.test.mjs
|
||||
packages/bus/tests/credential-status.test.mjs
|
||||
packages/bus/tests/credential-store.test.mjs
|
||||
packages/bus/tests/credential-verbs.test.mjs
|
||||
packages/bus/tests/credentials.test.mjs
|
||||
packages/bus/tests/csuite-messaging.test.mjs
|
||||
packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
packages/bus/tests/decision-close.test.mjs
|
||||
packages/bus/tests/decision-route.test.mjs
|
||||
packages/bus/tests/decisions.test.mjs
|
||||
packages/bus/tests/end-launch.test.mjs
|
||||
packages/bus/tests/grant-enroll.test.mjs
|
||||
packages/bus/tests/grant-executor.test.mjs
|
||||
packages/bus/tests/grant-host.test.mjs
|
||||
packages/bus/tests/grant-migration.test.mjs
|
||||
packages/bus/tests/hard-waits.test.mjs
|
||||
packages/bus/tests/host-run.test.mjs
|
||||
packages/bus/tests/human.test.mjs
|
||||
packages/bus/tests/instances-verb.test.mjs
|
||||
packages/bus/tests/land.test.mjs
|
||||
packages/bus/tests/launch-notice.test.mjs
|
||||
packages/bus/tests/limit-stop.test.mjs
|
||||
packages/bus/tests/limits-runtime.test.mjs
|
||||
packages/bus/tests/limits.test.mjs
|
||||
packages/bus/tests/message-citation.test.mjs
|
||||
packages/bus/tests/messages.test.mjs
|
||||
packages/bus/tests/messaging.test.mjs
|
||||
packages/bus/tests/names.test.mjs
|
||||
packages/bus/tests/plugins-verb.test.mjs
|
||||
packages/bus/tests/process.test.mjs
|
||||
packages/bus/tests/project-await.test.mjs
|
||||
packages/bus/tests/project-files.test.mjs
|
||||
packages/bus/tests/publish.test.mjs
|
||||
packages/bus/tests/replies.test.mjs
|
||||
packages/bus/tests/requirements.test.mjs
|
||||
packages/bus/tests/review.test.mjs
|
||||
packages/bus/tests/routes-verb.test.mjs
|
||||
packages/bus/tests/single-use.test.mjs
|
||||
packages/bus/tests/spec-review.test.mjs
|
||||
packages/bus/tests/spec-socket.test.mjs
|
||||
packages/bus/tests/spec.test.mjs
|
||||
packages/bus/tests/staff-request.test.mjs
|
||||
packages/bus/tests/state.test.mjs
|
||||
packages/bus/tests/task-page.test.mjs
|
||||
packages/bus/tests/task-read.test.mjs
|
||||
packages/bus/tests/tasks.test.mjs
|
||||
packages/bus/tests/tester-threads.test.mjs
|
||||
packages/bus/tests/tester-writes.test.mjs
|
||||
packages/bus/tests/tester.test.mjs
|
||||
packages/bus/tests/thread-migration.test.mjs
|
||||
packages/bus/tests/threads.test.mjs
|
||||
packages/bus/tests/transport.test.mjs
|
||||
packages/bus/tests/usage-broker.test.mjs
|
||||
packages/bus/tests/usage-runtime.test.mjs
|
||||
packages/bus/tests/web.test.mjs
|
||||
packages/bus/tests/workflow-roles.test.mjs
|
||||
@@ -1,86 +0,0 @@
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index 135a1699a..f0eb4ae65 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -88,6 +88,7 @@ export const TASK_PAGE_MAX = 200;
|
||||
// Row 148 (#1642): the human-only verbs behind the Console's document editor. The save is the one
|
||||
// request allowed past the ordinary 64 KiB envelope (server.mjs and client.mjs), up to its content cap.
|
||||
export const PROJECT_FILE_VERBS = Object.freeze(['project.files', 'project.file', 'project.file.save']);
|
||||
+export const LIBRARY_VERBS = Object.freeze(['library.file', 'library.status']);
|
||||
export const PROJECT_SAVE_VERB = 'project.file.save';
|
||||
export const PROJECT_SAVE_REQUEST_MAX = 1024 * 1024 + 64 * 1024;
|
||||
export const WEB_VERBS =Object.freeze(['web.search', 'web.fetch']);
|
||||
@@ -279,6 +280,7 @@ export class Broker {
|
||||
#organization;
|
||||
#credentialVerbs;
|
||||
#project;
|
||||
+ #library;
|
||||
#usage;
|
||||
#limits;
|
||||
#harnessOn;
|
||||
@@ -294,7 +296,7 @@ export class Broker {
|
||||
#stops = new Map();
|
||||
#clock = 0;
|
||||
// credentialStatus is the runtime's metadata-only Credentials.status(); the broker never gets use().
|
||||
- constructor({ store, businesses, secretCheck = () => {}, credentialStatus = () => [], organization = null, project = null, usage = null, limits = null, harnessOn = null, credentialVerbs = null, hostGrant = null, hostKeys = null }) {
|
||||
+ constructor({ store, businesses, secretCheck = () => {}, credentialStatus = () => [], organization = null, project = null, library = null, usage = null, limits = null, harnessOn = null, credentialVerbs = null, hostGrant = null, hostKeys = null }) {
|
||||
if (!object(businesses) || !Object.keys(businesses).length) fail('invalid-business');
|
||||
this.#businesses = structuredClone(businesses);
|
||||
this.#store = store;
|
||||
@@ -306,6 +308,7 @@ export class Broker {
|
||||
this.#hostGrant = hostGrant;
|
||||
this.#hostKeys = hostKeys;
|
||||
this.#project = project;
|
||||
+ this.#library = library;
|
||||
this.#usage = usage;
|
||||
this.#limits = limits;
|
||||
// Row 65: harnessOn(business, name) is true when the organization file's plugins.harness switches
|
||||
@@ -2192,6 +2195,8 @@ export class Broker {
|
||||
return this.#requestProject(s, { verb: request.verb, args: structuredClone(args) });
|
||||
if (PROJECT_FILE_VERBS.includes(request.verb))
|
||||
return this.#requestProjectFile(s, { verb: request.verb, args: structuredClone(args) });
|
||||
+ if (LIBRARY_VERBS.includes(request.verb))
|
||||
+ return this.#requestLibrary(s, { verb: request.verb, args: structuredClone(args) });
|
||||
if (CREDENTIAL_VERBS.includes(request.verb)) return this.#requestCredential(s, request.verb, structuredClone(args));
|
||||
if (["limits", "limits.set", "organization.set", "organization.revision", "plugins", "plugins.set", "instances", "instances.set", "routes", "routes.set"].includes(request.verb)) {
|
||||
// Row 123 (#1617, REQ-COS-1, REQ-LIMIT-1): organization.set is limits.set for a role whose
|
||||
@@ -2441,6 +2446,26 @@ export class Broker {
|
||||
throw this.#refused(s, ProjectFailure && e instanceof ProjectFailure ? new BusError(e.code) : e, request);
|
||||
}
|
||||
}
|
||||
+ // C2-04 M4: only a verified human reads library text or status. Host Git
|
||||
+ // functions stay injected, preserving this module's sandbox import closure.
|
||||
+ async #requestLibrary(s, request) {
|
||||
+ const { verb, args } = request;
|
||||
+ try {
|
||||
+ this.#human(s);
|
||||
+ const fields = verb === 'library.file' ? ['project', 'path'] : ['project'];
|
||||
+ keys(args, fields, fields);
|
||||
+ if (!this.#library?.readFile || !this.#library?.status) fail('project-not-configured');
|
||||
+ const context = { business: this.#business(s.business), project: args.project };
|
||||
+ const result = verb === 'library.file'
|
||||
+ ? await this.#library.readFile({ ...context, path: args.path })
|
||||
+ : await this.#library.status(context);
|
||||
+ this.#secretCheck(result);
|
||||
+ return result;
|
||||
+ } catch (error) {
|
||||
+ const Failure = this.#library?.LibraryError;
|
||||
+ throw this.#refused(s, Failure && error instanceof Failure ? new BusError(error.code) : error, request);
|
||||
+ }
|
||||
+ }
|
||||
// The eight task verbs reach the trusted S3 handler here. It runs outside any transaction, gets the
|
||||
// cap to authorize and record through authorize() and recordTask(); refusals are recorded as in request().
|
||||
async requestTask(cap, request, handler) {
|
||||
diff --git a/packages/cli/tests/stack-release.test.mjs b/packages/cli/tests/stack-release.test.mjs
|
||||
index 7398247ce..0e316fd74 100644
|
||||
--- a/packages/cli/tests/stack-release.test.mjs
|
||||
+++ b/packages/cli/tests/stack-release.test.mjs
|
||||
@@ -1779,7 +1779,7 @@ export class Store {
|
||||
const RCOPIES=join(base,'rcopies');mkdirSync(RCOPIES);
|
||||
for(const [id,v,froms] of [[B,'3g',['3f']],[C,'3h',['3f','3g']],[A,'3g',['3f']],[C1,'3g',['3f']]]){
|
||||
const d=join(RCOPIES,id);
|
||||
- for(const p of ['scripts/mosaic','scripts/mosaic-config.mjs','packages/cli/src/config.mjs','packages/cli/src/errors.mjs','packages/bus/src/business.mjs','packages/plugins/src/kinds.mjs','packages/business/src','roles'])cpSync(join(repo,p),join(d,p),{recursive:true});
|
||||
+ for(const p of ['scripts/mosaic','scripts/mosaic-config.mjs','packages/cli/src/config.mjs','packages/cli/src/errors.mjs','packages/bus/src/business.mjs','packages/plugins/src/kinds.mjs','packages/business/src','packages/library/src','roles'])cpSync(join(repo,p),join(d,p),{recursive:true});
|
||||
if(id===C1)writeFileSync(join(d,'scripts','mosaic'),`#!/usr/bin/env bash\nexec node "${join(RCOPIES,B,'packages','cli','src','cli.mjs')}" "$@"\n`,{mode:0o755});
|
||||
for(const [f,text] of [['packages/cli/src/cli.mjs',id===A?'// fixture host from before row 163\nprocess.exit(1);\n':script(rHost)],['packages/webui/src/cli.mjs',script(rConsole)],['packages/bus/src/store.mjs',rStore(v,froms)],['packages/bus/src/migrate-schema.mjs',script(rMigrate)],['packages/bus/src/broker.mjs','export class BusError extends Error { constructor(code) { super(code); this.code = code; } }\n']]){mkdirSync(dirname(join(d,f)),{recursive:true});writeFileSync(join(d,f),text)}
|
||||
execFileSync('chmod',['-R','a-w',d]);
|
||||
@@ -1,10 +0,0 @@
|
||||
1: e333af4dc ! 1: a6101e21c feat: add human-only library projects and served reads
|
||||
@@ Metadata
|
||||
Author: Herb <[email protected]>
|
||||
|
||||
## Commit message ##
|
||||
- feat: add human-only library projects and served reads
|
||||
+ feat: carry reviewed C2-04 library entry onto row 197 landing
|
||||
|
||||
## BUILD-LOG.md ##
|
||||
@@ BUILD-LOG.md: Before: managed project/thread verbs had no Console conversation area. After: fi
|
||||
@@ -1,166 +0,0 @@
|
||||
# Row 222 build: C2-03a fetch-only library sync
|
||||
|
||||
Row 222, #1723, reviewer Dewey. Brief: C2-03a in the case 2 plan (sage-1853, sage-1854), with
|
||||
sage-2021 and sage-2022 adding to it. Built on Herb's row 215 candidate source e333af4dc (base
|
||||
f8276c5eb, packet 14a03d10f, Herb's BUILD.md blob f80f21919d95), then rebased with no conflicts
|
||||
onto 215's landing e54e05463 (sage-2099) as branch megavolt/row222-r2. The old branch
|
||||
megavolt/row222 is kept.
|
||||
|
||||
Between e333af4dc and e54e05463, two of 222's files changed. broker.mjs gained row 249's
|
||||
hostLineLeft lines, which 222 doesn't touch. stack-copy.sh gained row 66's `tools/unslop-hook`
|
||||
in COPY_PATHS, two lines below 222's `packages/library/bin`. In the range-diff, commit 1 differs
|
||||
only in that context line, and commits 2 and 3 are identical.
|
||||
|
||||
## What it does
|
||||
|
||||
- `packages/library/src/sync.mjs` (new):
|
||||
- `syncCommand('fetch', url, opts)` builds the one git command.
|
||||
- `sync(context, opts)` fetches the configured branch into `refs/remotes/library/<branch>`,
|
||||
then publishes under the C2-04 library lock:
|
||||
- a fast-forward moves `refs/heads/served`;
|
||||
- a non-fast-forward is held as `library-diverged` until a human accepts the tip;
|
||||
- a failed fetch keeps serving the old commit and records `lastError`.
|
||||
- `packages/library/bin/askpass` (new, sh) is git's GIT_ASKPASS helper. It answers only the two
|
||||
prompts for the configured host and user. For the password it reads the first line of the slot
|
||||
file. The token never reaches argv, env, git config, a URL, the state file or a log.
|
||||
- `packages/library/src/mapping.mjs`: an optional `user` (the bot account name). Sync refuses an
|
||||
entry without it.
|
||||
- Bus:
|
||||
- `broker.mjs`: `library.sync` is human-only. It takes `{project, accept?}`, and a held code
|
||||
becomes a recorded refusal.
|
||||
- `runtime.mjs`: a timer syncs every entry with a `user` at start and every 60 s.
|
||||
- `webui/src/cli.mjs`: the Console gets the call.
|
||||
- `scripts/stack-copy.sh` copies `packages/library/bin`.
|
||||
- Docs: library README "Sync" section, SURVEY-RUN.md step 5.
|
||||
|
||||
## Scope rulings followed
|
||||
|
||||
- sage-1853/1854: the timer lives in the bus runtime, not a separate unit. The slot is
|
||||
`<configDir>/secrets/<business>/library-gitea`, mode 0600, owned by the bus uid.
|
||||
- sage-2021: `user` is optional in the mapping and required for sync. Test runs wait for Sage's
|
||||
"clear".
|
||||
- sage-2022 / Filbert N2 (#1716 comment 30071):
|
||||
- Sync never runs gc or prune and never fetches with `--prune`. `maintenance.auto=false` and
|
||||
`gc.auto=0` come from SAFE.
|
||||
- Test "Filbert N2" holds a served commit, lets sync move served, then reads the held commit's
|
||||
blob.
|
||||
- The read path is unchanged, so readLibraryFile's whole-tree read stays (see Known costs).
|
||||
|
||||
## Choices and tradeoffs
|
||||
|
||||
1. **One sync per mirror, refused as `library-sync-busy`.** The C2-04 lock covers publication
|
||||
only, and readers wait 5 s for it, so the fetch runs outside it. A module-level set refuses a
|
||||
second sync into the same mirror instead of letting two fetches race. A timer tick that finds
|
||||
its pass still running is skipped, not queued.
|
||||
2. **Problems are read before the lock.** readLibrary over a large tree can take longer than a
|
||||
reader's 5 s lock wait. Problems belong to the tip alone, so they are computed outside and
|
||||
only published inside.
|
||||
3. **The served ref moves by compare-and-swap.** `update-ref refs/heads/served <tip> <old>`
|
||||
(zero id on a first sync). If the state write then fails, the ref goes back, so the ref and
|
||||
the state file never disagree.
|
||||
4. **State written via a temp file beside the mirror.** inspectMirror refuses unknown names
|
||||
inside the mirror, so the temp file goes in its parent directory (O_EXCL|O_NOFOLLOW, 0600).
|
||||
Then fsync, rename into the mirror, and fsync the directory.
|
||||
5. **Divergence is held, even through a later fast-forward.** Once diverged, served stays put
|
||||
until `accept`. `diverged.at` keeps the first detection time, and `diverged.commit` follows
|
||||
the tip, because that is the commit accept must name. A tip that comes back to the served
|
||||
commit clears it.
|
||||
6. **`accept` starts the record over.** It must equal the fetched tip (otherwise
|
||||
`library-accept-stale`). It writes a fresh record, which also clears a state left from
|
||||
another branch (readSyncState refuses a branch mismatch).
|
||||
7. **`lastFetch` is the last successful fetch.** A failed fetch leaves it alone and sets
|
||||
`lastError`.
|
||||
8. **`credential.helper=` reset in argv.** It stops a user or system helper from storing or
|
||||
offering the token. With GIT_TERMINAL_PROMPT=0 from gitEnv, askpass is the only source.
|
||||
9. **`http.followRedirects=false`.** A redirect to another host would get the prompt for that
|
||||
host, which askpass refuses anyway. Not following redirects means no request reaches the
|
||||
other host at all (tested with a 302).
|
||||
10. **`core.createObject=rename`.** A departure from the brief; see the next section.
|
||||
11. **Extra env keys.** GIT_CEILING_DIRECTORIES (git never looks above the mirror) and
|
||||
MOSAIC_LIBRARY_HOST/USER/SLOT (the askpass inputs, no secret). The brief named
|
||||
GIT_ASKPASS only.
|
||||
12. **`SAFE` exported from `packages/project/src/git.mjs`.** One word. Sync reuses the same
|
||||
safe `-c` set instead of copying it.
|
||||
13. **Row 199's fd-3 helper not reused.** publishRemote (packages/seat/src/working.mjs) puts an
|
||||
inline `credential.helper` in argv and feeds the token to it on fd 3, so node reads the token
|
||||
first. The brief names GIT_ASKPASS. With askpass, node only lstats the slot and never opens
|
||||
it; the helper script reads it. The prompt checks do the same job as row 199's host check.
|
||||
14. **The timer's test hook.** `startBroker({librarySync: {command, intervalMs, configDir}})` is
|
||||
refused unless `command` is a function. A JSON boot config can't carry a function, so a boot
|
||||
file can't set it, and process.mjs needs no change.
|
||||
15. **No server.mjs edit.** server.mjs awaits every verb in LIBRARY_VERBS with a 120 s socket
|
||||
timeout. Adding `library.sync` to LIBRARY_VERBS covers it.
|
||||
|
||||
## Departure from the brief: `core.createObject=rename`
|
||||
|
||||
Sage accepted this departure (sage-2024, rev 2898), and Dewey rules on it in review. The fetch argv
|
||||
(`syncCommand`, packages/library/src/sync.mjs) is:
|
||||
|
||||
```
|
||||
[...SAFE, '-c', 'protocol.https.allow=always', '-c', 'http.followRedirects=false', '-c', 'credential.helper=',
|
||||
'-c', 'core.createObject=rename', '-C', mirror, 'fetch', '--no-tags', '--no-write-fetch-head', '--no-recurse-submodules', '--end-of-options',
|
||||
parsed.href, `+refs/heads/${branch}:refs/remotes/library/${branch}`]
|
||||
```
|
||||
|
||||
Why: by default git files each new object by link, then unlink. While that runs, the object has
|
||||
nlink 2. C2-04's inspectMirror refuses any file in the mirror with nlink other than 1, so a reader
|
||||
running during a fetch could be refused. With `rename`, git never makes a second link.
|
||||
|
||||
The argv test in sync.test.mjs pins the full sequence, including this flag. The race itself is not
|
||||
tested (sage-2024).
|
||||
|
||||
## Known costs and residuals
|
||||
|
||||
- **readLibraryFile reads the whole tree to return one file** (C2-01 exclusions, Filbert's
|
||||
note on 215). 222 doesn't touch the read path, so it stays.
|
||||
- **The human transport times out at 5 s, a follow-up for Dewey to rule fix or defer.**
|
||||
packages/bus/src/human-cli.mjs builds its `Client` (packages/bus/src/client.mjs) with the default
|
||||
`timeout = 5000`. A fetch can take up to the GIT_LIMITS ceiling (100 s), so a human call to
|
||||
library.sync against a slow remote can return outcome-unknown while the sync finishes, and the
|
||||
state file records the result. The outer layers allow longer: busCaller and humanCall in
|
||||
packages/webui/src/bus.mjs use 30 s, and the bus server awaits library verbs for 120 s.
|
||||
222 has no Console route to fix. packages/webui/src/serve.mjs has no library route at all
|
||||
(library.file, library.status and library.sync are passed to startServer and unused there), and
|
||||
neither serve.mjs nor human-cli.mjs is in 222's paths. Follow-up: when the Console gains a
|
||||
library.sync route, give that path a 120 s client timeout.
|
||||
- **Problems are unbounded until the state hits 8 MiB.** A tree with very many problems makes
|
||||
the state write fail with `library-state-invalid`, and served doesn't move. No cap per
|
||||
problem list was added.
|
||||
- **No behaviour test for the `credential.helper=` reset, a follow-up for Dewey (sage-2033).**
|
||||
Only the argv test pins the reset: mutant 3 (drop it) was killed by that test alone. Today the
|
||||
reset is defence in depth. gitEnv() sets GIT_CONFIG_GLOBAL=/dev/null and GIT_CONFIG_NOSYSTEM,
|
||||
and C2-04's inspectMirror refuses any mirror config key outside its allowlist, so no config
|
||||
git reads can name a helper. gitEnv() also builds a fresh env, so the caller's env can't add
|
||||
one. A behaviour test would have to plant a helper through the test's `command` wrapper (for
|
||||
example GIT_CONFIG_COUNT/KEY/VALUE, the way the CA wrapper adds GIT_SSL_CAINFO), then show
|
||||
that git never calls it. Left as a named follow-up.
|
||||
- **stack-copy.test.mjs is not changed.** It copies `ls-files -co`, which includes bin/askpass.
|
||||
The cli package is not mine.
|
||||
|
||||
## Tests
|
||||
|
||||
- `packages/library/tests/sync.test.mjs` (new). It uses a fake Gitea over TLS
|
||||
(`packages/seat/tests/fake-gitea.mjs`), a made-up token and scratch roots, with no network.
|
||||
It covers the argv and env, the URL and user refusals, askpass prompts, first sync,
|
||||
fast-forward, Filbert N2, reader overlap, divergence and accept, accept across a branch
|
||||
change, a wrong token, a failed first fetch, a redirect, slot refusals, no user, and busy.
|
||||
- `packages/library/tests/mapping.test.mjs`: the `user` field.
|
||||
- `packages/bus/tests/library-sync.test.mjs` (new): bus refusals for agent, tester and reader;
|
||||
the human path; a refused boot hook; the timer.
|
||||
- Run on 4a0e0ab3a under grant sage-2028, each file whole: sync 15/15, mapping 8/8,
|
||||
packages/bus/tests/library.test.mjs 6/6, library-sync 5/5. No log contains the token.
|
||||
- Mutants, each against sync.test.mjs whole, all killed. After each one git diff was empty
|
||||
and askpass stayed 755.
|
||||
|
||||
| Mutant | Killed by |
|
||||
|---|---|
|
||||
| protocol.https.allow -> protocol.allow=always | argv test |
|
||||
| drop http.followRedirects=false | argv test, 302 test |
|
||||
| drop the credential.helper= reset | argv test only (see Known costs) |
|
||||
| askpass answers any prompt | helper prompt test |
|
||||
| askpass prints the token for Username | helper test and 8 sync tests |
|
||||
|
||||
The last mutant's log holds the made-up fixture token, because the mutant printed it.
|
||||
- After the rebase onto 215's landing: these 4 files again, plus
|
||||
packages/library/tests/mirror.test.mjs, packages/webui/tests/library-cli.test.mjs,
|
||||
packages/webui/tests/pinned-copy.test.mjs and packages/cli/tests/stack-copy.test.mjs.
|
||||
@@ -1,128 +0,0 @@
|
||||
# Row 243: too-open mode refusal tests set their mode with chmod
|
||||
|
||||
Brief: `docs/plans/2026-10-21_gate-env-rows.md` § "The startup token refusal test sets its file mode"
|
||||
(Sage, sage-1909). Reviewer Webby. Lands after row 197 (mos-1162). Design notes written before 197
|
||||
lands, read at `origin/refactor` 01e1fe512. Recheck the line cites against 197's landing before code
|
||||
starts.
|
||||
|
||||
## The defect
|
||||
|
||||
`writeFileSync(file, data, { mode })` and `mkdirSync(dir, { mode })` apply the process umask to the
|
||||
mode. A test that creates a "too open" file this way and expects a refusal passes under `umask 022`
|
||||
(0644 stays 0644) and fails under `umask 077` (0644 becomes 0600, and the source accepts it).
|
||||
|
||||
Row 197 r6 (df0c59608) runs each gate step under `umask 022` (`gate-lane.mjs:46`), so the lane no
|
||||
longer hits this. Row 243 still makes the tests independent of the umask, as the brief asks.
|
||||
|
||||
## Sweep
|
||||
|
||||
Method: every source-side mode check in `packages/*/src` and `scripts/` (grep for `mode & 0o...`), then
|
||||
the tests that reach each check's refusal branch, deciding whether the too-open object gets its mode at
|
||||
creation or from an explicit chmod. Also a scan of every `writeFileSync`/`mkdirSync`/`openSync` in
|
||||
`packages/*/tests` with a group or other bit in its mode (50 hits, 41 without a following chmod), and a
|
||||
grep of the refusal messages for objects created with no mode or by a shell-out. Read at
|
||||
`origin/refactor` with `git show` and `git grep`; nothing run.
|
||||
|
||||
Affected refusal tests, all three verified by reading the test (the fourth file, an accept test, follows the table):
|
||||
|
||||
| Creation | Test | Source check | Expected refusal |
|
||||
|---|---|---|---|
|
||||
| `packages/bus/tests/process.test.mjs:76` `writeFileSync(file, secret, { mode: 0o644 })` | startup token refusal returns safe code... | `bus/src/credentials.mjs:205` (must be 0600) | `credential-file`, exit 2 (:83-84) |
|
||||
| `packages/webui/tests/proof-cli.test.mjs:28` `writeFileSync(file, value, { mode })`, mode 0o644 from the `mode` case at :27 | proof startup refuses partial flags... | `webui/src/serve.mjs:234` (0600 or 0400) | status 2 (:38) |
|
||||
| `packages/webui/tests/sso.test.mjs:360` `writeFileSync(.../secrets/mosaic-stack/a, ..., { mode: 0o644 })` | 11: the CLI refuses --sso... | `webui/src/sso.mjs:45` (no group or other bits) | status 2 and the "no group or other permission bits" line (:361-363); the chmod to 0600 at :364 comes after |
|
||||
|
||||
Fix for each: keep the write, then `chmodSync(<path>, 0o644)` right after it. For `proof-cli.test.mjs`
|
||||
the chmod goes inside the case map after the write, with the case's own mode, so the 0o600 cases are set
|
||||
explicitly too.
|
||||
|
||||
Not affected (each sets the mode with a chmod or a chmodding helper before the code under test reads it):
|
||||
bus credentials.test :52, credential-store.test :55-61; business access.test :225-226, business.test
|
||||
:159/161/174, credentials.test :60, cli.test :151, helpers `writeJson`/`tokenFile`; cli cli.test :176,
|
||||
notifier.test :318/:321, stack-release.test :1220/1239/1294/1313/1552, stack-upgrade.test :426-430,
|
||||
case2-unit.test :340/:510/:635; control-board discord.test :79; discord binding.test :106/118/140/277,
|
||||
notify.test :76, setspark.test :110, git.test :138/:360, offline-check.test :21; mosaic safety.test :80;
|
||||
queue review.test :214/:228; ledger gitea-helper-raw.test :113; webui service.test :797, sso.test :310;
|
||||
bus host-tools.test :182/:266. The 0o644/0o755 adapter and fake-binary writes (launcher, thread-launch,
|
||||
session, sandbox, checkout, commit, etc.) aren't read by a mode check, or are only checked for the exec
|
||||
bit, which 0700 keeps. `host-tools.test.mjs:205`, `:271` and the confDir at `:77` expect acceptance and
|
||||
only need "not group-writable".
|
||||
|
||||
Mode checks with no refusal test at all (not this row; listed for the record): `bus/src/store.mjs:121`,
|
||||
`bus/src/host-run.mjs:71`, `business/src/organization.mjs:28/45/109/141`,
|
||||
`conversation/src/controller.mjs:299`, `mosaic/src/materialize-fixture.mjs:16`,
|
||||
`mosaic/src/refresh-fixture.mjs:64`, `seat/src/session.mjs:72`, `scripts/git-credential-mosaic.mjs:49`,
|
||||
and the mode branch of `scripts/stack-release.sh:1952`.
|
||||
|
||||
Fourth file, folded in by Sage (sage-1918): `packages/cli/tests/stack-instances.test.mjs:84` and `:89`
|
||||
assert 0644 on the config and `instance.json`. `scripts/mosaic-config.mjs:337` creates them with
|
||||
`openSync(file, "wx", 0o644)` and no chmod, so under `umask 077` they come out 0600 and the test fails.
|
||||
This is an accept test of a source mode, not a refusal test.
|
||||
|
||||
| Creation | Test | Source | Ruling |
|
||||
|---|---|---|---|
|
||||
| `scripts/mosaic-config.mjs:337` via `bootstrap()` (`stack-instances.test.mjs:41`, a `spawnSync` of `scripts/bootstrap.sh`) | the `--instance` create test, :79-89 | `createExclusive` passes 0o644 and the umask narrows it | test-only (sage-1918) |
|
||||
|
||||
- No change to `mosaic-config.mjs`. Letting the operator's umask narrow the config is the source's
|
||||
choice; a chmod to 0644 would make the config wider than that umask. No row asks for it.
|
||||
- `bootstrap()` runs its child under an explicit `umask 022`, the pattern from `gate-lane.mjs:46`:
|
||||
`run("/bin/bash", ["-c", 'umask 022; exec "$@"', "bash", BOOTSTRAP, ...args], homeEnv(home))`. Every
|
||||
`bootstrap()` call goes through it (:79, :99, :102, :119, :127, :136, :140, :152, :165, :169), so the
|
||||
0644 assertions still prove the mode the source asks for, whatever the gate's umask.
|
||||
- New assertion: a `bootstrap --instance` run under `umask 077` makes the config and `instance.json`
|
||||
0600. That pins that the source honors the umask, so a later chmod "fix" fails a test. The directories
|
||||
stay 0700 in both runs (they're created with `mode: 0o700`, which 077 can't narrow).
|
||||
- The `config()` helper (:42) has no mode assertion and stays as it is.
|
||||
|
||||
Tests outside `packages/*/tests`: the five `scripts/foundation/*.test.mjs` files have no open-mode
|
||||
write. `cli.test.mjs:144/148` chmods to 0o000 and 0o600, which doesn't depend on the umask. The
|
||||
`agents/*/work` probe tests are review evidence, not gate steps (`discoverSteps` doesn't run them), so
|
||||
they're out of scope.
|
||||
|
||||
## Tests
|
||||
|
||||
- Each of the four files runs whole twice, once under `umask 022` and once under `umask 077`
|
||||
(`bash -c 'umask 077; node --test <file>'`). Both pass. The brief requires this for process.test.mjs;
|
||||
Sage extended it to all four (sage-1918).
|
||||
- Proof that the change matters: before the change, the same four files under `umask 077` fail on the
|
||||
named assertions. I record that run too, on the slot, so the 077 pass after the change is meaningful.
|
||||
- Order (mos-1162): this lands after 197 r6, so r6's proof ran on the unchanged test.
|
||||
|
||||
## Files (expected)
|
||||
|
||||
`packages/bus/tests/process.test.mjs`, `packages/webui/tests/proof-cli.test.mjs`,
|
||||
`packages/webui/tests/sso.test.mjs`, `packages/cli/tests/stack-instances.test.mjs`. Test-only. No
|
||||
source change.
|
||||
|
||||
## Build (sage-2056: start on row 197's landing a36523713)
|
||||
|
||||
Branch `morgana/row243`, one commit on a36523713. Cites rechecked there: all hold except proof-cli's
|
||||
write, which is now `proof-cli.test.mjs:30` (was :28).
|
||||
|
||||
- `bus/tests/process.test.mjs`: imports `chmodSync`; `chmodSync(file, 0o644)` after the write at :76.
|
||||
- `webui/tests/proof-cli.test.mjs:30`: `chmodSync(file, mode)` after the write, with each case's own
|
||||
mode, so the 0o600 cases are set explicitly too.
|
||||
- `webui/tests/sso.test.mjs:360`: `chmodSync(..., 0o644)` after the write, before the `--sso` start
|
||||
that must refuse.
|
||||
- `cli/tests/stack-instances.test.mjs`: `underUmask(mask, home, args)` runs `scripts/bootstrap.sh`
|
||||
through `/bin/bash -c 'umask <mask>; exec "$@"'`; `bootstrap()` is `underUmask("022", ...)`. New
|
||||
subtest in T-I1: under umask 077 the config dir and root are 0700, and the config and `instance.json`
|
||||
are 0600.
|
||||
- Hash pins: no test or script names any of the four files (a grep for the basenames; positive control
|
||||
`stack-release.test` found in two files). `stack-release.test.mjs:2122` mentions
|
||||
`stack-instances.test.mjs` only in a comment.
|
||||
|
||||
Tests: on Sage's slot (sage-2062, plan approved in sage-2059), 18:55Z. My busy check read CLEAR before
|
||||
and after. Each file ran whole with `node --test --test-concurrency=2` from its package, under
|
||||
`bash -c 'umask <mask>; exec ...'`, with TMPDIR from `mktemp -d /mnt/storage/scratch/tmp/g243XXXX`.
|
||||
Script `/mnt/storage/scratch/morgana-r243/slot243.sh`, logs in `logs/` next to it.
|
||||
|
||||
| Tree | umask | process | proof-cli | sso | stack-instances |
|
||||
|---|---|---|---|---|---|
|
||||
| base a36523713 | 077 | 7/1 | 2/1 | 27/1 | 21/2 |
|
||||
| candidate 137bda3af | 022 | 8/0 | 3/0 | 28/0 | 24/0 |
|
||||
| candidate 137bda3af | 077 | 8/0 | 3/0 | 28/0 | 24/0 |
|
||||
|
||||
(pass/fail.) The base fails are the predicted ones: "startup token refusal returns safe code...",
|
||||
"proof startup refuses partial flags...", "11: the CLI refuses --sso...", and in stack-instances the
|
||||
0644 subtest "alpha and beta get a 0700 config dir..." plus its parent T-I1 (so 2). stack-instances has
|
||||
one more test on the candidate (the umask 077 subtest). No unpredicted failure.
|
||||
@@ -1,200 +0,0 @@
|
||||
# Row 66: managed sessions run the unslop check on both harnesses
|
||||
|
||||
Sage, 2026-10-20. Brief: `docs/plans/2026-10-11_managed-session-config.md`, section "Managed
|
||||
sessions run the unslop check on both harnesses", blob 21ae25a328d4. Issue #1559. Reviewers:
|
||||
Dewey and Filbert. Built in the worktree `/mnt/storage/scratch/sage-b66` (branch `sage/row66`)
|
||||
on base 5487ed39d.
|
||||
|
||||
Candidate: see the commit line in the review request. `candidate-manifest.sha256` in this
|
||||
directory has the sha256 of each changed file at the candidate.
|
||||
|
||||
## What changed
|
||||
|
||||
**Wiring.** Both harness modules mount `tools/unslop-hook/lists.json`, `unslop-check.js` and
|
||||
the harness's own entry (pi `extension.ts`, Claude Code `claude-hook.js`) read-only at their
|
||||
own paths, and the bundle manifest lists the three in `sources` with their digests. Pi loads
|
||||
`extension.ts` as the second entry of `MOSAIC_EXTENSIONS`, after the gate extension. Claude
|
||||
Code's `settings.json` gains a Stop hook and a UserPromptSubmit hook, each
|
||||
`timeout -k 2 10 '<node>' '<dir>claude-hook.js' stop|prompt; exit 0`, hook timeout 20, no
|
||||
matcher. Neither can block a reply or a prompt.
|
||||
|
||||
**claude-hook.js** (new). `stop` checks each assistant message with text since the turn's
|
||||
prompt and logs `checked` or `flagged`. `prompt` checks the last reply and, when it has tells,
|
||||
prints the extension's notice, word for word, as `additionalContext`, once per reply (it reads
|
||||
the log for an earlier `notice_injected` with the same entry id). A broken lists.json logs
|
||||
`broken_lists`; any other fault logs `hook_failed`; the exit is always 0.
|
||||
|
||||
**The operator channel.** The runner sets `MOSAIC_UNSLOP_LOG` to `<run>/unslop.jsonl` after the
|
||||
module's variables, so a module can't point it elsewhere. After the landing turn and after each message turn it reads what the
|
||||
log gained (whole lines only, from an offset). The next RESULT it sends ends with a note. The
|
||||
whole note, both parts and the blank line before them, is at most 600 characters (r2):
|
||||
|
||||
- `[unslop: N reply|replies of this session flagged since the last note: <details>. The session gets a correction notice on its next turn.]`
|
||||
- `[unslop: the check is broken, so this session's replies go unchecked: <reason>]`, once a run.
|
||||
|
||||
That RESULT is what `mosaic talk` and `mosaic follow` print. A turn that sends no reply (an
|
||||
incoming RESULT, the landing turn) keeps its note for the next one. `note()` doesn't change
|
||||
state and `sent()` runs only after `message.send` succeeds, so a failed send keeps the note.
|
||||
`clip()` caps the body at 32000 characters plus its 33-character cut line before the note, so the
|
||||
sum is at most 32633, under the bus limit of 32768. The broken reason is cut at 300 where the
|
||||
runner takes it, from the log or from its own read failure, so the broken part is at most 371
|
||||
characters and the flagged part is cut to what is left.
|
||||
|
||||
**Counts.** `unslopCounts(path)` reads the log after the session ended:
|
||||
`{checked, flagged, patterns: {<source>: n}, notices, broken}`. A missing log gives zeros.
|
||||
Findings now carry `source`, the entry's pattern id (`ms-unslop:7`), so `patterns` is per id.
|
||||
|
||||
**The stack copy (r2).** `scripts/stack-copy.sh` `COPY_PATHS` gains `tools/unslop-hook`. Both
|
||||
modules join their files under `REPO`, and a session launched from a pinned copy has
|
||||
`REPO = copies/<sha>`. Without it every managed session from a copy past this row would fail at
|
||||
bundle build with ENOENT (Dewey P1, comment 29440).
|
||||
|
||||
## Round 2
|
||||
|
||||
Round 1 (candidate 8ec03b45a, manifest e68c6bce5ec4) got changes from Filbert (29439) and Dewey
|
||||
(29440). Round 2 carries:
|
||||
|
||||
- F1 (both): a note with both parts wasn't bounded. A 300-character reason, a long flagged part
|
||||
and a clipped answer came to 32934 (Filbert) or 33004 (Dewey), over 32768, and the broker
|
||||
refused the send. `note()` now gives the flagged part only the room the broken part leaves, and
|
||||
`fresh()` cuts every reason at 300, the runner's own read-failure reason included. Tests: the
|
||||
runner test with an answer of 40000 characters, a 400-character `hook_failed` reason and 30
|
||||
flagged replies (note ≤ 600, body ≤ 32768, cut line at 32000), and a unit check that both
|
||||
parts come to exactly 600 and that a read failure on a 250-character path is cut.
|
||||
- F2 (Filbert; Dewey's M3): no test failed a send through `main()`. The new runner test has the
|
||||
broker refuse the first RESULT. The note then rides the next RESULT. One correction to the
|
||||
F1 consequence as written: the broker marks a received message delivered, so the refused
|
||||
message isn't received again in that run. It stays unread and its sender gets no reply; the
|
||||
turn doesn't rerun.
|
||||
- P1 (Dewey): `COPY_PATHS` gains `tools/unslop-hook`. The copy fixtures in
|
||||
`stack-copy.test.mjs` and `pinned-copy.test.mjs` copy `tools/unslop-hook` too, and the
|
||||
pinned-copy top-level list gains `tools`. A new `stack-copy.test.mjs` test makes a copy, loads
|
||||
both harness modules from it, and checks that the adapter, the six unslop paths and the mounts
|
||||
are under the copy and exist.
|
||||
- N1 (Filbert): the two session-test comments say `<dir>/unslop.jsonl`.
|
||||
- N2 (Filbert), doc-only follow-up: the brief's `<run>/session/unslop.jsonl` (:463) and "print
|
||||
mode notifies nobody" (:477) are stale. The brief is Jason's text for this row; the deviation
|
||||
below records the path.
|
||||
- Dewey's notes, no change: the Claude Code Stop timing (finding 3 below) gets a look in the
|
||||
landing session; `patterns` keys per entry source, which is the brief's "per pattern".
|
||||
|
||||
r2 mutants, each killed by its intended test (`mutants-r2.log`):
|
||||
|
||||
| Mutant | Killed by |
|
||||
|---|---|
|
||||
| K1 the r1 `note()` cut | the clipped-answer runner test (the send is refused and it times out) and the unit check |
|
||||
| K2 `fresh()` doesn't cut the reason | the unit check |
|
||||
| K3 `sent()` before `message.send` | the refused-send runner test |
|
||||
| K4 `COPY_PATHS` without `tools/unslop-hook` | the copy test |
|
||||
|
||||
## Ship list against the brief
|
||||
|
||||
| Brief item | Where |
|
||||
|---|---|
|
||||
| A reply with a tell gets a correction notice on the next turn, both harnesses | `pi-session.test.mjs`, `claude-session.test.mjs`, row 66 four-turn tests: notices per request `[0, 1, 1, 2]`, notice text matched in the second request |
|
||||
| A clean reply gets none | same tests: turn 2 is clean and turn 3's request carries no new notice |
|
||||
| Broken lists.json fails closed: no clean verdict, operator told once, session alive | the row 66 broken-lists tests per harness: checked 0, flagged 0, first note broken, second note empty, the session answers both turns |
|
||||
| Counts readable after the session ends | `unslopCounts` on each session's log: `{checked: 4, flagged: 2, notices: 2, broken: null}`, patterns non-empty |
|
||||
| Interface 1 and the export list unchanged | no harness module export added or removed; the runner gains `unslopLog`, `unslopCounts`, `unslopNotes` |
|
||||
|
||||
## Findings made while building
|
||||
|
||||
1. **extension.ts read the wrong reply.** Pi 0.85.1 `getBranch()` returns entries root first
|
||||
(`session-manager.js:958-967` reverses the leaf-to-root walk). `before_agent_start` took the
|
||||
first assistant entry it met, which was the session's first reply, every turn. In the
|
||||
four-turn test the old code gave notices `[0, 1, 2]` over three turns (turn 3 re-noticed
|
||||
turn 1); walking from the end gives `[0, 1, 1]`. Fixed in `extension.ts`; this also affects
|
||||
the fleet copy under `~/.mosaic/tools`, which I didn't touch.
|
||||
2. **claude-hook replies() merged replies.** Grouping by `message.id` across the transcript
|
||||
merged two replies that shared an id (the test API answers `msg_mock` for all). It now groups
|
||||
adjacent assistant lines only, keyed by the first line's uuid. Before the fix turn 4 got no
|
||||
notice (`[0, 1, 1, 1]`).
|
||||
3. **Claude Code Stop timing.** On the first turn of a new session the transcript didn't yet
|
||||
hold the reply when Stop ran, so the hook checked `last_assistant_message` with an empty
|
||||
`entryId`. On resumed turns the reply was in the transcript. The verdict is the same either
|
||||
way; only the entry id differs.
|
||||
4. The finding detail format is `banned word "delve" x1`.
|
||||
|
||||
## Deviations
|
||||
|
||||
- **The log path is `<run>/unslop.jsonl`, not the brief's `<run>/session/unslop.jsonl`.** A
|
||||
thread run's session directory is the thread's store, and
|
||||
`packages/cli/tests/thread-launch.test.mjs:179` pins that a thread run keeps no per-run
|
||||
`session/`. My first build made `<run>/session` for the log and failed that test in the gate
|
||||
(452/453). The brief's other line, "`unslop.jsonl` in the run directory", still holds, and each
|
||||
run keeps its own log.
|
||||
|
||||
- **`packages/seat/tests/sandbox.test.mjs`** isn't an owned file. Its pin
|
||||
`binds(args).length === list.length - 1` broke because the modules now mount three more files.
|
||||
It is now `- 4`, and the test asserts the three unslop read-only binds by name.
|
||||
- **`scripts/stack-copy.sh`** and the two copy tests aren't owned files. The copy change is P1
|
||||
above. PB3 of the Part B window (`repin-partB-proof.md`) holds `scripts/stack-copy.sh` still
|
||||
until B7, so this row lands after the Part B window has run.
|
||||
- `MOSAIC_EXTENSIONS` is set through the pi module's `env`, not in the runner.
|
||||
- `unslop-check.js` gained the `source` field on findings (needed for per-pattern counts).
|
||||
|
||||
## Limits
|
||||
|
||||
- The log is in the run directory, which the session can write. A session could forge or erase
|
||||
its own counts. They are the session's report, not host evidence.
|
||||
- The pi extension's dedupe is in memory: after a restart, or when a turn's final message is
|
||||
tool-only, the same earlier reply can get a second notice.
|
||||
- `hook_failed`, `skipped_broken` and `broken_lists` all count as broken for the operator note.
|
||||
- No blocking (Q84 option B), no list changes, no skill changes: out of scope by the brief.
|
||||
|
||||
## Gate
|
||||
|
||||
Recorded with the candidate in the review request: test-unslop-check, the harness, plugins,
|
||||
seat and cli suites, and every `scripts/test-*.sh`. At landing Sage runs one managed session per
|
||||
harness and attaches the notice, the correction and the counts.
|
||||
|
||||
## Round 4
|
||||
|
||||
Round 3 (2369c00e3 on sage/row66-r3, base c40d846cb, manifest 42e3876ca168) had approvals from
|
||||
Filbert (29770) and Dewey (29771). Since then rows 200, 199, 232, 233, 240 and 238 changed three
|
||||
of the 23 paths: `docs/TOOLS.md`, `scripts/stack-copy.sh` and
|
||||
`packages/cli/tests/stack-copy.test.mjs`. Round 4 is the two round 3 commits cherry-picked onto
|
||||
4ced5e63d (sage/row66-r4). Neither pick had a conflict, and the tree equals a hand merge of each
|
||||
path with `git merge-file`. No code changed: `git diff BASE TIP | git patch-id --stable` is
|
||||
6d085621fd35 for both rounds.
|
||||
|
||||
- Row 232 added `copy --bundle` (`copy_bundle`). It builds the bundle with `copy_tree`, which
|
||||
copies `COPY_PATHS`, so a bundle copy also carries `tools/unslop-hook`. No extra change needed.
|
||||
- The Part B hold under Deviations is void. Part B was superseded by the Q175 SSO work and will
|
||||
not run, so nothing holds `scripts/stack-copy.sh`.
|
||||
- Review scope: the merge on the three moved paths and this section. The other 19 paths have the
|
||||
same blobs as round 3.
|
||||
|
||||
Rebased again on fefd54e13, after row 212 landed (ee7b2f137), as branch `sage/row66-r4b`, before the round 4
|
||||
request went out. 212 added `packages/library/src` to `COPY_PATHS` and a library line to the
|
||||
`stack-copy.test.mjs` file list. None of the four picks had a conflict. Every file's patch-id equals the 4ced5e63d
|
||||
build's except `scripts/stack-copy.sh`, where the only change is the hunk's context line
|
||||
(`packages/queue/src packages/library/src`). Row 66's two added lines are the same.
|
||||
|
||||
Rebased again on 29ce1e360, after rows 195, 213 and 231 landed, as branch `sage/row66-r4c` (r4b stays at
|
||||
49ad61963). Two of row 66's paths moved: `adapters/README.md` and `docs/TOOLS.md`. TOOLS.md merged without a
|
||||
conflict. In adapters/README.md, row 213 rewrote the skill-cap paragraph, because `claude` now gets the prompt
|
||||
as a file. The merge keeps 213's paragraph whole and adds row 66's "The unslop check (row 66)" section after
|
||||
it. Row 66's old cap sentence is dropped, since it described the argument limit that 213 removed. Every other
|
||||
path has the same blob as on r4b. Row 213 also changed the harness and both adapter scripts, so all of row 66's
|
||||
harness tests run whole again on this base before the request.
|
||||
|
||||
Rebased again on 7b9737953, after rows 245, 248 and 249 landed, as branch `sage/row66-r4d` (r4c stays at
|
||||
670b83f65). Only `docs/TOOLS.md` moved under row 66: row 245 rewrote the paragraph on what root reads in the
|
||||
host check. The cherry-pick had no conflict. `git patch-id --stable` of row 66's whole diff is 508bb684eade on
|
||||
both bases, and so is each file's own patch-id, TOOLS.md included. So row 66's hunks are byte-identical and only
|
||||
their context moved. The one test that names TOOLS.md, `packages/cli/tests/stack-release.test.mjs`, uses it in a
|
||||
message string and is in the singles list.
|
||||
|
||||
Rebased on a36523713 after row 197 landed (mos-1186 item 4), as branch `sage/row66-r5` (r4d stays at
|
||||
82c830779). Row 197 also touched `packages/harness/tests/claude-session.test.mjs` and `pi-session.test.mjs`.
|
||||
The cherry-pick had no conflict. The range-diff shows commit 1 differing only in one hunk header of
|
||||
pi-session.test.mjs, where git now names the context line. Commits 2-7 are `=`. `git patch-id --stable` is
|
||||
0049d05fb585 for the whole diff and d67275ac4251 without `agents/` on both bases. Correction: the r4d note
|
||||
above gives 508bb684eade for the whole diff. That number came from e25f76f54 before the 7b9737953 rebase. The
|
||||
whole-diff number on r4d is 0049d05fb585. The harness suite runs whole again on this base before landing.
|
||||
|
||||
Correction (Filbert round 4 N2, comment 30086): the r4c paragraph says "Row 66's old cap sentence is
|
||||
dropped." That's wrong. In round 3's diff the 64 KiB cap sentence is unchanged context, so row 66 never
|
||||
wrote it. Row 213 replaced it, and none of row 66's lines were dropped. The landing sessions are in
|
||||
LANDING-SESSION.md.
|
||||
@@ -1,43 +0,0 @@
|
||||
# Row 66 landing sessions (mos-1186 items 2-3)
|
||||
|
||||
Sage, 2026-10-21. Both ran on a scratch data root built from the candidate tree, branch `sage/row66-r5`
|
||||
at 273fff6f9 on a36523713, as row 64's D2 did (rc13bcd555652). The scripts were
|
||||
`/mnt/storage/scratch/sage-r66r5x/d2s/d2-build.mjs` and `d2-drive.mjs`. They used the business example
|
||||
with stand-in token files, tracker and Gitea URLs pointing at 127.0.0.1:9, and a scratch project repo.
|
||||
Nothing live was touched. The six skills were installed and enabled on each data root with
|
||||
`scripts/skill.sh` from the candidate tree.
|
||||
|
||||
Before the sessions, the harness suite ran whole on 273fff6f9: 149 pass, 0 fail, 12 s
|
||||
(2026-10-21T18:47:42Z).
|
||||
|
||||
## Claude Code, run r4ab24630d323 (18:48Z)
|
||||
|
||||
The chief and cto were bound, and the coder was launched through `launcher.fromSession` on claude-code,
|
||||
model claude-sonnet-5-5. The launch bundle names `tools/unslop-hook/claude-hook.js`, `unslop-check.js`
|
||||
and `lists.json`.
|
||||
|
||||
- Turn 1. cto asked for one sentence with four banned words. The RESULT body `mosaic talk` would print
|
||||
ends with the operator note:
|
||||
`[unslop: 1 reply of this session flagged since the last note: banned word "additionally" x1; banned word "crucial" x1; banned word "testament" x1; banned word "vibrant" x1. The session gets a correction notice on its next turn.]`
|
||||
- Turn 2. `unslop.jsonl` logs `notice_injected` for that turn. The coder's transcript has the notice as
|
||||
UserPromptSubmit hook additional context in the API request:
|
||||
`UNSLOP NOTICE (mechanical style check, not the user speaking): your previous reply contained violations of the fleet writing standard (SYSTEM.md / ms-unslop): ...`.
|
||||
cto asked the coder to quote it. The coder answered "I can't answer that one, and I won't quote
|
||||
anything from it." So the notice reached the model, which chose not to repeat it. Its reply checked
|
||||
clean.
|
||||
- Counts from `unslopCounts`: checked 2, flagged 1, patterns `ms-unslop:7` 4, notices 1, broken null.
|
||||
|
||||
This scratch instance has no `mosaic talk` view of its own, so the note above is the RESULT body the bus
|
||||
returned to cto. That is the text `mosaic talk` and `mosaic follow` print.
|
||||
|
||||
## pi, run r1dd94171bede (launch only)
|
||||
|
||||
The coder launched on pi, model claude-sonnet-5-5. The launch bundle names
|
||||
`tools/unslop-hook/extension.ts`, `unslop-check.js` and `lists.json`. No turn ran. This host has no
|
||||
credential pi reads until P19 #383 settles, and mos-0865 D2 rules out mapping the Claude Code token into
|
||||
a pi variable. No `unslop.jsonl` was written. Counts: checked 0, flagged 0, notices 0.
|
||||
|
||||
## Still open
|
||||
|
||||
Vikunja #454 tracks both live checks. Claude Code runs in the first re-pin whose tree includes row 66,
|
||||
backup first. Pi runs one full session with a tell after #383. See `docs/plans/DEFERRED.md`.
|
||||
@@ -1,90 +0,0 @@
|
||||
# 10-24 window, notes for draft 1
|
||||
|
||||
Sage, 2026-10-21T19:40Z. These are working notes, not a draft. Draft 1 is cut from them once NEW is fixed.
|
||||
Draft 0 is `repin-1024-draft0.md`.
|
||||
|
||||
## Changes since draft 0
|
||||
|
||||
- **Phase 2 order (mos-1197 item 3).** Phase 2 now runs after this window's re-pin is verified, not on
|
||||
10-23 before it, and Jason picks the hour. So this window's OLD is the live pin, not a phase 2 copy, and
|
||||
draft 0's line 14-17 and Q2 are out of date.
|
||||
- **Console flags.** They stay as they are: no `--sso` and no `--send`. `--send` goes on with `--sso` in the
|
||||
phase 2 window (mos-1197 2a). P0 checks that the window's activate line carries neither flag.
|
||||
- **NEW (mos-1161).** NEW is the latest code landing when draft 1 is cut. At 19:40Z that is e54e05463 (row
|
||||
215). 194 hasn't landed, so P3 has no lifecycle step unless it lands with a full gate first.
|
||||
- **Row 66 live check (Vikunja #454, DEFERRED 3b0aef995).** This is the first re-pin whose tree includes
|
||||
2c38325ec. Add a step after the window is verified. One Claude Code managed session with a prompt that
|
||||
draws a known tell, then record the operator note on the RESULT, the next-turn notice and the
|
||||
`unslop.jsonl` counts. Backup first (Q173). Pi isn't run (#383).
|
||||
|
||||
## OLD, read 19:38Z from `stack-release.sh status mosaic-stack` (read only)
|
||||
|
||||
- Copy 4429a104f6d65ccf165f6c83b5d1dce3147dfde0, schema 3i, pm true, activation 20261020T220206Z-4429a104f6d6.
|
||||
- Console flags: `--port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username
|
||||
--allow-user jason.woltje --tester-port 7333`. P1 re-reads these on the day.
|
||||
- Check pass, unit flags match the pointer, 123 commits of drift.
|
||||
|
||||
## Schema
|
||||
|
||||
`git diff --name-only 4429a104f origin/refactor` shows only `packages/bus/schema.sql` and
|
||||
`migrations/3i-3j.sql` (row 234). Nothing since c771a36f4 adds a step, so the migration is still 3i to 3j.
|
||||
Recheck this at the cut. Row 206 (3k-3l) hasn't landed.
|
||||
|
||||
## Rows NEW carries after c771a36f4 (first-parent, code paths)
|
||||
|
||||
| Row | Commit | Live effect to check |
|
||||
|---|---|---|
|
||||
| 240 | c515273db | Installer I4: root host check, pins, boot unit. This window doesn't run it. |
|
||||
| 228 | 86249ac55 | ZAI_API_KEY joins the session env allowlist. The live config sets no ZAI key, so the env is unchanged. Check in P3. |
|
||||
| 238 | d49b1f2bd | sso-config takes `--instance` on named instances. Default instance, `--sso` off, so there's no effect. |
|
||||
| 212 | ee7b2f137 | New package packages/library. The live business has no library entry. |
|
||||
| 195 | b65014647 | scripts/case1-accept.sh, root only. Not run. |
|
||||
| 213 | 361ba2387 | Creative roles (roles/companion.*), persona file and block, launch-settings, bundle.mjs. Live roles are chief, pm, coder and reviewer. P3: the chief's and pm's bundles are unchanged apart from the new code path, and one pm reply. |
|
||||
| 231 | 29ce1e360 | Library reader fixes. No live library. |
|
||||
| 235 | b1fece6f0 | Machine grant row b: raise binding, executor, reconcile, revoke and sweep (broker, host-grant, credentials, runtime). The live business has no hosts. P3: bus start runs the grant reconcile and sweep, and they change nothing. Show the log lines. |
|
||||
| 221 | 300766450 | Persona import script, with a count-only dry run. Not run. yaml 2.9 joins package-lock, so P3 runs npm ci on the copy. |
|
||||
| 247 | 856c1826b | Persona import follow-up. Not run. |
|
||||
| 245 | 6d5545d44 | case1-accept F9 follow-up. Not run. |
|
||||
| 248 | 8a04f4aa4 | Test stubs only. |
|
||||
| 249 | 9de5a57ab | broker: hostLineLeft on a grant whose install never returned. No grants live. The A22b look-alike count in draft 0 already covers `hostLineLeft`. |
|
||||
| 197 | a36523713 | Test lane fixture. No live effect. |
|
||||
| 66 | 2c38325ec | Managed sessions run the unslop check, runner.mjs, and stack-copy.sh COPY_PATHS adds tools/unslop-hook. P3 checks that the copy has tools/unslop-hook. The live check is above. |
|
||||
| 243 | 6096b051b | Tests only. |
|
||||
| 215 | e54e05463 | Library entry kind, consumer skips, M9, bare mirror, library.file and library.status. The live business has no library entry. M9 refuses any organization write that changes `projects`, so P3 checks that the chief's or pm's usual organization writes don't touch projects. |
|
||||
| 250 | 1b6158ce2 | Conversation shim and K12 test. No live effect on its own. |
|
||||
| 222 | 0b33f5e9d | Fetch-only library sync: library.sync bus verb, a 60 s timer per library entry with a sync user, the askpass helper, and stack-copy.sh COPY_PATHS. The live business has no library entry, so the timer starts nothing. P3: the copy has packages/library/bin/askpass with its mode, and bus start logs no `library:` line. |
|
||||
| 196 | 7247d80c7 | Human boundary: SO_PEERCRED on the bus socket, the interpreter receipt in bus/peercred-starts.jsonl, and the Console's private tester socket in place of `--tester-port`. The section "If 196 lands before the cut" applies. P3: bus start writes a receipt line, and the Console starts with `--tester-socket`. |
|
||||
|
||||
Added 2026-10-21T20:30Z. NEW at this hour is 0b33f5e9d (row 222, landed 20:13Z), the latest code
|
||||
landing. PRD 1.9 (f48725cfc) and 1.10 are doc and test changes, but `packages/tasks/requirements.json`
|
||||
is in the copy, so `task.create` takes REQ-WEB-2 and REQ-INST-2 as ids after the re-pin. P3: requirements
|
||||
returns 70 ids at 1.10. 196 r6 (527b9a1e6, on f48725cfc) is in its gate, so the section below may apply.
|
||||
|
||||
Added 2026-10-21T21:02Z. 196 landed at 7247d80c7 (20:57Z), and c3d88840c after it is doc-only. NEW at
|
||||
this hour is 7247d80c7, so the section below applies.
|
||||
|
||||
## If 196 lands before the cut
|
||||
|
||||
196 retires the Console's `--tester-port` (webui cli.mjs:30, "activate explicitly with --tester-socket").
|
||||
The live Console runs `--tester-port 7333`, so a NEW that carries 196 changes the Console's command line.
|
||||
Draft 1 would then need:
|
||||
- the activate line with `--tester-socket` and its path;
|
||||
- the P2 unit diff showing only that change;
|
||||
- a P3 rehearsal that starts the Console with it.
|
||||
|
||||
bus.tester stays Jason's. The tester path changes how the test client reaches the Console, but not who can
|
||||
reach it from outside, so it stays Q173 work. I confirm that with Mos in draft 1. If 196 hasn't landed, NEW
|
||||
leaves it out and none of this applies.
|
||||
|
||||
mos-1198 item 4: until row 253 (#1758, case2-unit.sh and case1-accept.sh to `--tester-socket`) lands, no
|
||||
Case 1 or Case 2 host (.53, .54) takes a copy that carries 196. This window is dragon-lin only, so it isn't
|
||||
blocked, but any .53 or .54 step that names NEW waits on 253.
|
||||
|
||||
Row 250 landed 1b6158ce2 at 19:42Z (conversation shim and K12 test). It has no live effect on its own, but
|
||||
it is now the latest code landing if the cut were made today.
|
||||
|
||||
## Still open from draft 0
|
||||
|
||||
- The P-step evidence for rows 199, 210 and now 235 at bus start, from a P3 rehearsal run.
|
||||
- Recount the restore-guard table list from NEW (T46).
|
||||
- Q3 operator: Darkwing if free.
|
||||
@@ -1,168 +0,0 @@
|
||||
# 10-24 window: re-pin 4429a104f to 7247d80c7 (rows 190, 199, 210, 234 and on, row 196 last), with 3i-3j (draft 1)
|
||||
|
||||
Sage, 2026-10-21, draft 1, for mos-1145 under DECISIONS Q173. Mos checks this file at its commit before P0.
|
||||
Any change to this file or to NEW after that check means Mos checks it again (mos-0849/0850). The step layout
|
||||
follows `repin-4429a104f.md`. Where a step is unchanged, I name it and say what differs. Draft 0 is
|
||||
`repin-1024-draft0.md`, and the working notes are in `repin-1024-draft1-prep.md`.
|
||||
|
||||
## Who, and what nobody does
|
||||
|
||||
- Q3 below names the operator: Darkwing if they're free, otherwise me. Mos verifies each step's output before
|
||||
the next one, and runs `rehearse` (P3).
|
||||
- Jason has no step. Q173 covers a re-pin of this test system with a migration, a backup first and a STATE
|
||||
report after. Nothing is pruned.
|
||||
- Nobody acts as Jason. No `--by jason`, no human shell or tmux pane, and every bus read and write carries
|
||||
`--tester`. `bus.tester` stays as it is. If it isn't `true`, stop at P1.
|
||||
- No pi (P19 #383). No Save in the human Console, no `mosaic name`.
|
||||
- Outside reach doesn't change. There's no `--sso` and no `--send`. Both go on together in the Q175 phase 2
|
||||
window, which runs after this window is verified, when Jason starts it (mos-1195, mos-1197). The proof pair
|
||||
stays unset. The tunnel still forwards 7332 only (P4 and W10).
|
||||
- One Console flag does change. Row 196 retires the tester's TCP port. The live Console runs
|
||||
`--tester-port 7333`, and NEW refuses that flag. So W5 converts it explicitly with `--tester-socket`, and
|
||||
the tester listener becomes the 0600 socket `$DATA/console/tester.sock`. Only 127.0.0.1 could reach port
|
||||
7333, so nobody outside gains or loses reach. Mos ruled this Q173 work in mos-1211 item 2. The socket is
|
||||
narrower than loopback TCP, and Mos's acceptance in mos-1015 (on sage-1359) already accepted losing
|
||||
browser access to 7333. DECISIONS has no Jason ruling on 7333 (mos-1214 item 2).
|
||||
- Under mos-1198, .53 and .54 take no copy carrying 196 until row 253 lands. This window is dragon-lin only.
|
||||
|
||||
## Names
|
||||
|
||||
- OLD, live: `4429a104f6d65ccf165f6c83b5d1dce3147dfde0`, schema 3i, pointer `pm: true`, activation
|
||||
`20261020T220206Z-4429a104f6d6`. The Console runs `--port 7332 --public-host mosaic.woltje.com --auth-header
|
||||
X-authentik-username --allow-user jason.woltje --tester-port 7333`, read from `status` at 19:38Z. P1
|
||||
re-reads all of these on the day. I don't copy them from this file.
|
||||
- NEW: `7247d80c7af7ffa70fc61557406bf491cdf3bfc7`, the row 196 landing, the latest code landing when this
|
||||
draft was cut (mos-1161). It is 135 commits past OLD (`git rev-list --count 4429a104f..7247d80c7`). The commit
|
||||
after it, c3d88840c, is doc-only and doesn't move NEW. If 244 or 251 land before P0, NEW stays here unless
|
||||
Mos rules otherwise (Q1).
|
||||
- 194 hasn't landed, so P3 has no lifecycle step (mos-1161).
|
||||
- `REPO`, `P`, `WIN=agents/sage/work/window-repin-7247d80c7/` and `SNAP` are as in `repin-4429a104f.md`, with
|
||||
the sha checks at P0 and before S1, S2 and any D3.
|
||||
|
||||
## What NEW carries over OLD
|
||||
|
||||
This is draft 0's table, rows 201 through 234 plus PRD 1.7 and 1.8, unchanged, together with these rows from
|
||||
`git log --first-parent c771a36f4..7247d80c7`, limited to packages, scripts, roles, contracts, adapters,
|
||||
skills, tools, migrations and the package files:
|
||||
|
||||
| Row | Commit | Live effect to check |
|
||||
|---|---|---|
|
||||
| 240 | c515273db | Installer I4: root host check, pins and the boot unit. This window doesn't run them. |
|
||||
| 228 | 86249ac55 | ZAI_API_KEY joins the session env allowlist. The live config sets no ZAI key, so the env doesn't change. P3 checks this. |
|
||||
| 238 | d49b1f2bd | sso-config takes `--instance`. Default instance with `--sso` off, so no effect. |
|
||||
| 212 | ee7b2f137 | New package, packages/library. The live business has no library entry. |
|
||||
| 195 | b65014647 | scripts/case1-accept.sh, root only. Not run. |
|
||||
| 213 | 361ba2387 | Creative roles, persona file and block, launch-settings, bundle.mjs. P3 checks that the chief's and the pm's bundles are unchanged apart from the new code path, and gets one pm reply. |
|
||||
| 231 | 29ce1e360 | Library reader fixes. No live library. |
|
||||
| 235 | b1fece6f0 | Machine grant row b. The live business has no hosts. P3: bus start runs the grant reconcile and sweep, they change nothing, and the log lines are shown. |
|
||||
| 221, 247 | 300766450, 856c1826b | Persona import script and follow-up. Not run. yaml 2.9 joins package-lock, and W0's npm ci covers it. |
|
||||
| 245, 248, 249 | 6d5545d44, 8a04f4aa4, 9de5a57ab | case1-accept F9, test stubs, and `hostLineLeft` on a grant whose install never returned. No grants are live. The look-alike count below covers `hostLineLeft`. |
|
||||
| 197 | a36523713 | Test lane fixture. No live effect. |
|
||||
| 66 | 2c38325ec | Managed sessions run the unslop check. COPY_PATHS adds tools/unslop-hook, and P3 checks the copy has it. W12 is the live check. |
|
||||
| 243 | 6096b051b | Tests only. |
|
||||
| 215 | e54e05463 | Library entry kind, consumer skips, M9 and the bare mirror. M9 refuses an organization write that changes `projects`, so P3 checks that the chief's and the pm's usual organization writes don't touch it. |
|
||||
| 250 | 1b6158ce2 | Conversation shim and K12 test. No live effect on its own. |
|
||||
| 222 | 0b33f5e9d | library.sync verb, a 60 s timer per library entry, and the askpass helper in COPY_PATHS. No library entry, so the timer starts nothing. P3: the copy has `packages/library/bin/askpass` with its mode, and bus start logs no `library:` line. |
|
||||
| PRD 1.9, 1.10 | f48725cfc, add0f1aae | `packages/tasks/requirements.json` is in the copy. W9: the pm's requirements read answers version 1.10 with 70 ids. |
|
||||
| 196 | 7247d80c7 | The human boundary. See the next section. |
|
||||
|
||||
## Row 196 in this window
|
||||
|
||||
What the code does (`scripts/stack-release.sh:791-845`, `docs/TOOLS.md` "Console tester listener"):
|
||||
|
||||
- An inherited `--tester-port` with no `--tester-socket` refuses `tester-transport-migration` before anything
|
||||
stops. So `--tester-socket` goes on W3 and W5, and the plan's drop line must read
|
||||
`--tester-port 7333 (replaced by private Unix socket)`.
|
||||
- Before the stop, activate checks the socket path: `$DATA/console/tester.sock` must fit 107 bytes, and
|
||||
`console/` must be absent or a directory with no symlink, owned by the instance's uid, with no group or
|
||||
other bits. A failure refuses `tester-socket-path` before the stop. P1 reads `ls -ld $DATA/console`
|
||||
(expected absent).
|
||||
- Activate preflights the pinned root-owned system Python, records its identity, and checks the bus's fresh
|
||||
start receipt. Each bus start appends one line to `$DATA/bus/peercred-starts.jsonl`. P3's rehearsal must show
|
||||
the preflight passing on dragon-lin, and W9 reads the one new receipt line.
|
||||
- `rehearse` starts NEW's Console with `--tester-socket` under its scratch data root when the copy carries
|
||||
the socket marker (`stack-release.sh:2153-2155`). It doesn't run activate's path check from line 815, so
|
||||
that check first runs live at W3. P1's `ls -ld $DATA/console` plus the path length are its only preview.
|
||||
If the rehearsal Console fails to start on the socket, P3 stops and the log goes to Mos.
|
||||
- Direct browser access to the tester is gone, with Mos's acceptance in mos-1015. W10's browser check on
|
||||
127.0.0.1:7333 becomes `node packages/cli/src/tester-http.mjs GET /api/config` and `GET /api/bus/agents`, run from
|
||||
the NEW copy against the live data root. Each must answer 200 with the same tester flags OLD's 7333 gave.
|
||||
`mosaic ... --tester` still uses broker.sock.
|
||||
|
||||
Rollback is where 196 matters most. Without `--sso`, rollback takes the Console flags from the pointer, and
|
||||
after W5 the pointer carries `--tester-socket`. OLD's Console doesn't support the socket. So rollback to OLD
|
||||
drops the tester listener, the plan prints `--tester-socket (tester disabled; no TCP fallback)`, and port 7333
|
||||
doesn't come back. The test client then has no tester listener until a new activate. Q4 asks Mos how to
|
||||
handle that.
|
||||
|
||||
## Schema and backups
|
||||
|
||||
- `SCHEMA_VERSION` is 3i at OLD and 3j at NEW (`packages/bus/src/store.mjs:17`). The only step is
|
||||
`packages/bus/src/migrations/3i-3j.sql` (row 234, tables `hosts` and `host_grants`). Nothing after c771a36f4
|
||||
changes schema.sql or adds a step. `--plan` must say `migration: 3i -> 3j`.
|
||||
- Restore guard, recounted at NEW (T46, `packages/cli/tests/stack-release.test.mjs:913`). COUNTED is the
|
||||
same 11 tables (`stack-release.sh:404`). The untimed list has six: `host_grants`, `hosts`, `meta`,
|
||||
`message_threads`, `sqlite_sequence` and `task_comment_cursors`. Each write to `hosts` or `host_grants` goes
|
||||
with a `grant.*` event, which is counted. A D3 snapshot still covers them, as draft 0 says.
|
||||
- W5 takes the stopped store backup every activate takes (SHA256SUMS, SCHEMA 3i, STAMP) plus the rollback
|
||||
set. Before `--migrate` writes, I check that SCHEMA reads 3i and record the backup's SHA256SUMS hash. W0b
|
||||
copies the business file, as last time.
|
||||
- Grant look-alikes (row 234 A22b, gizmoduck-0107): P3, and again just before W5, on the backup copy. Count the
|
||||
`action.allowed` events whose body.action or body.operation starts with `grant.`, or whose body has
|
||||
`hostLineLeft`. Expect 0. Any nonzero count stops the window until I've read those rows.
|
||||
- Rollback after the migration isn't the plain rollback. OLD is 3i and the store is 3j, so going back needs
|
||||
`--restore <W5 activation>`, which loses the events written after W5. Mos decides any restore past W5.
|
||||
|
||||
## Before the window (nothing stopped)
|
||||
|
||||
| # | Who | Step |
|
||||
|---|-----|------|
|
||||
| P0 | Mos | The `$P` sha check, and this file's commit. |
|
||||
| P1 | Sage | `status`: pointer, activation, schema 3i, Console flags, unit flags match. The business file sha256 and `business-check.mjs` LOAD_OK for OLD now and NEW after W0. `ls -ld $DATA/console` (expected absent). `bus.tester` is `true`. |
|
||||
| W0 | Sage | `scripts/stack-copy.sh copy $NEW` in a gap between gate runs. The package-lock diff is empty. The copy has `tools/unslop-hook` and `packages/library/bin/askpass`, with the mode NEW's tree gives it. |
|
||||
| P2 | Sage | `console-check.sh $NEW` on a stub Console on a scratch port, once without and once with `--tester-socket` under a scratch data root. CONSOLE_PASS both. Render the Console unit for NEW from REPO's `webui-service.sh` and diff it against the live unit. The only difference allowed is `--tester-port 7333` becoming `--tester-socket`. Diff the bus unit too. It must match apart from the copy path. |
|
||||
| P3 | Mos | `stack-release.sh rehearse $NEW mosaic-stack --backup <latest live activation> --port <scratch>` with `--migrate` on the backup copy. It must show the 3j step, row counts before and after, the interpreter preflight passing, a receipt line, the grant reconcile and sweep changing nothing, no `library:` line, no publish or land decision open (rows 241, 242), the look-alike count 0, and one pm reply. As in mos-1107, Mos also starts NEW's Console by hand with the pointer's flags, with `--tester-socket` in place of `--tester-port`, and reads healthz, `/api/config` and the two tester-http reads. |
|
||||
| P4 | Sage | The tunnel read. |
|
||||
| P5 | Sage | The four service scripts are held at NEW (`git diff --quiet $NEW HEAD --` on them, and empty porcelain). If 244 or 251 lands and touches one of them, P5 fails and the window waits for Mos. |
|
||||
| P6 | Sage | The 7332 matrix (a)-(g) on OLD, saved as `$WIN/matrix-old.txt`, plus the two tester reads on 7333 with curl, for W10 to compare against. |
|
||||
|
||||
## The window
|
||||
|
||||
| # | Who | Step |
|
||||
|---|-----|------|
|
||||
| W0b | Sage | The business file copy. |
|
||||
| W1 | Sage | Idle check, the start stamp from `date -u`, then S1 with `$SNAP --held`. Open pm tasks from row 42: pm finishes or parks them before W5, or I record which piece crosses the window. |
|
||||
| W2 | Sage | `status`: pointer on OLD, `pm: true`, 3i, unit flags match. |
|
||||
| W3 | Sage | `stack-release.sh activate $NEW mosaic-stack --pm --migrate --tester-socket --plan`. It must show OLD to NEW, `migration: 3i -> 3j`, the backup line, the drop line for `--tester-port 7333`, and a Console line with OLD's other flags exactly: no `--send`, no `--sso`, no proof pair. Any other difference stops here. |
|
||||
| W4 | Sage | The unit reads, as in the 177-185 plan. |
|
||||
| W5 | Sage, on Mos's go | The same command without `--plan`. Exit 0, `result ok`, and every gate check passes, `pm_launched` included. Record the activation id, the backup path, STAMP and the backup SHA256SUMS sha256. Then `status`. |
|
||||
| W9 | Sage, after Mos verifies W5 | The 177-185 W9 list, plus: the webui journal since the W5 stamp (with `UTC`) has no `Sign-in:` line; `/proc/<Console pid>/cwd` names the NEW copy; `$DATA/console/tester.sock` is 0600 in a 0700 `console/`; `peercred-starts.jsonl` gained one line for this start; the bus journal has the grant reconcile and sweep lines and no `library:` line; the pm's requirements read gives 1.10 with 70 ids. |
|
||||
| W10 | Sage | The matrix again, as `$WIN/matrix-new.txt`, identical to `matrix-old.txt` apart from the lines the pin changes, each one named. The two tester reads through `tester-http.mjs` match P6's. Port 7333 has no listener (`ss -ltn`). Then P4 again. A write without a signed-in session must still be refused. That's Console POST through the main port, with no session. This is the check mos-1195 asks for before phase 2 is done, so I run it here too, as a baseline. |
|
||||
| W11 | Sage | STATE report in `$WIN/STATE.md`, posted on P19 386, 412 and 435 (J2, mos-1215), and on the Gitea issues for 190, 199, 210, 234 and 196. |
|
||||
| W12 | Sage, after W11 | Row 66's live check (Vikunja #454). One Claude Code managed session with a prompt that draws a known tell, then the operator note on the RESULT, the next-turn notice and the `unslop.jsonl` counts. Backup first (Q173). Pi isn't run (#383). |
|
||||
|
||||
## Stop conditions and rollback
|
||||
|
||||
The same as the 177-185 plan. Two failures in one window: stop and report (mos-0823).
|
||||
|
||||
Rollback before W5 writes is `rollback --plan`, then the real run. After the migration it needs `--restore
|
||||
<W5 activation>`, with Mos deciding. Both drop the tester listener (see Row 196 above). Keep every copy.
|
||||
Prune nothing.
|
||||
|
||||
## Questions for the plan check, answered (mos-1214 item 3)
|
||||
|
||||
- Q1: NEW stays 7247d80c7 unless a landing fixes something this window needs.
|
||||
- Q2: mos-1211 item 2 rules the `--tester-port 7333` to `--tester-socket` change Q173 work.
|
||||
- Q3: Darkwing operates if free, and I check. Otherwise I operate.
|
||||
- Q4: after a rollback, the tester listener stays off for the window's length, and the tester goes through
|
||||
broker.sock. A same-copy re-activation of OLD with `--tester-port 7333` goes to Mos only if a rollback
|
||||
holds past the window day.
|
||||
|
||||
## What Sage ran for this plan
|
||||
|
||||
Read only, 2026-10-21 between 20:40Z and 21:20Z: the path-limited first-parent log c771a36f4..7247d80c7,
|
||||
`git rev-list --count`, `SCHEMA_VERSION` at both ends, `git diff --name-only` on the schema and migrations,
|
||||
`stack-release.sh` lines 40-47, 125-158, 404, 791-845, 886-919 and 2140-2157, T46 in
|
||||
`stack-release.test.mjs:913`, `packages/cli/src/tester-http.mjs`, and TOOLS.md:1274-1310 on the tester
|
||||
listener. Nothing ran against
|
||||
live. OLD's values come from the 19:38Z `status` read, and P1 reads them again.
|
||||
@@ -1419,28 +1419,4 @@ are never rewritten or removed; corrections are new entries.
|
||||
2026-10-21T06:47:54Z | researcher | row 228 (#1729) round 3 in review (rev 2702; start rev 2700) | rebase of r2 onto the 234 landing c771a36f4 as researcher/row228-r3 cf18c42b9 (one commit, pushed) with Webby's round 2 N1 (:711 and :718); manifest 82cf98c6 (3 files); slot sage-1796: session.test 13 + host.test 42 = 55/0, manifest OK before and after, busy228.sh copy named in the clear; r2 94/0 and M1 killed stand (seat blobs unchanged); request attempt left in requesting state (lock held by sage-238-review-2b when the outcome rev was written, exit 3; transport said failed pre-send, no token), Sage resolves and posts as jarvis; packet agents/researcher/work/queue-228/r3
|
||||
2026-10-21T07:29:23Z | researcher | row 228 (#1729) landed as 86249ac55 (pushed 07:25Z by Sage) | patch-id b6ffe31feb0d matches my r3 candidate cf18c42b9 (checked here against origin/refactor); Sage combined gate with 238: seat 165/0, cli 640/0, scripts 585/0; queue note rev 2725, done rev 2727, #1729 closed comment 29966 (sage-1824); q228r2 worktree removed, branches researcher/row228, -r2 and -r3 stay on origin and locally; packets agents/researcher/work/queue-228 r1 r2 r3 uncommitted
|
||||
2026-10-21T15:19:14Z | Sage (Opus 5.5, 1ef1e4f8) | MVP push 10-21 afternoon: rows 249, 197 proof 3/4, 222 singles, 66 r4d, queue-commit | 249 landed 9de5a57ab (+7b9737953 DEFERRED N1, #1751 closed, Vikunja 445 c442); 197 proof 3 rc=1 on a driver defect, Herb's fix a5b636750 to Webby, proof 4 set up in sage-r197p4; 222 singles 34/34 and 5 mutants killed (sage-2028); 66 round 4 in review (82c830779, c30083/30084); queue revs 2642-2904 committed 0636721e6
|
||||
2026-10-21T15:20:10Z | Dewey (Opus 5.5, 84fb346c) | row 66 r4 review (sage-2036, sage/row66-r4d 82c830779, manifest 6cfd812da4ca) | APPROVE 30085, rev 2905; rebase only, code lines identical to r3 (-U0 patch-id b3e9e076e5f1), four shared files clean; no tests run; dewey-0768 Sage
|
||||
2026-10-21T15:20:58Z | Filbert (Opus 5.5, 048f3c63) | row 66 r4 review (sage-2037, sage/row66-r4d 82c830779, manifest 6cfd812da4ca) | APPROVE 30086, rev 2906; static, no tests; rebase only, row 66 +/- lines identical to r3 next to rows 212/213/232/245; N1 code-only patch-id d67275ac4251 (508bb684eade includes BUILD.md), N2 BUILD.md cap-sentence wording; packet-only notes
|
||||
2026-10-21T18:55:21Z | Filbert (Opus 5.5, 048f3c63) | row 215 r2 merge-scoped review (herb-0093, mos-1160, herb/row215-on197 dde3445ab, manifest 40d9722a) | APPROVE 30103, rev 2924; static, no tests; patch-id d191e7e9586c same as r1, 28/30 blobs+modes = e333af4dc, broker.mjs and stack-release.test.mjs = clean merge-file onto a36523713; r1 N1-N4 carry, suite gate Sage's
|
||||
2026-10-21T19:06:16Z | Sage (Opus 5.5, 1ef1e4f8) | row 66 landing, #435/J2 brief, 196 r2/215/243/250/251 gate coordination (mos-1186, mos-1193, mos-1195, mos-1197) | row 66 LANDED 2c38325ec + DEFERRED 3b0aef995, #1559 closed; 640aa03f2 brief pushed; REQ-WEB-2 wording to Mos (sage-2067); 196 r2 stop 2 ruled (sage-2072); 215 gate on slot (Herb); #1754 for 243; 250 Gizmoduck/Filbert, 251 Darkwing/Dewey
|
||||
2026-10-21T19:20:16Z | Darkwing (Opus 5.5, 7525c8e4) | row 251 T27 ssh-add lifetime (sage-2075, sage-2084, Vikunja #453, Gitea #1756) | darkwing/row251 68f2dfd4b pushed (e5e4b2e5a step 1, c19b4167e -t 2 + 3.5 s sleep, host-run.mjs unchanged); in-review r1 rev 2944, request 30121 resolved rev 2947, manifest c7497de3; Dewey woken darkwing-0111; slot asked darkwing-0110, nothing run
|
||||
2026-10-21T19:23:11Z | Dewey (Opus 5.5, 84fb346c) | row 251 r1 static review (darkwing-0111), 68f2dfd4b, digest c7497de3 | no blocking findings; OpenSSH 10.5p1 citations checked at V_10_5_P1; comment 30126 on #1756; verdict to be recorded on r2 with part A results; no tests run
|
||||
2026-10-21T19:23:48Z | Filbert (Opus 5.5, 048f3c63) | row 250 r1 static review (gizmoduck-0146, sage-2091, gizmoduck/row250 e9cfd92f8, manifest 14ff20b6) | CHANGES 30125, rev 2950; static, no tests; C1 R13 never calls h.ctrl.close() so the controller server (controller.mjs:548) stays open and cohort.test.mjs is expected not to exit; fix await h.ctrl.close() before h.c.close(); cause trace, step 1, no loosening, R13 coverage, no pins, no drift all hold
|
||||
2026-10-21T19:28:22Z | Filbert (Opus 5.5, 048f3c63) | row 250 r2 static review (gizmoduck-0148, gizmoduck/row250-r2 c1a858975, manifest eca0b8e2) | APPROVE 30130, rev 2957; static, no tests; C1 fixed: R13 closes its controller after the checks (cached release, one entry) and again in finally (no-op); no drift, no findings; gate run Sage's
|
||||
2026-10-21T19:31:02Z | Herb (gpt-6.1-sol, f6cf4287) | row 215 C2-04 landed as e54e05463 (#1716 closed c30133, queue done rev 2955) | Filbert round 2 APPROVE c30103/rev 2924; candidate dde3445ab on a36523713 preserves rows 249 and 197. Granted sage-2071: business 209/0, seat 166/0, cli 729/0, project 41/0, bus 604/0, webui 300/0 with one environment editor-build skip; all ten scripts/test-*.sh 585/0; total 2634/0 in 926.796 s, ended 19:20:47Z, leftover process sweep 0, temp root and owned network removed. Sage accepted receipts and landed after 6096b051b (sage-2097); no further 215 work.
|
||||
2026-10-21T19:34:18Z | Sage (Opus 5.5, 1ef1e4f8) | row 215 landing, 196 r3 grant withdrawn for the base change and r4 granted, 250/222/244/251 slot order | 215 LANDED e54e05463 (patch-id 2f68188b6c9d = a36523713..dde3445ab, tree = merge-tree; herb-0095 2634/0, webui esbuild skip ruled env); #1716 closed c30133, done rev 2955, Vikunja 416 c471. sage-2092 withdrawn (r3 conflicted with 215), sage-2096 to Gander r4 f8a59e6aa, mutant kills kept by blob sha. 250 r2 request c30131 (rev 2958), Filbert APPROVE 2957. 244 issue #1757 (rev 2959). 222 r2 c9aa9c2ee accepted; gate scope per the row. Order: Gander, Gizmoduck, Megavolt, Morgana, Darkwing.
|
||||
2026-10-21T19:46:12Z | Dewey (Opus 5.5, 84fb346c) | row 222 r1 static review (megavolt-0095), c9aa9c2ee, manifest c2121b55 | APPROVE, comment 30138 on #1723, queue rev 2966; rulings: createObject=rename accepted, 5 s human timeout deferred with STATUS codes in the follow-up, credential.helper reset argv-only accepted; notes N1-N5; no tests run
|
||||
2026-10-21T19:49:37Z | Sage (Opus 5.5, 1ef1e4f8) | row 250 landing, row 196 r5 grant (mos-1198) and resume (mos-1200), F27 row 253 | 250 LANDED 1b6158ce2 (patch-id 29786caa, Filbert rev 2957, Gizmoduck slot green), #1755 closed c30139, Vikunja 450; 196 r5 91e3696ef hunk checked by Duckworth, webui 304/0; my queue add tripped Gander's busy check, not a stop (mos-1200), resume on 05e940117; row 253 #1758 brief 0cdead66c
|
||||
2026-10-21T20:46:03Z | Sage (Opus 5.5, 1ef1e4f8) | row 222 landing, PRD 1.9 and 1.10, Pocket ID design row 255, row 254 brief, 196 r6 grants | 222 LANDED 0b33f5e9d (megavolt-0098 gate, Dewey rev 2966, patch-id edb60b4f), #1723 closed c30147, done rev 2972; follow-up row 254 (#1759, after 196); PRD 1.9 f48725cfc (REQ-WEB-2, REQ-DEC-3 amended, mos-1202); 458 brief 7d08237e1 (#1760), row 255 rev 2976; PRD 1.10 add0f1aae REQ-INST-2 post-v1 (mos-1204, tasks 97/0, bus req 3/0); Vikunja 458 c478, 416 c479; queue-commit 21def2850 revs 2968-2976; 196 r6 gate gander-0066 2334/0, 38/38 killed; 244 granted sage-2147; 196 r6 resume granted sage-2145 after self-tee busy refusal (mos-1205). Miss: landed 222 before checking 196's manifest; 196 carried results voided. Class rule now (mos-1204, replaces the mos-1200 interface grep): before any landing push, compare every in-review and in-progress row's manifest against the landing's paths.
|
||||
2026-10-21T21:14Z | Sage (claude-opus-5-5, 1ef1e4f8) | row 196 landed 7247d80c7 and doc commit c3d88840c (#1694 closed, comment 30159); rows 253 and 254 briefed and launched (Gander #1758, Megavolt #1759); Honker 194 b4 rebase ruling (creative delete stays refused, Agents page hides Delete on the server predicate, actor-threaded delete deferred); queue revs 2977-2994 committed abb352d27 incl. Morgana 244, Gander 196 r6, Duckworth 196 m2, Darkwing 251 r2; 10-24 window draft 1 written (NEW 7247d80c7, --tester-socket, Mos mos-1211 agrees Q173) | landed and launched; draft 1 to Mos next
|
||||
2026-10-21T16:34:44Z | Huey (gpt-6.1-sol) | mos-1183, Q198/Q199 system-manager design, Vikunja 452, huey/system-manager-design on 6c75887b0 | design and six proposed slices documented; pinned citations and docs checks pass; no build, suite, live action or paid call; Gitea/queue capture remains Sage-owned
|
||||
2026-10-21T18:45:47Z | Huey (gpt-6.1-sol) | mos-1194, Q198 design r2, scrooge-0001 findings 1–8, Vikunja 452 | all findings addressed in design and slice acceptance criteria; 30 citation references checked, no suites/live changes/paid calls; Mos routes r2 back to Scrooge
|
||||
2026-10-21T19:56:11Z | Huey (gpt-6.1-sol) | mos-1201/1201a, Q198 design r3, scrooge-0002 N1–N3 | three doc notes applied; Q4 ready for Mos’s combined owner approval question; no builds, suites, live changes or paid calls
|
||||
2026-10-21T20:19:53Z | Huey (gpt-6.1-sol) | mos-1203, Q198 design r4, DECISIONS Q204 | Q1–Q3 approved quotes recorded, cap settings interpretation labelled, Q4 pending and P1 unchanged; doc-only checks, no builds/live changes/paid calls
|
||||
2026-10-21T20:48:49Z | Huey (gpt-6.1-sol) | mos-1206, Q198 r5 protected mode/outage recovery, Vikunja 452 | Q205/Q206 recorded with labelled readings and probe/resume acceptance proposals; Q4 superseded, Q22 pending; doc checks only, no builds/suites/real probes/live changes/paid calls; Scrooge re-review via Mos
|
||||
2026-10-21T21:04:37Z | Huey (gpt-6.1-sol) | mos-1208/mos-1210, Q198 r6, Q207 and scrooge-0003 S-F1–S-F7 | central fallback/parallel probes, request failure and recovery release fixes, quota/probe budgets and credential isolation documented; doc checks only, no builds/suites/probes/live changes/paid calls; Mos routes r6 to Scrooge
|
||||
2026-10-21T21:39:25Z | Huey (gpt-6.1-sol) | mos-1222, Q198 r6.1, scrooge-0004 N1–N3 | small doc touch-up verified, no runtime changes/builds/tests/probes/paid calls; Scrooge confirms three items before Sage handoff
|
||||
2026-10-21T21:12:18Z | Della (GPT-6.1-Sol, mos-1213) | Vikunja 460 independent post-v1 email plan, della/email-plan from c3d88840c | 341-line proposal, 13 post-v1 rows, six Jason questions, 42 pinned citation anchors verified. Canonical queue next della: nothing. Planning only, no live mail/service/MVP/queue change; phase B/C with Mos, no Ludwig plan read. Commit and branch push authorized by dispatch.
|
||||
2026-10-21T21:37:07Z | Della (GPT-6.1-Sol, mos-1220) | Vikunja 460 phase B email cross-review, della/email-plan | Ludwig plan 4a27b73ac and review 143415779 read in full. Cross-review has ten findings and eleven merged questions; original Della plan unchanged. Canonical queue next della: nothing. Static verification only; review push followed by direct della-0002 handoff to both threads under Q210. Phase C base choice remains with Mos.
|
||||
2026-10-21T21:43:02Z | Della (GPT-6.1-Sol, mos-1223) | Vikunja 460 phase C merged email plan, della/email-plan | Mos-selected base plus Ludwig grafts; original plans/reviews unchanged. Sixteen post-v1 rows, eight READY and eight WAIT/optional; eleven Jason questions. Canonical queue next della: nothing. Docs-only checks. Commit/push then immediate della-0003 handoff to Ludwig/Mos; Sage landing/queueing follows approval.
|
||||
2026-10-21T21:45:20Z | Della (GPT-6.1-Sol, mos-1223 / ludwig-0004) | merged email plan focused review fixes | External content-key/expiry location and restore tests specified; fake registry work READY, production registry gated on PRD approval/Q4. Merged plan 399 lines, original plans/reviews unchanged. Commit/push and focused Ludwig review before Sage handoff.
|
||||
|
||||
+29
-47
@@ -418,7 +418,6 @@ One read-only tree supplies the bus, Console and human CLI (row 85,
|
||||
`copy` requires a canonical checkout (.git directory); --allow-worktree
|
||||
is a test override. COMMIT must be reachable from both local refactor and
|
||||
origin/refactor. It archives the runtime/import closure, adapters, roles,
|
||||
`tools/unslop-hook` (the unslop check both harness modules mount, row 66),
|
||||
RELEASE, package.json and package-lock.json; refuses missing manifests;
|
||||
runs npm ci inside the temporary copy; removes write permissions; and
|
||||
renames beside the target. A published existing copy stays unchanged.
|
||||
@@ -465,7 +464,7 @@ reports checkout or copy identity and refactor drift, and writes nothing.
|
||||
|
||||
```
|
||||
scripts/stack-release.sh adopt BUSINESS
|
||||
scripts/stack-release.sh activate ID BUSINESS [--pm | --pm-after-harness] [--migrate] [--tester-socket | --tester-port N (legacy copies)]
|
||||
scripts/stack-release.sh activate ID BUSINESS [--pm | --pm-after-harness] [--migrate] [--tester-port N]
|
||||
[--proof-header NAME --proof-file PATH | --no-proof | --sso] [--no-send] [--timeout S] [--plan]
|
||||
scripts/stack-release.sh pm-on BUSINESS [--timeout S]
|
||||
scripts/stack-release.sh rollback BUSINESS [--restore ACTIVATION [--events N]] [--timeout S] [--plan]
|
||||
@@ -562,8 +561,7 @@ refuses `capture-failed` before it stops anything. Adopt uses the same rule.
|
||||
The Console's row 178 proof pair gets into the pointer only through `activate`
|
||||
(row 187). `--proof-header NAME --proof-file PATH` puts the pair in the
|
||||
pointer's Console flags and the unit after the preview flags and before `--send`
|
||||
and the tester flag (`--tester-socket`, or `--tester-port` for legacy copies),
|
||||
where `webui-service.sh` renders it, replacing any pair
|
||||
and `--tester-port`, where `webui-service.sh` renders it, replacing any pair
|
||||
already there. `--no-proof` drops it. Either may name the live copy, which a
|
||||
plain activate refuses with `already-active`, so the proof goes on or off
|
||||
without changing copies; `--no-proof` with no pair in the pointer still refuses
|
||||
@@ -693,12 +691,6 @@ backup's checks it prints `BACKUP_STORE <activation id> schema <version>`.
|
||||
it never picks another port. `--timeout` (default 60 seconds) bounds the
|
||||
gate and each stop.
|
||||
|
||||
A copy marked for the private tester receives `--tester-socket` during rehearsal;
|
||||
a legacy copy receives no tester flag. The socket is under the rehearsal's
|
||||
scratch dataRoot, at `data/console/tester.sock`. That path is longer than the live
|
||||
one. A long dataRoot can pass activation's pathname preflight and still make the
|
||||
rehearsal Console refuse its socket path; the rehearsal then fails closed.
|
||||
|
||||
Before it makes anything, it checks the pointer, the copy (present,
|
||||
reachable from refactor, a readable schema, a bus host with `--no-launch`),
|
||||
the port and the backup's `SHA256SUMS`. Then it makes
|
||||
@@ -1271,46 +1263,36 @@ not claim an assistant answer; an uncertain receipt is never retried. Read the
|
||||
current list/history before trying again. Activation still needs Mos's separate
|
||||
window; changing these files does not authorize a live Console action.
|
||||
|
||||
### Console tester listener (`serve --tester-socket`, row 196)
|
||||
### Console tester listener (`serve --tester-port N`, row 176)
|
||||
|
||||
`node packages/webui/src/cli.mjs serve --tester-socket` adds private HTTP at
|
||||
`<dataRoot>/console/tester.sock` (0600) under console/ (0700). The path must fit
|
||||
107 bytes. Unsafe ownership, modes, symlinks and pre-existing entries refuse.
|
||||
The main Console remains on its configured TCP port. New copies refuse --tester-port.
|
||||
`node packages/webui/src/cli.mjs serve --tester-port N` adds a second listener
|
||||
bound only to `127.0.0.1:N`. N must be an integer in 1024..65535, different
|
||||
from `--port` and never 7332 (the tunnel's forwarded port). It requires the
|
||||
bus configuration. It calls only the tester shim; the main listener keeps its
|
||||
existing human transport and rejects every `x-mosaic-tester` request.
|
||||
The tester listener rejects the main preview auth header and only accepts its
|
||||
own loopback Host/port. Its Settings banner identifies the tester. Its instance,
|
||||
route and name editors use the tester's three writes; settings, document saves,
|
||||
assistant stop, role messages and chat writes stay refused. Writes require the
|
||||
exact `http://127.0.0.1:N` Origin, same-origin Fetch Metadata, JSON and the existing
|
||||
bounded strict bodies. `tester-off` and `tester-required` answer HTTP 403.
|
||||
|
||||
The tester's fixed Host is mosaic-tester.invalid and its Origin is
|
||||
http://mosaic-tester.invalid. No DNS is used. POST also needs same-origin Fetch
|
||||
Metadata and bounded JSON. The endpoint uses only TESTER_CLI. It admits the
|
||||
existing instance, route, name and tester-chat writes, never owner settings,
|
||||
document saves, assistant stop or role messages. bus.tester stays Jason's switch.
|
||||
Authorization, login/session cookies and configured proxy headers refuse.
|
||||
`scripts/webui-service.sh render|install --tester-port N` carries the flag into
|
||||
ExecStart, and status names its URL. Bad tester ports exit 4. Install remains a
|
||||
unit write for the authorized operator, with no start/restart verb.
|
||||
|
||||
```sh
|
||||
node packages/cli/src/tester-http.mjs GET /api/bus/agents
|
||||
printf '%s' '{"name":"fixture"}' | node packages/cli/src/tester-http.mjs POST /api/chat/projects
|
||||
```
|
||||
|
||||
The helper loads the selected instance config and reports HTTP status/text/body
|
||||
as JSON, exiting 2 for refusal. It never retries writes. Direct browser access
|
||||
is removed with Mos's acceptance (mos-1015). A future authenticated browser relay
|
||||
behind SSO is a separate row. No TCP compatibility bridge is provided.
|
||||
|
||||
`webui-service.sh render|install --tester-socket` checks target support and carries
|
||||
the flag into ExecStart. `stack-release.sh activate ID BUSINESS --tester-socket`
|
||||
explicitly replaces an inherited --tester-port pair in both unit and pointer.
|
||||
Without explicit conversion a new target refuses tester-transport-migration before
|
||||
stopping anything. Unsupported targets refuse tester-socket-target. Rollback drops
|
||||
unsupported socket enablement, visibly in plan/steps, without enabling TCP. Legacy
|
||||
flags remain supported by the release tool for legacy target copies only. Failed
|
||||
activation recovery can restore the previous TCP unit and its old limits.
|
||||
|
||||
Activation of a new copy preflights the pinned root-owned system Python ELF,
|
||||
records its resolved path/version/identity/hash and checks the bus's fresh startup
|
||||
receipt. Restarts revalidate and append actual interpreter identity to
|
||||
`<dataRoot>/bus/peercred-starts.jsonl`, without comparing an old activation hash.
|
||||
After an OS interpreter update, the next authorized re-pin uses a different reviewed
|
||||
copy and refreshes activation evidence. Do not bypass already-active or use a PATH shim.
|
||||
All live operations keep their existing window authority.
|
||||
`stack-release.sh activate ID BUSINESS --tester-port N` replaces or adds this
|
||||
Console flag in both the installed unit and the pointer. It checks the target
|
||||
copy's own Console before stopping anything; an explicit unsupported request
|
||||
refuses `tester-port-target`. A port outside 1024 to 65535, 7332 or the
|
||||
Console's `--port` is a usage error (exit 4). Under `--plan` both are listed
|
||||
with the plan's other refusals instead, the bad port as `tester-port-invalid`,
|
||||
and the plan exits 3. Without an explicit flag, activate and rollback
|
||||
keep it between supporting copies, or drop it when the target predates support.
|
||||
The plan prints the final Console flags and any dropped `--tester-port N`;
|
||||
the steps log records a drop too. `pm-on` keeps the pointer's Console flags.
|
||||
These operations retain their existing Mos/Jason window authority. Nothing in
|
||||
this row forwards the tester port through the tunnel or changes live units.
|
||||
|
||||
Console proxy proof (row 178, #1676): `serve`, `webui-service.sh render` and
|
||||
`install` accept `--proof-header NAME --proof-file PATH` together, under preview
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user