Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7c38a6aa5 | ||
|
|
ef0939e351 | ||
|
|
57bcdebf97 | ||
|
|
1c7b32bd9d | ||
|
|
9563fbc8b8 | ||
|
|
1da28a7bd1 | ||
|
|
f1e8cda074 | ||
|
|
e9fc105ac9 | ||
|
|
a5330386c4 | ||
|
|
1e47b09198 | ||
|
|
f4e2cb804f | ||
|
|
56701f715d | ||
|
|
b285e581ea | ||
|
|
efe3e46973 |
No files matched your search
+11
-6
@@ -5583,9 +5583,14 @@ claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r
|
||||
|
||||
2026-10-24 — Magica row329 R2 (#1827): B1 ASCII-only management key fix verified with complete-tree refusals and positive auth control; package66/66,30bus readers261/261,49CLI readers726/726,config55/55, no required skip/failure. N1 corrects R1 bus total to1019; N3 stale-lock guidance and N4 34-code inventory corrected. Two over-selected file runs are recorded separately, with no F7 inference; cause unknown/Vikunja625. Old502 test/helper files byte-identical, slot returned to Sage. Evidence agents/magica/work/queue-329/BUILD.md.
|
||||
2026-10-24T23:37:46Z | Sage | Row 329 (#1827, P1 pinned model proxy, Magica) LANDED 61ebf2c34, pushed 23:31:27Z 10-24. Before: refactor at 669cdf42c. After: Magica's 4 commits (94cde633e, c65fb34ee, d1f6f2b19, 61ebf2c34) cherry-picked onto 669cdf42c, diff vs the gated tree limited to drift paths, range-diff in scratch. Gate: one unchanged full landing gate in /mnt/storage/scratch/sage-r329l/wt (gate.sh 8b4978887 c8a9bcf94), started 23:08:12Z at load 14.35, GATE GREEN 23:29:14Z at load 8.67, no rerun, no test or timeout edit (mos-1634). Host note: two Codex workers cleaned T3 worktrees from about 23:14Z (mos-1639, Vikunja 632). Approvals: Dewey r2 c31643 rev 4047, Boyd r2 c31642 rev 4048. #1827 comment 31650, closed. Vikunja 237 comment 1109 (stays open for P2-P7); C4 P10 red filed as Vikunja 631. Queue: note rev 4063, done rev 4064, committed b24d917ec. DEFERRED: N2 and R2-N1 bound to row 331, N1 bound to P7. Overlap: row 284 (packages/bus/src/broker.mjs) and row 157 (scripts/mosaic-config.mjs) rebase onto 61ebf2c34 before their gates.
|
||||
2026-10-25T00:15:48Z | Sage | Row 284 (#1789, C2-05c library.get scope, Della) LANDED ce0b6ed41, pushed 00:09:52Z 10-25. Before: refactor at 9e2689dff (row 329 landing docs). After: fast-forward to Della's 7 rebased commits 78b932feb..ce0b6ed41; 8 paths, manifest-r4 de505cfd matches the landed tree. Gate: one unchanged full landing gate in /mnt/storage/scratch/sage-r284l/wt (the 329 gate.sh with D and the compose project renamed), started 23:51:19Z at load 1.62, GATE GREEN 00:09:04Z at load 5.20, no rerun, no test or timeout edit. Counts: bus 1020/0, business 283/0, cli 999 pass 1 allowed skip (FED R7), harness 177/0, library 156/0, seat 218/0, webui 458/0, every scripts/test-*.sh rc 0; queue 34 and task 87/93 skips are the standing ones. Della's whole-file runs on ce0b6ed41: library-lookups 12/0, library-tools 5/0, query 34/0. Approval: Webby round 2 delta c31654 rev 4070 (round 1 rev 4062). Overlap sweep: rows 13, 157, 309, gyro/row310 and fethry/row332-p1 clean. #1789 comment 31655, closed. No Vikunja task for the row. Queue: note rev 4071, done rev 4072, committed 7c8dc2033. DEFERRED: Webby N1 (whole-tree listing per get) bound to the next library read-path row; N2 needs nothing; N3 is this gate.
|
||||
2026-10-25T00:18:35Z | Sage | Follow-up tasks for mos-1647 item 3 (Q109): Vikunja 633 (P7 cutover, CLIProxyAPI 8.0.42 startup Grok-npm and antigravity version refreshes, from row 332 isolated runs) and 634 (row 284 Webby N1, library get lists the whole tree). DEFERRED gains the 633 entry and the 634 number for row 284 N1. Filing script and receipt in agents/sage/work/vikunja-setup/.
|
||||
2026-10-24T22:15:07Z | Herb | row 214 #1715 C2-11a focused evidence | Before: wikilinks are ordinary editor text; raw/sig retention keeps no-edit bytes, but the model has no inert node. After: inert inline wikilink atom preserves spelling through neighbouring edits; invalid attrs share HTML/entity escaping. On herb/row214-r2 base487500a16, grant sage-4286 lane B: baseline10/10 roundTrips equal (outcome A); baseline structural0/1 expected red; four whole editor files40/0, both mutants killed0/1 and restored1/0, whole webui69 files455/0 in174.189s with MOSAIC_REQUIRE_EDITOR_BUILD=1, nice19, no skips/cancellations. A mistaken preliminary7-file subset28/0 is logged and excluded from gate evidence. CSS byte-identical, final process sweep0, scratch TMPDIR removed. Filbert candidate review and every scripts/test-*.sh gate remain pending; no click, target resolution or library save change.
|
||||
2026-10-25T04:36:47Z | Sage | Row 214 (#1715, C2-11a editor wikilink node, Herb) LANDED 3a8e4abad, pushed 04:27Z 10-25. Before: refactor at 78b69e1e6. After: Herb's six commits cherry-picked onto 78b69e1e6 and fast-forwarded. Gate GREEN 04:10:34Z: 18 package suites rc 0 (webui 471/471, cli 999 plus the allowed FED R7 skip), every scripts/test-*.sh rc 0, queue package via test-queue.sh 156. Design skips: queue 34 (not the canonical root), task 87/93 (row 244). Filbert APPROVE c31679 rev 4093. Range-diff equal except commit 5's BUILD-LOG context; 40/41 paths same blob, BUILD-LOG additions only. #1715 closed c31680. Queue note 4094, done 4095, committed ce8bb4d8b.
|
||||
2026-10-25T04:36:47Z | Sage | Row 193 (#1691, threads user roles design, Morgana) LANDED 35f34ad27, doc-only: five design commits cherry-picked onto ce8bb4d8b, adding only agents/morgana/work/queue-193/DESIGN.md (verify-commit ok, 1 path). Duckworth APPROVE c31676 rev 4088 (posted and recorded by Sage; Duckworth has no Gitea credential). No test reads queue-193. Build rows from the design: 204/#1702, 205/#1703 (landed), 275/#1780, 206/#1704, 207/#1705, 208/#1706.
|
||||
2026-10-25T04:58:30Z | Sage | Row 255 (#1760, Vikunja 458, bundled Pocket ID design for Q203, Launchpad) LANDED de3e23dde, doc-only: Launchpad's three design commits e29d8ec90, 9f60021a0 and c8f2bc723 cherry-picked onto 775bbe236 (range-diff equal), adding only agents/launchpad/work/queue-255/DESIGN.md. No test reads queue-255. Webby APPROVE round 1 c31689 rev 4103 (posted by Sage; Webby has no Gitea token). Mos rulings in mos-1666: M1 approved with conditions (rollback removes components before the pointer goes back and the STATE check confirms the key is absent; the loader stays strict inside the key; four test-config.sh cases), R1 chosen, M2 dropped. Sage gate check against Q203, O6, REQ-WEB-2 and REQ-INST-1: consistent. One PRD text gap goes to Mos: REQ-INST-2 says the stack writes the providers entry, and R1 prints it for the user to paste. Webby N1 and N2 bind P4; N3-N8 carry into the P1-P6 build rows, all post-v1.
|
||||
## 2026-10-24 — row332 P3 proxy harness configuration: investigation/test placement
|
||||
|
||||
Fethry at c8a9bcf94, per Sage sage-4292 and mos-1616 pi-route amendment. Before: every managed session receives instance-wide provider credentials; harnesses have no transient per-session proxy context; pi preflight checks only its binary. Intended after: proxy-mode isolation, Claude proxy env, pi private run-local route config using environment references only, credential preflight, and business proxy account settings. Design/test plan: agents/fethry/work/queue-332/BUILD.md. Initial tests placed before production changes. No tests run: Sage CLEAR is required and has not arrived. No success/acceptance claim, live change, or dependency landing. Existing proxy issue number requested from Sage; not yet received.
|
||||
|
||||
## 2026-10-24 — row332 crash stop, documentation-only checkpoint
|
||||
|
||||
Fethry stopped under Mos mos-1630/Jason's T3 crash instruction. No production implementation, tests, probes, mutants or acceptance runs occurred; Sage CLEAR never arrived. Explicit route metadata per sage-4293 is recorded in agents/fethry/work/queue-332/BUILD.md; full state and resumption boundaries are in HANDOFF.md there. Safe crash checkpoint commits documentation/historical plain-text import manifest only; four unrun tests and the import-audit script remain uncommitted. No long jobs restarted, protected branch changes, merges, live changes or further thread messages.
|
||||
|
||||
2026-10-24 — Fethry row332 P3 UNRUN implementation checkpoint: optional proxy route per sage-4325 (default Anthropic), transient preflight/bundle/spawn context and serialization split, pi private model file/provider credential requirement. Existing initial RED evidence precedes source changes; only specifically authorized old fixtures updated. GPT wire API value PENDING until separate offline CLEAR/evidence; P2 seam remains injected context, no real proxy/auth access. Not GREEN, not accepted or landed. Details agents/fethry/work/queue-332/BUILD.md.
|
||||
|
||||
2026-10-24 — Fethry row332 P3 checkpoint ef0939e35: required explicit route restored per sage-4293/4328; openai-responses chosen by Sage sage-4331 as reasoning-based tie-break, not evidence-decided (both offline shapes passed). Rehashed pinned8.0.42 single active-tool isolated GLM turn confirms thinking/tool_stream survive to stand-in;bundle7/7,proxy-harness5/5,no skips. Real Codex auth proof remains row209 phaseA step7. P2 landing/rebase,mutants,reviews and full gate still pending; no landing claim. Plain evidence/limitations in agents/fethry/work/queue-332/BUILD.md.
|
||||
@@ -1,934 +0,0 @@
|
||||
# Row284 C2-05c — supporting scope and served-tree blob (#1789)
|
||||
|
||||
Owner Della; reviewer Dewey; gate Sage. Build start sage-3658/3660 (10-23).
|
||||
Branch della/row284. Original prerequisite base Honker28346bad7ea3;
|
||||
merge fc05bcbc3 carries22423816cf28 and2164f3fbc25a intact. Only conflict was
|
||||
CLI thread-launch's added footer tests: retained both full test bodies and
|
||||
assertions. No prerequisite code copied. Every prerequisite needs its own
|
||||
review/mutants/landing under mos1351; rebase after283 lands.
|
||||
|
||||
## Execution status
|
||||
|
||||
UNTESTED. No Node, node--check, test or mutant run before Sage CLEAR. First
|
||||
own commit is the authorized old-test migration; the implementation follows.
|
||||
Sage authorizes an immediate untested push. No queue write or shared-log edit.
|
||||
224 stays first;284 is critical to Bubba288. T4 for224 is not a CLEAR yet.
|
||||
|
||||
## Binding readings
|
||||
|
||||
Brief C2-05c at94c33a43c:1737-1789, Q226, sage2918 and mos1330 item3.
|
||||
get defaults canon; explicit playground/supporting opt-in; mismatch null.
|
||||
Sort full outgoing/incoming lists supporting, playground, canon before paging,
|
||||
keep cross-scope links and universe filter. Manuscript stays canon/playground.
|
||||
No all/array scope, write tool, guard, mapping or creative-name-count change.
|
||||
|
||||
## mos-1330 old-test migration (separate commit)
|
||||
|
||||
All paths below are packages/library/tests/query.test.mjs. Baseline file at
|
||||
fc05bcbc3 matches216's file. Source assertions retained; negative calls receive
|
||||
explicit scope too, so universe isolation cannot pass on default-scope denial.
|
||||
|
||||
Call/assertion 348 -> 348:
|
||||
|
||||
```js
|
||||
// OLD
|
||||
const rin = await get(s, { universe: 'idea', path: 'Drafts/New World/Characters/Rin.md' });
|
||||
// NEW
|
||||
const rin = await get(s, { universe: 'idea', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' });
|
||||
```
|
||||
|
||||
Call/assertion 350 -> 350:
|
||||
|
||||
```js
|
||||
// OLD
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Drafts/New World/Characters/Rin.md' }), null);
|
||||
// NEW
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' }), null);
|
||||
```
|
||||
|
||||
Call/assertion 366 -> 366:
|
||||
|
||||
```js
|
||||
// OLD
|
||||
assert.equal(await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path }), null);
|
||||
// NEW
|
||||
assert.equal(await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path, scope: 'playground' }), null);
|
||||
```
|
||||
|
||||
Call/assertion 367 -> 367:
|
||||
|
||||
```js
|
||||
// OLD
|
||||
const own = await get(src(ref), { universe: 'harbor', path });
|
||||
// NEW
|
||||
const own = await get(src(ref), { universe: 'harbor', path, scope: 'playground' });
|
||||
```
|
||||
|
||||
Assertion 349 retained, OLD == NEW:
|
||||
|
||||
```js
|
||||
assert.equal(rin.scope, 'playground');
|
||||
```
|
||||
|
||||
Assertion 368 retained, OLD == NEW:
|
||||
|
||||
```js
|
||||
assert.equal(own.scope, 'playground');
|
||||
```
|
||||
|
||||
The null assertions at350 and366 are the complete OLD/NEW expressions above:
|
||||
expectation remains null. Added one separate no-scope playground-get -> null
|
||||
behavior test. It is unrun and expected to expose old get behavior until the
|
||||
new scope implementation lands. This migration is authorized by mos1330 under
|
||||
mos1272; no check removed or weakened. Dewey checks this list in manifest review.
|
||||
|
||||
## 283 surface and blob choice
|
||||
|
||||
Inspected actual46bad7ea3: optional editor.user is present. reader's parsed
|
||||
file records and index entries still discard tree oid. In owned query.mjs use
|
||||
the existing bounded listTree(repo, servedCommit) to obtain exact path oid,
|
||||
not HEAD and not a user-supplied revision expression. No reader/index edit.
|
||||
Tradeoff: one additional bounded tree listing per get; latency unmeasured.
|
||||
Recheck after rebasing to283's actual landing.
|
||||
|
||||
## Intended owned paths
|
||||
|
||||
query.mjs; broker.mjs lookup branch; tools.mjs lookup schemas/descriptions;
|
||||
library query.test.mjs/query-fixture.mjs; bus library-lookups.test.mjs;
|
||||
harness library-tools.test.mjs; this BUILD.md. Other files are prerequisites.
|
||||
|
||||
## Gate
|
||||
|
||||
Dewey manifest approval, whole library/bus/harness suites and every
|
||||
scripts/test-*.sh on Sage gate. Before review grep all package tests for enum
|
||||
pins and canon/playground pairs. Keep shared logs out; send receipts to Sage.
|
||||
No test or mutant evidence claimed. Manifest/digest follows complete code.
|
||||
|
||||
## Implementation head (UNTESTED, sage-3658)
|
||||
|
||||
- query scope accepts supporting for find/search/get. get defaults canon,
|
||||
mismatch null. Manuscript passes a separate two-value scope allowlist.
|
||||
- get returns blob from listTree(source.repo,index.commit) after scope/universe
|
||||
filtering. The same index.commit supplies the text; source HEAD is irrelevant.
|
||||
- Full outgoing and incoming link lists are stably sorted by supporting,
|
||||
playground,canon before combining/paging. All visible cross-scope links stay;
|
||||
universe/hybrid visibility still applies. Scope metadata isn't added to links.
|
||||
- Broker only adds optional scope to library.get's strict fields. No new verbs.
|
||||
- Typed scope expands find/search/get only; manuscript retains its own two-value
|
||||
enum. Names/M3 counts remain the row224 six/eight, no write tools added.
|
||||
- New tests: book/universe/draft supporting find/search/get; defaults/mismatch;
|
||||
absent supporting prefix; source HEAD advances but each scope's blob equals
|
||||
served:path; 300 outgoing plus300 incoming links ordered across bounded pages,
|
||||
retaining cross-scope links and dropping other-universe links; hybrid source
|
||||
stays canon-only; no all/array scope; manuscript rejects supporting; broker
|
||||
scope/blob forwarding; typed enums and unchanged names. All unrun.
|
||||
|
||||
## Additional old assertion pin (brief Gate)
|
||||
|
||||
harness/tests/library-tools.test.mjs:49 at23816cf28 (line49, unchanged in this head):
|
||||
OLD find scope enum ['canon','playground']; NEW ['canon','playground','supporting'].
|
||||
This is the exact scope-enum pin the brief directs updating. Existing six/eight
|
||||
name snapshots and TYPES equality assertion are unchanged. The new manuscript
|
||||
pin intentionally remains ['canon','playground']. No other two-scope test pin
|
||||
was found by rg over packages/*/tests at this build's prerequisite merge.
|
||||
|
||||
## Proposed mutation evidence (reviewer confirms final set)
|
||||
|
||||
All unrun. Require assertion failures with whole-file runs and pristine restore:
|
||||
M1 remove supporting from query SCOPES -> supporting lookup cases.
|
||||
M2 drop get's requested-scope comparison -> default/mismatch null cases.
|
||||
M3 use source HEAD for blob lookup -> served-tree/advanced-HEAD equality case.
|
||||
M4 remove link rank sort -> multi-page outgoing/incoming expected order.
|
||||
M5 restrict links to requested scope -> cross-scope link counts/order case.
|
||||
M6 drop sees() from visible/link filtering -> second-universe/hybrid cases.
|
||||
M7 allow supporting in manuscript validator -> manuscript refusal case.
|
||||
M8 omit get scope from broker fields -> real broker supporting get case.
|
||||
M9 widen typed manuscript enum -> typed-scope separation case.
|
||||
|
||||
## Inspection and pending gate
|
||||
|
||||
No production imports change in broker/tools, so no new sandbox closure file
|
||||
or mount. query.mjs is host library code and adds existing reader.listTree;
|
||||
no new package/export/copy-path file. rg found the one old find scope pin plus
|
||||
the intentional new manuscript two-scope pin. Whole library/bus/harness and
|
||||
shell gates remain required. CLI integration/merge context is prerequisite224/
|
||||
219, not this row's source delta; any changed gate expectation goes to Sage.
|
||||
Node checks, tests, mutants and elapsed-time evidence remain absent pending
|
||||
CLEAR. The first test-migration commit and this implementation are distinct.
|
||||
|
||||
Sage sweep receipt: Della row284 builds on28346bad7ea3 plus intact224 merge;
|
||||
mos1330 old-test migration separate, supporting scope/blob implementation and
|
||||
fixtures authored, completely UNTESTED. No shared-log/queue write or live action.
|
||||
|
||||
## Current assertion anchors after implementation imports
|
||||
|
||||
The separate migration commit0ed4fbab9 retains its complete OLD/NEW text
|
||||
above. Adding only the fs/path imports in the implementation shifts anchors:
|
||||
|
||||
query.test.mjs:130: `const blendCh2 = await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path: 'Book One/Chapters/Chapter 02.md' });`
|
||||
query.test.mjs:350: `const rin = await get(s, { universe: 'idea', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' });`
|
||||
query.test.mjs:351: `assert.equal(rin.scope, 'playground');`
|
||||
query.test.mjs:352: `assert.equal(await get(s, { universe: 'harbor', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' }), null);`
|
||||
query.test.mjs:368: `assert.equal(await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path, scope: 'playground' }), null);`
|
||||
query.test.mjs:369: `const own = await get(src(ref), { universe: 'harbor', path, scope: 'playground' });`
|
||||
query.test.mjs:370: `assert.equal(own.scope, 'playground');`
|
||||
|
||||
No result/null assertion changed; scope arguments carry the explicit opt-in.
|
||||
|
||||
## Dewey dewey-0941 static review — round2
|
||||
|
||||
Static scope fc05bcbc3..47db04eba CLEAN; not a final verdict or test evidence.
|
||||
M1-M9 accepted as the final set. Optional M10 not added to this gate.
|
||||
N2 taken: keep the existing canon-path supporting-scope mismatch assertion,
|
||||
and ADD get(Book One/Support/Notes/Helper.md,scope:supporting) -> null under
|
||||
the default mapping with no supporting prefix. The supporting-positive test
|
||||
already returns this same path under withSupporting, so the added probe
|
||||
pins the missing-prefix case directly. No assertion removed or weakened;
|
||||
mos1330's separate migration commit and its retained assertions unchanged.
|
||||
|
||||
N1 proposed DEFERRED/follow-up for Sage: retain each tree oid in reader/index
|
||||
entries so get can return blob without cat-file/whole ls-tree -r -l per page.
|
||||
Current get's result is pinned correctly, but per-page cost grows with the
|
||||
library. No performance measurement yet. This optimization needs reader/index
|
||||
ownership and separate acceptance/performance evidence; do not silently expand
|
||||
284's manifest or change its served-snapshot contract for it.
|
||||
|
||||
No Node, tests, mutants or syntax checks run in this round; hold still applies.
|
||||
|
||||
## sage-4281 — rebase onto landed 224/283, 2026-10-24
|
||||
|
||||
New worktree /mnt/storage/scratch/della-row284-r2, branch della/row284-r2,
|
||||
base refactor 95d4991d20a4ef291c824d37c886eaeaa9be7062. Cherry-picked only
|
||||
284-owned 0ed4fbab9, 47db04eba, 5d587a552. Range-diff: all three equal, no
|
||||
conflicts. The separate mos-1330 migration remains its own commit. No 216,
|
||||
224 or 283 prerequisite commits copied. Old della/row284 remains unchanged.
|
||||
|
||||
mos-1584 fixture check: new tests add no businessDoc() with a library. The
|
||||
harness role() uses landed 224's gitea reference for bean; the library-enabled
|
||||
CLI chief fixture fix is also upstream. New broker test uses the direct
|
||||
Broker fixture (no businessDoc/bootConfig), not a new validated organization.
|
||||
No new made-up credential values are introduced in this row; existing short
|
||||
fixture references are reused, so no new credential reaches 24 characters.
|
||||
No credential values were inspected or printed. No fixture edit necessary.
|
||||
|
||||
No Node, npm, syntax check, service, test, mutant or install run in this worktree.
|
||||
No canonical node_modules link. Dependency installation remains a separately
|
||||
cleared local npm ci if needed; tests wait for Sage CLEAR. For future runs use
|
||||
shell mktemp -d /mnt/storage/scratch/tmp/XXXXXX and per-child absolute nice 19.
|
||||
Shared logs unchanged; Sage owns landing receipts.
|
||||
|
||||
## Import-derived whole-file run plan (mos-1612)
|
||||
|
||||
Walked relative static import/re-export edges and literal dynamic imports
|
||||
transitively, from each packages/*/tests/**/*.test.mjs to changed query.mjs,
|
||||
broker.mjs, tools.mjs or query-fixture.mjs. This follows source import edges,
|
||||
not textual mentions. Example CLI/thread-launch -> Broker; CLI/helpers ->
|
||||
Broker; webui/serve -> webui/bus -> Broker; harness/bundle -> tools.
|
||||
Evidence generator and per-test import chains are in
|
||||
/mnt/storage/scratch/della-row284-r2-evidence/import-run-list.py and .json.
|
||||
The import-derived set has 260 files; union with the brief's whole library,
|
||||
bus and harness suites adds files that use subprocesses/source reads instead
|
||||
of direct imports. Excluded case1-accept.test.mjs by sage-4281. Any dynamic
|
||||
nonliteral loading or external shell gate is not claimed covered by import
|
||||
tracing; mandatory package suites and Sage's full script gate remain required.
|
||||
|
||||
First focused whole files: library/query.test.mjs; bus/library-lookups.test.mjs;
|
||||
harness/library-tools.test.mjs. Then the full import-derived/mandatory union
|
||||
below, each file whole (duplicates need not repeat without a change). This
|
||||
is a proposed run list for Sage's CLEAR, not authorization to run now.
|
||||
M1-M9 retain Dewey's agreed specification above; no mutant executed.
|
||||
|
||||
Whole-file union:
|
||||
|
||||
```text
|
||||
packages/bus/tests/access-revoke.test.mjs
|
||||
packages/bus/tests/account-migration.test.mjs
|
||||
packages/bus/tests/address.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/citation-availability.test.mjs
|
||||
packages/bus/tests/citation-guard.test.mjs
|
||||
packages/bus/tests/citation-runtime.test.mjs
|
||||
packages/bus/tests/comment-cursors.test.mjs
|
||||
packages/bus/tests/comment-migration.test.mjs
|
||||
packages/bus/tests/console-decide.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/fire-revokes-grants.test.mjs
|
||||
packages/bus/tests/gitea-grant-docker.test.mjs
|
||||
packages/bus/tests/gitea-grant.test.mjs
|
||||
packages/bus/tests/gitea-migration.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/grant-scope-runtime.test.mjs
|
||||
packages/bus/tests/grant-scope.test.mjs
|
||||
packages/bus/tests/hard-waits.test.mjs
|
||||
packages/bus/tests/host-run.test.mjs
|
||||
packages/bus/tests/host-tools.test.mjs
|
||||
packages/bus/tests/human.test.mjs
|
||||
packages/bus/tests/instances-verb.test.mjs
|
||||
packages/bus/tests/interpreter.test.mjs
|
||||
packages/bus/tests/land.test.mjs
|
||||
packages/bus/tests/launch-notice.test.mjs
|
||||
packages/bus/tests/launcher-released.test.mjs
|
||||
packages/bus/tests/library-credential.test.mjs
|
||||
packages/bus/tests/library-lookups.test.mjs
|
||||
packages/bus/tests/library-sync.test.mjs
|
||||
packages/bus/tests/library.test.mjs
|
||||
packages/bus/tests/lifecycle-revoke.test.mjs
|
||||
packages/bus/tests/lifecycle-verbs.test.mjs
|
||||
packages/bus/tests/limit-checks.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/message-filter.test.mjs
|
||||
packages/bus/tests/messages.test.mjs
|
||||
packages/bus/tests/messaging.test.mjs
|
||||
packages/bus/tests/name-migration.test.mjs
|
||||
packages/bus/tests/names.test.mjs
|
||||
packages/bus/tests/peer-transport.test.mjs
|
||||
packages/bus/tests/peercred.test.mjs
|
||||
packages/bus/tests/plugins-verb.test.mjs
|
||||
packages/bus/tests/principal.test.mjs
|
||||
packages/bus/tests/process.test.mjs
|
||||
packages/bus/tests/processing-runtime.test.mjs
|
||||
packages/bus/tests/processing-timeout.test.mjs
|
||||
packages/bus/tests/processing-web.test.mjs
|
||||
packages/bus/tests/processing.test.mjs
|
||||
packages/bus/tests/project-await.test.mjs
|
||||
packages/bus/tests/project-files.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/bus/tests/publish.test.mjs
|
||||
packages/bus/tests/reload.test.mjs
|
||||
packages/bus/tests/replies.test.mjs
|
||||
packages/bus/tests/requirements.test.mjs
|
||||
packages/bus/tests/review.test.mjs
|
||||
packages/bus/tests/revoke-window.test.mjs
|
||||
packages/bus/tests/room-check.test.mjs
|
||||
packages/bus/tests/rooms.test.mjs
|
||||
packages/bus/tests/routes-verb.test.mjs
|
||||
packages/bus/tests/schema.test.mjs
|
||||
packages/bus/tests/session-clear.test.mjs
|
||||
packages/bus/tests/session-compactions.test.mjs
|
||||
packages/bus/tests/sessions.test.mjs
|
||||
packages/bus/tests/single-use.test.mjs
|
||||
packages/bus/tests/spec-migration.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/store.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-claims.test.mjs
|
||||
packages/bus/tests/thread-migration.test.mjs
|
||||
packages/bus/tests/thread-shares.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-migration.test.mjs
|
||||
packages/bus/tests/usage-runtime.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/bus/tests/user-principal.test.mjs
|
||||
packages/bus/tests/viewer.test.mjs
|
||||
packages/bus/tests/web.test.mjs
|
||||
packages/bus/tests/workflow-roles.test.mjs
|
||||
packages/business/tests/case1-business-file.test.mjs
|
||||
packages/business/tests/launch-settings.test.mjs
|
||||
packages/cli/tests/access-boot.test.mjs
|
||||
packages/cli/tests/access.test.mjs
|
||||
packages/cli/tests/app.test.mjs
|
||||
packages/cli/tests/boot-status.test.mjs
|
||||
packages/cli/tests/case1-hostcheck.test.mjs
|
||||
packages/cli/tests/case2-install.test.mjs
|
||||
packages/cli/tests/case2-persona-import.test.mjs
|
||||
packages/cli/tests/case2-unit.test.mjs
|
||||
packages/cli/tests/channel-cli.test.mjs
|
||||
packages/cli/tests/channel-recovery.test.mjs
|
||||
packages/cli/tests/cli.test.mjs
|
||||
packages/cli/tests/compactions-launch.test.mjs
|
||||
packages/cli/tests/config.test.mjs
|
||||
packages/cli/tests/credentials.test.mjs
|
||||
packages/cli/tests/federation-acceptance.test.mjs
|
||||
packages/cli/tests/follow.test.mjs
|
||||
packages/cli/tests/git-socket.test.mjs
|
||||
packages/cli/tests/grants-scope.test.mjs
|
||||
packages/cli/tests/grants.test.mjs
|
||||
packages/cli/tests/host.test.mjs
|
||||
packages/cli/tests/hosts.test.mjs
|
||||
packages/cli/tests/idle-stop-race.test.mjs
|
||||
packages/cli/tests/instances.test.mjs
|
||||
packages/cli/tests/launch-account.test.mjs
|
||||
packages/cli/tests/launch-limit-checks.test.mjs
|
||||
packages/cli/tests/launch-limits.test.mjs
|
||||
packages/cli/tests/launch-routes.test.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/lifecycle.test.mjs
|
||||
packages/cli/tests/limits-tokens.test.mjs
|
||||
packages/cli/tests/limits.test.mjs
|
||||
packages/cli/tests/mark-read.test.mjs
|
||||
packages/cli/tests/names.test.mjs
|
||||
packages/cli/tests/notifier.test.mjs
|
||||
packages/cli/tests/optional-tracker.test.mjs
|
||||
packages/cli/tests/other-tree.test.mjs
|
||||
packages/cli/tests/processing-cli.test.mjs
|
||||
packages/cli/tests/project-name-repo.test.mjs
|
||||
packages/cli/tests/project.test.mjs
|
||||
packages/cli/tests/publish-socket.test.mjs
|
||||
packages/cli/tests/reply-limits.test.mjs
|
||||
packages/cli/tests/revoke-window.test.mjs
|
||||
packages/cli/tests/session-clear.test.mjs
|
||||
packages/cli/tests/session-cli.test.mjs
|
||||
packages/cli/tests/session-launch.test.mjs
|
||||
packages/cli/tests/stack-copy.test.mjs
|
||||
packages/cli/tests/stack-instances.test.mjs
|
||||
packages/cli/tests/tester-http.test.mjs
|
||||
packages/cli/tests/tester-reads.test.mjs
|
||||
packages/cli/tests/tester-threads.test.mjs
|
||||
packages/cli/tests/tester.test.mjs
|
||||
packages/cli/tests/thread-cli.test.mjs
|
||||
packages/cli/tests/thread-launch.test.mjs
|
||||
packages/cli/tests/thread-revoke.test.mjs
|
||||
packages/cli/tests/trackers-boot.test.mjs
|
||||
packages/cli/tests/transport.test.mjs
|
||||
packages/cli/tests/usage.test.mjs
|
||||
packages/cli/tests/verbs.test.mjs
|
||||
packages/harness/tests/bundle.test.mjs
|
||||
packages/harness/tests/citation-runner.test.mjs
|
||||
packages/harness/tests/claude-gate.test.mjs
|
||||
packages/harness/tests/claude-session.test.mjs
|
||||
packages/harness/tests/creative.test.mjs
|
||||
packages/harness/tests/gate.test.mjs
|
||||
packages/harness/tests/git-tools.test.mjs
|
||||
packages/harness/tests/library-tools.test.mjs
|
||||
packages/harness/tests/mcp-server.test.mjs
|
||||
packages/harness/tests/pi-session.test.mjs
|
||||
packages/harness/tests/raise-domain.test.mjs
|
||||
packages/harness/tests/runner.test.mjs
|
||||
packages/harness/tests/skills.test.mjs
|
||||
packages/harness/tests/spec-tools.test.mjs
|
||||
packages/harness/tests/tools.test.mjs
|
||||
packages/library/tests/guard.test.mjs
|
||||
packages/library/tests/index-build.test.mjs
|
||||
packages/library/tests/links.test.mjs
|
||||
packages/library/tests/mapping.test.mjs
|
||||
packages/library/tests/mirror.test.mjs
|
||||
packages/library/tests/query.test.mjs
|
||||
packages/library/tests/reader.test.mjs
|
||||
packages/library/tests/render.test.mjs
|
||||
packages/library/tests/scope.test.mjs
|
||||
packages/library/tests/supporting.test.mjs
|
||||
packages/library/tests/survey.test.mjs
|
||||
packages/library/tests/sync.test.mjs
|
||||
packages/processing-control/tests/task.test.mjs
|
||||
packages/seat/tests/sandbox.test.mjs
|
||||
packages/seat/tests/session.test.mjs
|
||||
packages/tasks/tests/adapter.test.mjs
|
||||
packages/tasks/tests/comment-restart.test.mjs
|
||||
packages/tasks/tests/fields.test.mjs
|
||||
packages/tasks/tests/processing.test.mjs
|
||||
packages/tasks/tests/shapes.test.mjs
|
||||
packages/tasks/tests/startup.test.mjs
|
||||
packages/tasks/tests/sync.test.mjs
|
||||
packages/tasks/tests/tree.test.mjs
|
||||
packages/tasks/tests/verbs.test.mjs
|
||||
packages/webui/tests/agents-browser.test.mjs
|
||||
packages/webui/tests/agents.test.mjs
|
||||
packages/webui/tests/assistant.test.mjs
|
||||
packages/webui/tests/board-held.test.mjs
|
||||
packages/webui/tests/browser-edge.test.mjs
|
||||
packages/webui/tests/browser.test.mjs
|
||||
packages/webui/tests/bus-browser.test.mjs
|
||||
packages/webui/tests/bus.test.mjs
|
||||
packages/webui/tests/channel-chat.test.mjs
|
||||
packages/webui/tests/chat-browser.test.mjs
|
||||
packages/webui/tests/chat-instances.test.mjs
|
||||
packages/webui/tests/chat-replies-browser.test.mjs
|
||||
packages/webui/tests/chat-sessions-access.test.mjs
|
||||
packages/webui/tests/chat.test.mjs
|
||||
packages/webui/tests/conversation.test.mjs
|
||||
packages/webui/tests/decide-browser.test.mjs
|
||||
packages/webui/tests/decide-sso.test.mjs
|
||||
packages/webui/tests/decision-http.test.mjs
|
||||
packages/webui/tests/discord.test.mjs
|
||||
packages/webui/tests/docs-browser.test.mjs
|
||||
packages/webui/tests/editor-browser.test.mjs
|
||||
packages/webui/tests/editor.test.mjs
|
||||
packages/webui/tests/granted-user.test.mjs
|
||||
packages/webui/tests/history-return-flow.test.mjs
|
||||
packages/webui/tests/instances-browser.test.mjs
|
||||
packages/webui/tests/instances.test.mjs
|
||||
packages/webui/tests/library-cli.test.mjs
|
||||
packages/webui/tests/library-routes.test.mjs
|
||||
packages/webui/tests/library-status.test.mjs
|
||||
packages/webui/tests/limits-browser.test.mjs
|
||||
packages/webui/tests/limits-route.test.mjs
|
||||
packages/webui/tests/messages.test.mjs
|
||||
packages/webui/tests/pinned-copy.test.mjs
|
||||
packages/webui/tests/preview.test.mjs
|
||||
packages/webui/tests/processing-browser.test.mjs
|
||||
packages/webui/tests/processing.test.mjs
|
||||
packages/webui/tests/project-file.test.mjs
|
||||
packages/webui/tests/project-name-repo.test.mjs
|
||||
packages/webui/tests/proof-cli.test.mjs
|
||||
packages/webui/tests/proof.test.mjs
|
||||
packages/webui/tests/reads.test.mjs
|
||||
packages/webui/tests/relaunch.test.mjs
|
||||
packages/webui/tests/return-flow.test.mjs
|
||||
packages/webui/tests/room-browser.test.mjs
|
||||
packages/webui/tests/room-http.test.mjs
|
||||
packages/webui/tests/routes-browser.test.mjs
|
||||
packages/webui/tests/routes.test.mjs
|
||||
packages/webui/tests/send-browser.test.mjs
|
||||
packages/webui/tests/send.test.mjs
|
||||
packages/webui/tests/serve.test.mjs
|
||||
packages/webui/tests/settings-form.test.mjs
|
||||
packages/webui/tests/settings-write.test.mjs
|
||||
packages/webui/tests/shell.test.mjs
|
||||
packages/webui/tests/sso-browser.test.mjs
|
||||
packages/webui/tests/sso.test.mjs
|
||||
packages/webui/tests/tester-browser.test.mjs
|
||||
packages/webui/tests/tester-cli.test.mjs
|
||||
packages/webui/tests/tester-listener.test.mjs
|
||||
packages/webui/tests/tester-socket.test.mjs
|
||||
packages/webui/tests/thread-claims-browser.test.mjs
|
||||
packages/webui/tests/thread-claims.test.mjs
|
||||
packages/webui/tests/thread-sharing.test.mjs
|
||||
packages/webui/tests/usage-browser.test.mjs
|
||||
packages/webui/tests/usage.test.mjs
|
||||
packages/webui/tests/user-option-swap.test.mjs
|
||||
packages/webui/tests/views.test.mjs
|
||||
```
|
||||
|
||||
Queue next on 2026-10-24 names row284 but reports the whole brief differs
|
||||
from its queue pin and asks the lead to re-pin. Sage-4281 names 5e8a720b and
|
||||
says the section is unchanged; awaiting lead resolution of the queue pin
|
||||
before the start move. No queue policy refusal is bypassed.
|
||||
|
||||
## sage-4289 lane B — completed verification, 2026-10-24
|
||||
|
||||
Current reviewer is Webby under mos-1614 / sage-4284, replacing Dewey.
|
||||
Dewey's earlier static readings and agreed M1-M9 remain historical evidence.
|
||||
Row284 claimed in-progress rev4038, op della-284-start-1 after lead re-pin.
|
||||
Candidate tested: 2f1a6bd93e5fc602c46ee5f770d19adecde5fc11. No code,
|
||||
fixture or assertion change during verification. Local npm ci used the exact
|
||||
lockfile, ignore-scripts/no-audit/no-fund, rc0,128 packages; no canonical
|
||||
node_modules link. Installer receipt and log are in the evidence directory.
|
||||
|
||||
Run list sent in full to Sage before starting (della-0058); source is the
|
||||
import walk documented above, union mandatory package suites,279 whole files.
|
||||
Three targeted files first, then M1-M9 with byte-exact restore after each,
|
||||
then remaining276 whole files. Already-passed unchanged targeted files are
|
||||
not repeated. Every Node invocation used fresh shell gXXX TMPDIR,29 bytes,
|
||||
absolute nice19 set in the child before exec, timeout -k10 (900-second cap,
|
||||
shortened automatically near23:45Z hardstop). All timeout nice observations
|
||||
were19. Normal run total1067.962s; mutant total19.485s. Completed22:34Z.
|
||||
|
||||
| Package | Whole files | Pass | Fail | Skip |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| bus | 114 | 1012 | 0 | 0 |
|
||||
| business | 2 | 25 | 0 | 0 |
|
||||
| cli | 58 | 610 | 0 | 1 |
|
||||
| harness | 15 | 177 | 0 | 0 |
|
||||
| library | 12 | 156 | 0 | 0 |
|
||||
| processing-control | 1 | 7 | 0 | 0 |
|
||||
| seat | 2 | 23 | 0 | 0 |
|
||||
| tasks | 9 | 95 | 0 | 0 |
|
||||
| webui | 66 | 396 | 0 | 0 |
|
||||
|
||||
Totals:279 whole files,2501 passed,0 failed,1 skipped,0 cancelled.
|
||||
Sole skip: packages/cli/tests/federation-acceptance.test.mjs,
|
||||
FED R7 scratch two-instance acceptance, directs running
|
||||
scripts/test-federation-acceptance.sh. That acceptance was not exercised;
|
||||
Sage's full shell landing gate is separate. case1-accept.test.mjs excluded
|
||||
as ordered. No unlisted run or extra mutant. Targeted counts: query34/34,
|
||||
broker12/12,typed tools5/5,zero skips.
|
||||
|
||||
M1-M9 all killed with exit1, no syntax/setup failures. M1 and M8 are expected
|
||||
behavior errors when a required capability is removed; the others fail
|
||||
assertions/refusal checks. Killing named tests are recorded below. Each
|
||||
restored original bytes in finally; git diff --stat and status --porcelain
|
||||
empty after every mutant and again after all normal runs, before receipts.
|
||||
No extra post-restore test rerun.
|
||||
|
||||
| Mutant | Killing behavior oracle | Restored |
|
||||
| --- | --- | --- |
|
||||
| M1 | supporting find/search/get | byte-exact, clean |
|
||||
| M2 | get without scope returns null | byte-exact, clean |
|
||||
| M3 | each get blob equals its served tree object | byte-exact, clean |
|
||||
| M4 | full outgoing and incoming links stay in scope order | byte-exact, clean |
|
||||
| M5 | full outgoing and incoming links stay in scope order | byte-exact, clean |
|
||||
| M6 | full outgoing and incoming links stay in scope order | byte-exact, clean |
|
||||
| M7 | manuscript still refuses supporting | byte-exact, clean |
|
||||
| M8 | broker forwards supporting scope | byte-exact, clean |
|
||||
| M9 | scope schemas expand only find/search/get | byte-exact, clean |
|
||||
|
||||
Post-run sweep: current OS user's executable names node/nodejs/chromium/
|
||||
chrome, matching cwd or argv paths under this worktree or any run TMPDIR.
|
||||
Checked289 unique roots;0 matching live processes. No signals sent, no
|
||||
other seat's process inspected beyond process identity/path matching.
|
||||
No full argv, environment or credential values printed. Slot returned to
|
||||
Sage in della-0059 at22:34Z. No further tests.
|
||||
|
||||
Evidence: /mnt/storage/scratch/della-row284-r2-evidence/run-4289 contains
|
||||
install receipt, exact commands, stdout/stderr per whole-file run, mutant
|
||||
edits/restores, summaries and hashed logs. The following plain-text ledger
|
||||
freezes commands and results; raw logs remain available for reviewer checks.
|
||||
Each normal test path below was run whole; hashes are SHA256 of raw logs.
|
||||
|
||||
```text
|
||||
{"label":"target-query","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gUgw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.889,"mutant":false,"tests":34,"pass":34,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"dc2575e2c597b099c94b7cf254b0cb4d009a0ddb14c0cbd572f93e5ad15f8f72"}
|
||||
{"label":"target-broker","command":["timeout","-k","10","900","node","--test","packages/bus/tests/library-lookups.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDd2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.431,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6729e92f2241a2c2d0b725cb9c6ed4fe4d8b50352fd179cf30f905182eac9160"}
|
||||
{"label":"target-tools","command":["timeout","-k","10","900","node","--test","packages/harness/tests/library-tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmPG","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.169,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"532de351eef39478011d7f84b3b506711c3bafc71676716f623fa29573fc4dec"}
|
||||
{"label":"M1","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gIGt","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.683,"mutant":true,"tests":34,"pass":30,"fail":4,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ec36434e918ee16c7639ec0ec4259be66e0381e2684bac7c6ee5755756bded78"}
|
||||
{"label":"M2","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/geid","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.587,"mutant":true,"tests":34,"pass":31,"fail":3,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e08eadfd606fc685faed21edb06b1d7d00fd11e7942051fddc0b48b83c6bef90"}
|
||||
{"label":"M3","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gs4j","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.538,"mutant":true,"tests":34,"pass":33,"fail":1,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"8abb79847deb7a05940c7b48d5407dde6baaf394fef31334f6ac266d65b3c02f"}
|
||||
{"label":"M4","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gvmZ","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.674,"mutant":true,"tests":34,"pass":33,"fail":1,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"8b8386b876fb85e12335be27216dc5c6a8d5c311c03db0bf49ffbe0639a8693c"}
|
||||
{"label":"M5","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gG6o","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.633,"mutant":true,"tests":34,"pass":32,"fail":2,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"08ff976a29e42f593dce3262e596e75c43da2ae2e3dfe48945989fe98c3061cf"}
|
||||
{"label":"M6","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gWpu","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.347,"mutant":true,"tests":34,"pass":23,"fail":11,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4cd149d0f74e402d2294c2d9ef05aac440ec4c3dc379acad7b9624b7402528bb"}
|
||||
{"label":"M7","command":["timeout","-k","10","900","node","--test","packages/library/tests/query.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g65B","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":2.403,"mutant":true,"tests":34,"pass":33,"fail":1,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"541100f0937dd2e592ed9bee7c48f27ae4e13634d3c0dcf53fc3e8b2f632a000"}
|
||||
{"label":"M8","command":["timeout","-k","10","900","node","--test","packages/bus/tests/library-lookups.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gtX5","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":1.421,"mutant":true,"tests":12,"pass":11,"fail":1,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2adc93e5aaa663621caa9fd762faded3a975f62de918d7c46a1b5b0469001955"}
|
||||
{"label":"M9","command":["timeout","-k","10","900","node","--test","packages/harness/tests/library-tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gMtM","start_nice":19,"observed_timeout_nice":19,"exit":1,"seconds":0.199,"mutant":true,"tests":5,"pass":4,"fail":1,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"da8c8c2094732b36526dc803e567d4bce18ff964bf70ff406e1981bb7dd313de"}
|
||||
{"label":"import-001","command":["timeout","-k","10","900","node","--test","packages/bus/tests/access-revoke.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGcs","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.728,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ee78177b9385025df0b0ce154e9f92f3d84a01920da94eb2b95df7aee533721a"}
|
||||
{"label":"import-002","command":["timeout","-k","10","900","node","--test","packages/bus/tests/account-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/giJX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.456,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"04456ac702b53d59e127eb7ae2d9828b79acbbcc99c8845cc226e88e4569ffb2"}
|
||||
{"label":"import-003","command":["timeout","-k","10","900","node","--test","packages/bus/tests/address.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gLUL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.102,"mutant":false,"tests":15,"pass":15,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c4ff31db588ac88b6492416d3850b123492e29dbd7c6b2aa283dd736e6caa8cc"}
|
||||
{"label":"import-004","command":["timeout","-k","10","900","node","--test","packages/bus/tests/agents.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDuh","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.493,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"424001894b865c63405976f7facc9a9c93c2ac018b6c97f17ebf87001d071d52"}
|
||||
{"label":"import-005","command":["timeout","-k","10","900","node","--test","packages/bus/tests/approval-binding.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gsfL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.305,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f8029477d12d0acbd774ec6fa82d9af47ae93c575e0ada16c31130248280431d"}
|
||||
{"label":"import-006","command":["timeout","-k","10","900","node","--test","packages/bus/tests/broker.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gwdO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.532,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b02528f749bc8367149451f2118cf612f7d46ee6269ad05d9a894d6ef893b727"}
|
||||
{"label":"import-007","command":["timeout","-k","10","900","node","--test","packages/bus/tests/business.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gX5H","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.102,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"3246c77a5431fda5ee0ef798b9850ee8bf05297c7afa272fc88d148582dc14d8"}
|
||||
{"label":"import-008","command":["timeout","-k","10","900","node","--test","packages/bus/tests/channel-proof.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g0t2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.644,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d3dc7af8bd80c5cd391a42468cec38fa2cdf4d7bb8d758e84094a255cf2e8626"}
|
||||
{"label":"import-009","command":["timeout","-k","10","900","node","--test","packages/bus/tests/chief-of-staff.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gAXk","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.744,"mutant":false,"tests":42,"pass":42,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6e355388daee3b3cfe0251abd3f1f1fc56744e26354b8489d8113e4cb4033847"}
|
||||
{"label":"import-010","command":["timeout","-k","10","900","node","--test","packages/bus/tests/citation-availability.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gNQV","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.391,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fe32f9423c7317c53d0946d6422fb4ea58bcbb0795730b80cba7b5daae47b8ef"}
|
||||
{"label":"import-011","command":["timeout","-k","10","900","node","--test","packages/bus/tests/citation-guard.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gilj","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.258,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1f6c35c535a407a121ec4ee9bb4e9acdc12b5e16e3f8ccf75bcb94a66511b820"}
|
||||
{"label":"import-012","command":["timeout","-k","10","900","node","--test","packages/bus/tests/citation-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gjTW","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.331,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9cb0ab5a64b667f563c827239c242ee77475acb8744e515d8472d839d7190e2e"}
|
||||
{"label":"import-013","command":["timeout","-k","10","900","node","--test","packages/bus/tests/comment-cursors.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQvO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.162,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"898a7bcc0f68f8a54748a9da6c75b702738b07230a48ff4f939206b1c2dccfdf"}
|
||||
{"label":"import-014","command":["timeout","-k","10","900","node","--test","packages/bus/tests/comment-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g4nL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.609,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ade667dca625e36750417b46f3156be89ec5d40fff78511722c3fa671f3bcd25"}
|
||||
{"label":"import-015","command":["timeout","-k","10","900","node","--test","packages/bus/tests/console-decide.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/girM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.893,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"11a0ac7147f0164542442a9fc6e9224e5d36305cd3e999fc03733e289dfc8f4e"}
|
||||
{"label":"import-016","command":["timeout","-k","10","900","node","--test","packages/bus/tests/creative.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gXAL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.447,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"13b107465c7ddecb4fba573b58d4ff42f8807221d1956325b2a0e54eec4581d2"}
|
||||
{"label":"import-017","command":["timeout","-k","10","900","node","--test","packages/bus/tests/credential-claim.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g8Cy","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.157,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a66956b56367cb240de84571fc79e4297bf4bf49c06ce92ac3dd9c5d155b26a5"}
|
||||
{"label":"import-018","command":["timeout","-k","10","900","node","--test","packages/bus/tests/credential-status.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEDT","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.401,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"8812b6b0962c7b15e437a9c9b5741d502ab81001d9e17c9b5b14729db8f6033d"}
|
||||
{"label":"import-019","command":["timeout","-k","10","900","node","--test","packages/bus/tests/credential-store.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPQx","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.158,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2ead3ac9725024e493121f7aaa8e7cf71a35616ffd57c901d3f425ac50b4a8b7"}
|
||||
{"label":"import-020","command":["timeout","-k","10","900","node","--test","packages/bus/tests/credential-verbs.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g1Wz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.328,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"bf447a8e6566816992f48a92e6821441ec1acd86960251aeee4b03b6e4b6dee3"}
|
||||
{"label":"import-021","command":["timeout","-k","10","900","node","--test","packages/bus/tests/credentials.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/grcF","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.105,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f3f807e470c8ec40f6c1aea188308a1ca183c8f0e98a0eaea996c96577ab471a"}
|
||||
{"label":"import-022","command":["timeout","-k","10","900","node","--test","packages/bus/tests/csuite-messaging.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gFHk","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.779,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1034823ca51c040db2f0bb18416c67761580ed55df0e60636883bc217878afd5"}
|
||||
{"label":"import-023","command":["timeout","-k","10","900","node","--test","packages/bus/tests/daily-quota-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gl0H","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.401,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"95472c3d6b012d38f3db4c790fdd48b710535beee03274c0ea44a2cbd97ed095"}
|
||||
{"label":"import-024","command":["timeout","-k","10","900","node","--test","packages/bus/tests/decision-close.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g2Iz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.34,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"5c855717b19f203797db5b4f2789dd8f8df7d49cbdfee62ae0ffa220e4ed1a4a"}
|
||||
{"label":"import-025","command":["timeout","-k","10","900","node","--test","packages/bus/tests/decision-route.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDI5","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.286,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"485577231e6e797c256db8a832d98aca4bf856e47459e0c30a1940598c60b8aa"}
|
||||
{"label":"import-026","command":["timeout","-k","10","900","node","--test","packages/bus/tests/decisions.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/geqP","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.474,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"aa887a5b2b30390fab4906cbd2f6ffa4ec37cc9e794478b18e7cd47eb354063b"}
|
||||
{"label":"import-027","command":["timeout","-k","10","900","node","--test","packages/bus/tests/end-launch.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g5u4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.414,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e3aced744c09beda07405cba691c54a8c8dca973b7718285f67612cbfdad4ac1"}
|
||||
{"label":"import-028","command":["timeout","-k","10","900","node","--test","packages/bus/tests/fire-revokes-grants.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gD7b","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.034,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0e79b5a7c00f0701c84b76f3e9fd73f1bac2c9343594039df1e8a667e42d6ea4"}
|
||||
{"label":"import-029","command":["timeout","-k","10","900","node","--test","packages/bus/tests/gitea-grant-docker.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcCX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":25.371,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"5720e4fc3d58350dc4192c7ceb5dff76aba9bf1aff1ac917e016e7295380b325"}
|
||||
{"label":"import-030","command":["timeout","-k","10","900","node","--test","packages/bus/tests/gitea-grant.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gIPd","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":12.386,"mutant":false,"tests":66,"pass":66,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"142962fbea6f3602701e4bcc5e0248cb06b98a2fad8bfafb92143a593e535ee6"}
|
||||
{"label":"import-031","command":["timeout","-k","10","900","node","--test","packages/bus/tests/gitea-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPFr","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.443,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2a3d38fa696805a193460d33bfec2461778463b7087e368b738700c583ad23c3"}
|
||||
{"label":"import-032","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-enroll.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gAeL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.838,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fc5d1d86af5c0689eb5a92d94ee1dc7a0143299523fc010d4a119c34b30ff768"}
|
||||
{"label":"import-033","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-executor.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEJ1","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":22.682,"mutant":false,"tests":42,"pass":42,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"97a66205b109952a7704ff9d5d63efbb0277922a0bf1510a677284f9ccbc9831"}
|
||||
{"label":"import-034","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-host.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gYeV","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.433,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0ab7ed5613f9c353c5e6f786ceffc6112c4f851debb799cf60ff73ae2f2bf65d"}
|
||||
{"label":"import-035","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcHz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.495,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"690a9c67e3426b8f6dc94c34f1b34ae5e502c0f8fb9ce67c5beab7cf5122557e"}
|
||||
{"label":"import-036","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-scope-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gVjH","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.228,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c013731042ef37735fe6648ec299831b127d3ddb351c613d95efd4bc610d6ff2"}
|
||||
{"label":"import-037","command":["timeout","-k","10","900","node","--test","packages/bus/tests/grant-scope.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gwvw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.35,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1b48fba6570d0dcef4666725bde8b8c8f95e75eb8abb517d15b226a6ae5b0ea4"}
|
||||
{"label":"import-038","command":["timeout","-k","10","900","node","--test","packages/bus/tests/hard-waits.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gM7r","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.464,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"41d7bdf1b5276a7205b6b3e61ff4ac2f7982d60f5f190c3475e75c1ff4cebefd"}
|
||||
{"label":"import-039","command":["timeout","-k","10","900","node","--test","packages/bus/tests/host-run.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfCB","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":15.268,"mutant":false,"tests":26,"pass":26,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7f5c5ab5e5f654c1826e84369739616606de89763879d96ffaa9cc196db05d72"}
|
||||
{"label":"import-040","command":["timeout","-k","10","900","node","--test","packages/bus/tests/host-tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbtM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.726,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"dfd0a799f300925eb291c8047adc0f9359bf05927f0b1c129c6b420fcf0bfcc0"}
|
||||
{"label":"import-041","command":["timeout","-k","10","900","node","--test","packages/bus/tests/human.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gnLK","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.102,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"09791081c562afc5c9fa6da5b6df4e37935797147fc6d4c3f4cd8be2dd3d56ae"}
|
||||
{"label":"import-042","command":["timeout","-k","10","900","node","--test","packages/bus/tests/instances-verb.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g46h","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.305,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d41d14dd33492e34f21452550fed8d0ca0d3b1847cca0fb86c53ad13f8cb4fb7"}
|
||||
{"label":"import-043","command":["timeout","-k","10","900","node","--test","packages/bus/tests/interpreter.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gTjS","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.178,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c3be5eace9c994767d451fcd0d99ddfff2a647a8f7e74f21306c95ac503c229c"}
|
||||
{"label":"import-044","command":["timeout","-k","10","900","node","--test","packages/bus/tests/land.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gOEa","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.156,"mutant":false,"tests":18,"pass":18,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b59e6b60f597b4b1d02d4ced63344dbcb820946148a11a4ddd8e29ac422ef0f8"}
|
||||
{"label":"import-045","command":["timeout","-k","10","900","node","--test","packages/bus/tests/launch-notice.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gv3V","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.543,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4979af0184d2b8fe0cfc7048da37828e2f58a8bb433b589399be4d8a7798371d"}
|
||||
{"label":"import-046","command":["timeout","-k","10","900","node","--test","packages/bus/tests/launcher-released.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEQl","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.365,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9e4890aeaa7e21398fb140c469c606cb8a5cec2b564826232ade66f171fed937"}
|
||||
{"label":"import-047","command":["timeout","-k","10","900","node","--test","packages/bus/tests/library-credential.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJlk","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.11,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ca7c89d815a3bc281b406089a04dbaf94d04927c0b6b0ae840cae34cd8e858f5"}
|
||||
{"label":"import-049","command":["timeout","-k","10","900","node","--test","packages/bus/tests/library-sync.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/geyX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.525,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"835bea6e1730fb67ab7d7ef02701ace657b0b3a839d300713ca16d0a32713828"}
|
||||
{"label":"import-050","command":["timeout","-k","10","900","node","--test","packages/bus/tests/library.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gejb","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.736,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"70633e1f2e5662e511239ada1bb47e1dc197b79e2c9ecf005308b270f713a41c"}
|
||||
{"label":"import-051","command":["timeout","-k","10","900","node","--test","packages/bus/tests/lifecycle-revoke.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gA7g","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.815,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"190fd253cefb4d669245531043a93225d37ae66ba694635a3e8bffd86c9e4264"}
|
||||
{"label":"import-052","command":["timeout","-k","10","900","node","--test","packages/bus/tests/lifecycle-verbs.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gYLp","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.62,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"071bed270aff7f251d954b557e090230ee6e224535938b85b93e8f885d3fb944"}
|
||||
{"label":"import-053","command":["timeout","-k","10","900","node","--test","packages/bus/tests/limit-checks.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gt3p","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.347,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"cb634a9e2819a161ec128a250586e4086591696309f00c9e6a62d7c54c6b9382"}
|
||||
{"label":"import-054","command":["timeout","-k","10","900","node","--test","packages/bus/tests/limit-stop.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g1Vs","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.362,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"93504cdb3c5a9e5295bd72b8224ec69c43bbd344529a97538376c5a09e47328e"}
|
||||
{"label":"import-055","command":["timeout","-k","10","900","node","--test","packages/bus/tests/limits-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/giXl","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.454,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a18ac489d4eaa62e0bdb40444d70722379b0f4dc172f28e71f8600307ce7c3b6"}
|
||||
{"label":"import-056","command":["timeout","-k","10","900","node","--test","packages/bus/tests/limits.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZog","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.424,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"072dfdd9f45f609d52910d3619d4253bd05b54ec36e1a8599db17e17b472e99a"}
|
||||
{"label":"import-057","command":["timeout","-k","10","900","node","--test","packages/bus/tests/message-citation.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gCEq","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.244,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d53489b437b4adc8ac10bc52d0f1e6557b6fd187786008a6ad13a264207be034"}
|
||||
{"label":"import-058","command":["timeout","-k","10","900","node","--test","packages/bus/tests/message-filter.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gsfe","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.58,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6038a839d1b12b29d8cdbc0ea341ae22197e19444be5743ca327cb188cd1af59"}
|
||||
{"label":"import-059","command":["timeout","-k","10","900","node","--test","packages/bus/tests/messages.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gkz2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.501,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e507905469453069f469a1366bd4cbd446c6b7e2e8ba5234c3d0bee83d1172ba"}
|
||||
{"label":"import-060","command":["timeout","-k","10","900","node","--test","packages/bus/tests/messaging.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPZR","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.502,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"434390031617151891ecb63a788da353c0d43051a4ea60db2e5727b149c9de4e"}
|
||||
{"label":"import-061","command":["timeout","-k","10","900","node","--test","packages/bus/tests/name-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gsLH","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.192,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1979f0b1dd32162d42acace08a4b4306249e1096f5bbadb47038681af6b375d5"}
|
||||
{"label":"import-062","command":["timeout","-k","10","900","node","--test","packages/bus/tests/names.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/grPm","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.313,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1d35ce65a08ec74388a7a65af8bfb7a87d341fab5795360fd553e65aa10d4999"}
|
||||
{"label":"import-063","command":["timeout","-k","10","900","node","--test","packages/bus/tests/peer-transport.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g2ja","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.194,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"579cce4a4581e991e6cad80666cd40bfb10d1346699f1233a44dab5d17ee1583"}
|
||||
{"label":"import-064","command":["timeout","-k","10","900","node","--test","packages/bus/tests/peercred.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g35b","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.499,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c6d9c4a534f8aab5c73e6920346674eb243a19439eaaa09436ff4c2bc9b68fd7"}
|
||||
{"label":"import-065","command":["timeout","-k","10","900","node","--test","packages/bus/tests/plugins-verb.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGrj","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.331,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4677c69292a7fe1961239e40ecd5848b1e9355e6d9326f1c935dd077605cc36b"}
|
||||
{"label":"import-066","command":["timeout","-k","10","900","node","--test","packages/bus/tests/principal.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g5U9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.102,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"efac2a82f133ae63ba26543832b6704df573f345c7699b48b928d4329467f03e"}
|
||||
{"label":"import-067","command":["timeout","-k","10","900","node","--test","packages/bus/tests/process.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/go8U","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.448,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e26c9f5eb045dd7f651f453875fc1daac5dafa5f2060a69c3edcf37c79433e24"}
|
||||
{"label":"import-068","command":["timeout","-k","10","900","node","--test","packages/bus/tests/processing-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmrO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.392,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"624f60b78329dbf8db5b5ce17e9f218148f7e417a46bcace45666b10193ea4c4"}
|
||||
{"label":"import-069","command":["timeout","-k","10","900","node","--test","packages/bus/tests/processing-timeout.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gt14","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.263,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"30a4c425941c5732bb0afa09ff8cf2229f11ec6031c7cd3ae26932cf55dc2552"}
|
||||
{"label":"import-070","command":["timeout","-k","10","900","node","--test","packages/bus/tests/processing-web.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gWj9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.126,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"dbe9bc036efc99fc38b2dea8824cb7a64fc39e49fcd3a1ef07c60298b0d8e69f"}
|
||||
{"label":"import-071","command":["timeout","-k","10","900","node","--test","packages/bus/tests/processing.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gP4m","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.381,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d2204029f1dbc5836a759b43d421f2790ca32b97a1cc1fc6cb3f098fa4d7ab5d"}
|
||||
{"label":"import-072","command":["timeout","-k","10","900","node","--test","packages/bus/tests/project-await.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/grrE","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.177,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"55cb0e215ff4f1e3265322c3336b3861d37fc3ba3cac53a31aa3dcc9ee0cab46"}
|
||||
{"label":"import-073","command":["timeout","-k","10","900","node","--test","packages/bus/tests/project-files.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZZ4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.894,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b3395652052ccd06de8df2a1ce1aaac185dab50e854fb712a33aef8319d17fdc"}
|
||||
{"label":"import-074","command":["timeout","-k","10","900","node","--test","packages/bus/tests/project-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gYyK","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.404,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b139c3c9cea5fc9bd86ac64f33c4af23f568bee13f9271fef40a07d76ed51cf2"}
|
||||
{"label":"import-075","command":["timeout","-k","10","900","node","--test","packages/bus/tests/publish.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gUl2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.831,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0adf717babd8ac6229a115e1c796071fd68c1524f140d4596c9f1ee8c528b69f"}
|
||||
{"label":"import-076","command":["timeout","-k","10","900","node","--test","packages/bus/tests/reload.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZPr","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.003,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2ce6a9bd3ea3eeccf1689e1b6335b72bba2d440ae27feeec3dc727567fa140ff"}
|
||||
{"label":"import-077","command":["timeout","-k","10","900","node","--test","packages/bus/tests/replies.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbjz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.374,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6db5c1588c83f2df4be469f06857569df7f4cfc47c18b15a8f9e741d4d739c4f"}
|
||||
{"label":"import-078","command":["timeout","-k","10","900","node","--test","packages/bus/tests/requirements.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g1jX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.192,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"32b876110fc8a35246f6ab16343dae9ea6da42ef556a99e1e5356e077474a96f"}
|
||||
{"label":"import-079","command":["timeout","-k","10","900","node","--test","packages/bus/tests/review.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gVJz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.427,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"333b7d84cf72b95ba2cdb1d3824bcb8043623c5f0810c68ed22738210977c297"}
|
||||
{"label":"import-080","command":["timeout","-k","10","900","node","--test","packages/bus/tests/revoke-window.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gRZs","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.305,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7e759b3330537c0c566b55b2c405adc6f5f48c3b229c4450d938aaec3280fc09"}
|
||||
{"label":"import-081","command":["timeout","-k","10","900","node","--test","packages/bus/tests/room-check.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gzW9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.225,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"300f1ea96ccfa38c9405ef163e531cfeec3c7eb8f46986f077669ca95b8f72f3"}
|
||||
{"label":"import-082","command":["timeout","-k","10","900","node","--test","packages/bus/tests/rooms.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEx0","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.033,"mutant":false,"tests":18,"pass":18,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fbcac36a4495da1def5dd650d8aea5758bf25d3e7473148a2b8961bb97b57239"}
|
||||
{"label":"import-083","command":["timeout","-k","10","900","node","--test","packages/bus/tests/routes-verb.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g0LO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.292,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4fef276b76a79518faa03b81d119962ab8880af3010fa33ead93f393dca89f02"}
|
||||
{"label":"import-084","command":["timeout","-k","10","900","node","--test","packages/bus/tests/schema.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZFQ","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.169,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e71271414564fa851dbf25a155b44dcf481770c7f3d4dafe5ce44a09c49526b1"}
|
||||
{"label":"import-085","command":["timeout","-k","10","900","node","--test","packages/bus/tests/session-clear.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfrg","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.773,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c8097880d5e9a396fb907bc1f35f342821971b545fea7f1e4ddcb2b9f2fb322a"}
|
||||
{"label":"import-086","command":["timeout","-k","10","900","node","--test","packages/bus/tests/session-compactions.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfRL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.179,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0a2f0ef4d7f6588e2aaeb5a5d8e200650ae573c4468640130140eb83430261b3"}
|
||||
{"label":"import-087","command":["timeout","-k","10","900","node","--test","packages/bus/tests/sessions.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gaNb","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.654,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"11f26dc0d082b49ce7839d22aca75067dcc2f978d6c319da3d2800adcc0a9ffc"}
|
||||
{"label":"import-088","command":["timeout","-k","10","900","node","--test","packages/bus/tests/single-use.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gSe3","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.416,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7a0e2e7a4a6ab79b85462ad1a39955c5402dab8a9236534c857cef88d08ecc87"}
|
||||
{"label":"import-089","command":["timeout","-k","10","900","node","--test","packages/bus/tests/spec-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPmw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.215,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b9831356a0d65a037796a66764dcf7dcc267d8512e70087b364cbe390a8c85dc"}
|
||||
{"label":"import-090","command":["timeout","-k","10","900","node","--test","packages/bus/tests/spec-review.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqKv","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.034,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"8a70a550b2b056c35f2e85bdd4a155bf7d02332d89596aeed40e16bec765221c"}
|
||||
{"label":"import-091","command":["timeout","-k","10","900","node","--test","packages/bus/tests/spec-socket.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gY6G","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.787,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d58670526310fa5106ab9b3d724d817910283b76cfa8bd79278b0428e42b73c3"}
|
||||
{"label":"import-092","command":["timeout","-k","10","900","node","--test","packages/bus/tests/spec.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gnTM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.538,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d04ac45ad25906322cbbd50b703c316c4eeefad1d40f901eeaf2c34224fc5958"}
|
||||
{"label":"import-093","command":["timeout","-k","10","900","node","--test","packages/bus/tests/staff-request.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g07B","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.544,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e0e379d2e0871ecbbae9a5e92ee7217342dc31cf69c80373aeef72f78ea27fd9"}
|
||||
{"label":"import-094","command":["timeout","-k","10","900","node","--test","packages/bus/tests/state.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gx6m","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.289,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"63ac32064c6220c89204a8c34f13ce45ebb76f65a6e10e4173608740e1b54887"}
|
||||
{"label":"import-095","command":["timeout","-k","10","900","node","--test","packages/bus/tests/store.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g5mj","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.286,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"329377b361787f86ffb5bda9210559d3d073e8ed9cfacc43e341156de63af707"}
|
||||
{"label":"import-096","command":["timeout","-k","10","900","node","--test","packages/bus/tests/task-page.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gErK","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.203,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0e48322586d18073df7d9efbc0700b7f9e2e45a7a61eb32ffa13ab9d9695de54"}
|
||||
{"label":"import-097","command":["timeout","-k","10","900","node","--test","packages/bus/tests/task-read.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g7B0","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.237,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"3aa73723d9410d5c6851352f6b3d9c0f671f9b008b8a2355021488f2a071c22b"}
|
||||
{"label":"import-098","command":["timeout","-k","10","900","node","--test","packages/bus/tests/tasks.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqcQ","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.037,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"60e43ca791f0ee0e5a91c0a112ad0d971f38d28e18d6feb7a2d33132aec934fe"}
|
||||
{"label":"import-099","command":["timeout","-k","10","900","node","--test","packages/bus/tests/tester-threads.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbPX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.486,"mutant":false,"tests":15,"pass":15,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"101fcf483990278f3a997ed1cff44b6191b1766147083ddf21341a4480eb602b"}
|
||||
{"label":"import-100","command":["timeout","-k","10","900","node","--test","packages/bus/tests/tester-writes.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gMT4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.609,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d5618314574cf7e64ac877e29787712f5fd68903228e6e1001c37cdd9b54a9e4"}
|
||||
{"label":"import-101","command":["timeout","-k","10","900","node","--test","packages/bus/tests/tester.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gl5m","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.337,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c44885e9d43e6ed5969af2f87ecc17fe00e1f1895435d86f5ddbe399c945642e"}
|
||||
{"label":"import-102","command":["timeout","-k","10","900","node","--test","packages/bus/tests/thread-claims.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmfF","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.354,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"bd053d20e52d1859ea6ed13f316e7ed27dac3ba3a8f1be5b3b7adef2fa15e356"}
|
||||
{"label":"import-103","command":["timeout","-k","10","900","node","--test","packages/bus/tests/thread-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gUt3","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.513,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ee94081c476ab12b1c1b73eb2efb6138c22deee6dda92aa015fd2b2cc4cc405e"}
|
||||
{"label":"import-104","command":["timeout","-k","10","900","node","--test","packages/bus/tests/thread-shares.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g6KY","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.966,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e2c37691510cc5acfecfcd6d5be612b701fa72a06c544c265b027a381eb577ae"}
|
||||
{"label":"import-105","command":["timeout","-k","10","900","node","--test","packages/bus/tests/threads.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqdT","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.848,"mutant":false,"tests":20,"pass":20,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0e25845dfd5e6c68c206ef19b6ab74b5e00d01cf2ce6cd8843b7f0abe4229d60"}
|
||||
{"label":"import-106","command":["timeout","-k","10","900","node","--test","packages/bus/tests/transport.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gG0Z","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.355,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"177ad5f143bb47dc7d65ef89785b19170ed7f5a25d1dd78079c73367b7d34bb5"}
|
||||
{"label":"import-107","command":["timeout","-k","10","900","node","--test","packages/bus/tests/usage-broker.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gYVM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.179,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"91d3b9ff3e854f2afb6d635a0994a4b2d1af482804067c2e6f78930babf25378"}
|
||||
{"label":"import-108","command":["timeout","-k","10","900","node","--test","packages/bus/tests/usage-migration.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJIX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.232,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"35dae9048409bf16982b1554b0d3bf53de51293c012b428cfa95e3876c353d1b"}
|
||||
{"label":"import-109","command":["timeout","-k","10","900","node","--test","packages/bus/tests/usage-runtime.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gzcI","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.3,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1b260c414d98caf272852cc1c6a0928a79f84b05baad356f954fabb8befed9f4"}
|
||||
{"label":"import-110","command":["timeout","-k","10","900","node","--test","packages/bus/tests/usage.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g9hD","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.341,"mutant":false,"tests":15,"pass":15,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4b7a7719685b54f0bafcd0d6ca0eff8da3c35e8c438b69fb63826120c444646d"}
|
||||
{"label":"import-111","command":["timeout","-k","10","900","node","--test","packages/bus/tests/user-principal.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gCyo","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.843,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7e5d8e391b6d683905f7654276e74e56cd2e0bb3019d8882fb51f5e96e8bb4e2"}
|
||||
{"label":"import-112","command":["timeout","-k","10","900","node","--test","packages/bus/tests/viewer.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gckq","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.495,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0088c69c83ad21b0c09c5b74986f7d1b5609f6155d40d6230cb755914506b209"}
|
||||
{"label":"import-113","command":["timeout","-k","10","900","node","--test","packages/bus/tests/web.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gr8J","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.209,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"81db5367857555ba39abf0d45a2b4837a60c796109af4039b43f3dceaaf9a3e4"}
|
||||
{"label":"import-114","command":["timeout","-k","10","900","node","--test","packages/bus/tests/workflow-roles.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gObE","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.265,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4a3d911233067a9623aacbe0f856296e7c80d616d1099a30a9ce253506791bb2"}
|
||||
{"label":"import-115","command":["timeout","-k","10","900","node","--test","packages/business/tests/case1-business-file.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gKGR","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.839,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2dd7e08774e88449fc90beffa7a1097772a4b04906e62548cd34b31f1cf541b3"}
|
||||
{"label":"import-116","command":["timeout","-k","10","900","node","--test","packages/business/tests/launch-settings.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gaiJ","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.451,"mutant":false,"tests":18,"pass":18,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"849eeebfaaf47c96f22db45752fb5f00143663fb4ed0aa2d22d74f8af9ea3905"}
|
||||
{"label":"import-117","command":["timeout","-k","10","900","node","--test","packages/cli/tests/access-boot.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gU7B","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.64,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1698f3f93b14d11b330e559f19a580edae78b4182042df0e7da1cc9d4cbb53be"}
|
||||
{"label":"import-118","command":["timeout","-k","10","900","node","--test","packages/cli/tests/access.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHaW","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.364,"mutant":false,"tests":34,"pass":34,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e42f5491e4db8370ad6f6c2f09a8008c9559ecd572f0985f766f0ca11b1d7b60"}
|
||||
{"label":"import-119","command":["timeout","-k","10","900","node","--test","packages/cli/tests/app.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmHw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":16.086,"mutant":false,"tests":30,"pass":30,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d65043a7cf3a1d67b99bb47de8efa029c44b90b9fcc0cc7cb8d8ed54403bba81"}
|
||||
{"label":"import-120","command":["timeout","-k","10","900","node","--test","packages/cli/tests/boot-status.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gYv3","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.916,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f6753a454d658737099bb6da76219aeb3c6e92bce76b78c53f2d9dae29f5d777"}
|
||||
{"label":"import-121","command":["timeout","-k","10","900","node","--test","packages/cli/tests/case1-hostcheck.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gvaK","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.735,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"aeb1e23bf951d5859d7adb54fe8f3c6464ba4bf368e9316dce8e5142e097565c"}
|
||||
{"label":"import-122","command":["timeout","-k","10","900","node","--test","packages/cli/tests/case2-install.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gLWb","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":11.37,"mutant":false,"tests":27,"pass":27,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"06166332e80fd57cd9ae5e5ef2f167260adb413cd6c799b9c1834255cbf3ed63"}
|
||||
{"label":"import-123","command":["timeout","-k","10","900","node","--test","packages/cli/tests/case2-persona-import.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g955","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.606,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6005b321161cba438dc94ee6f58a05a05919e099da0d5b43b16b0438214b128e"}
|
||||
{"label":"import-124","command":["timeout","-k","10","900","node","--test","packages/cli/tests/case2-unit.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPC5","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":104.569,"mutant":false,"tests":47,"pass":47,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b9c64e1eea4e389dfc10b9e1ddf88e47d903c7abb1f175b0f73b0a6adf5e8a3b"}
|
||||
{"label":"import-125","command":["timeout","-k","10","900","node","--test","packages/cli/tests/channel-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gCxf","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.604,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"69ae3003d282a5f998613498ca1a696b684a9e4c03f5b006409d1fb15402c3c6"}
|
||||
{"label":"import-126","command":["timeout","-k","10","900","node","--test","packages/cli/tests/channel-recovery.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gy7b","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.039,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0df2d0dce24f2c7e9e70c1db3da115d848ee778a3b77c30f50db5fa5b70b15a8"}
|
||||
{"label":"import-127","command":["timeout","-k","10","900","node","--test","packages/cli/tests/cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g4YA","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.986,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9e9f75b810bdce44a7e288a0f03572a824642a0e615c3912113d8882fba57f20"}
|
||||
{"label":"import-128","command":["timeout","-k","10","900","node","--test","packages/cli/tests/compactions-launch.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gH0o","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":18.141,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7ab789f5de01f4d9fb2c2933fc906d657bb3c867ebb7e8545b4ae8b2f07e348b"}
|
||||
{"label":"import-129","command":["timeout","-k","10","900","node","--test","packages/cli/tests/config.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gvdv","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.989,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"46976c51d867431031baeb7dfb03518e111f88327f99f24fafa727c987037710"}
|
||||
{"label":"import-130","command":["timeout","-k","10","900","node","--test","packages/cli/tests/credentials.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gW4m","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.558,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1633748b05e927193646fd8eaeb9cc64092553734a972a33ac9b26baee4390e1"}
|
||||
{"label":"import-131","command":["timeout","-k","10","900","node","--test","packages/cli/tests/federation-acceptance.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEeW","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.281,"mutant":false,"tests":1,"pass":0,"fail":0,"cancelled":0,"skipped":1,"todo":0,"log_sha256":"76dec3f040a21cad59757b69487247ebb3b6a8b27b015f0615585b3be477942a"}
|
||||
{"label":"import-132","command":["timeout","-k","10","900","node","--test","packages/cli/tests/follow.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gxPz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.084,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"db3463b8998634a487878c02c81b31eb196077dc45ac102de56f6f06a7bd26ee"}
|
||||
{"label":"import-133","command":["timeout","-k","10","900","node","--test","packages/cli/tests/git-socket.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcHM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":27.936,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c1a6247751b05dcaad81d9a42e93c923200f2971ef17622924d00a07c8292735"}
|
||||
{"label":"import-134","command":["timeout","-k","10","900","node","--test","packages/cli/tests/grants-scope.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gRr9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.298,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2f9222ce2ac41443cb24c69bffea46fd96c53af469670f642dcc2319d162ffc5"}
|
||||
{"label":"import-135","command":["timeout","-k","10","900","node","--test","packages/cli/tests/grants.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbr2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.418,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"018fba785221ec997b369739f1fa39ff927f7144b6276f071338a64ba331e555"}
|
||||
{"label":"import-136","command":["timeout","-k","10","900","node","--test","packages/cli/tests/host.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gIQc","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":20.522,"mutant":false,"tests":43,"pass":43,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"98d2bb8ac91e143fd16fb02b29d877b2df4397a1d8857687707d0bfebb3459be"}
|
||||
{"label":"import-137","command":["timeout","-k","10","900","node","--test","packages/cli/tests/hosts.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gB9t","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.5,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"376d8a698c39bc25b9e43ee63f762718ab2d2d2dbfab36da61971e3982f98353"}
|
||||
{"label":"import-138","command":["timeout","-k","10","900","node","--test","packages/cli/tests/idle-stop-race.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gt4N","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.246,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4ee49db59177a6cedcc98642ad2b4215e1489c8720e3ab27c88a1d3513b4384f"}
|
||||
{"label":"import-139","command":["timeout","-k","10","900","node","--test","packages/cli/tests/instances.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/ga2n","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.158,"mutant":false,"tests":15,"pass":15,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"125780e39af442913bf056f71a57b663c954d8eb5a96fb245db8063237ccb1e1"}
|
||||
{"label":"import-140","command":["timeout","-k","10","900","node","--test","packages/cli/tests/launch-account.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gEgp","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.427,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1a2de9540358023f6acb51ab8cdfe0f56e21331cca06ecef672fe7e9b1e0b43a"}
|
||||
{"label":"import-141","command":["timeout","-k","10","900","node","--test","packages/cli/tests/launch-limit-checks.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gxqf","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.398,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"027fb83eb3ef68f01fde4e1a272faf569516372f194e3e8404973756f9ffb974"}
|
||||
{"label":"import-142","command":["timeout","-k","10","900","node","--test","packages/cli/tests/launch-limits.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g5N5","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.255,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a3c26a3f092d8e7dd96fe1addfcd77b89d726d027e9f988340a1442823644c3c"}
|
||||
{"label":"import-143","command":["timeout","-k","10","900","node","--test","packages/cli/tests/launch-routes.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gMhQ","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.514,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ba0335e2efd7de694b51ca89b427ffb06b652f6d9757df1997f9c1c7703ac74a"}
|
||||
{"label":"import-144","command":["timeout","-k","10","900","node","--test","packages/cli/tests/launcher.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqhv","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":45.769,"mutant":false,"tests":34,"pass":34,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"5e5374884901f29432961198070f3ede2f87fcc41a818423c3cb90c919dfd7d0"}
|
||||
{"label":"import-145","command":["timeout","-k","10","900","node","--test","packages/cli/tests/lifecycle.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g76b","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":16.885,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"37c3dcc1555bc527fe0f853c1a08bae993bd541143c3b6f7edc360c0c3c26d8d"}
|
||||
{"label":"import-146","command":["timeout","-k","10","900","node","--test","packages/cli/tests/limits-tokens.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g7dV","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.224,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6dae4cd3607f44b07df6a5e6764276a2ef152b892f050340d6defd14a83b731e"}
|
||||
{"label":"import-147","command":["timeout","-k","10","900","node","--test","packages/cli/tests/limits.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gLVw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.442,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"efe051216bb6347423f556f8951c6b6c4adf9c266d8fde6fedfbebb3e678c17f"}
|
||||
{"label":"import-148","command":["timeout","-k","10","900","node","--test","packages/cli/tests/mark-read.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gVQ4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.266,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b90e024010c9a6fbded17306d01b78b2f5748167f9dd4fee20bc5775ef72de81"}
|
||||
{"label":"import-149","command":["timeout","-k","10","900","node","--test","packages/cli/tests/names.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJL7","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.297,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b8d4005cb4e0f1acbe89bc6427b952459b2b876f54c1ed031a558789b535e87e"}
|
||||
{"label":"import-150","command":["timeout","-k","10","900","node","--test","packages/cli/tests/notifier.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gSos","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.033,"mutant":false,"tests":27,"pass":27,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c7156a9c99f99c3b51da2c73b728349f348dac6a0b0530bda96212a848014f7c"}
|
||||
{"label":"import-151","command":["timeout","-k","10","900","node","--test","packages/cli/tests/optional-tracker.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/ggn7","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.413,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d09457d3034c683bc98639f04d83d5348815571d46d5c30cbe055aed5ceef3a7"}
|
||||
{"label":"import-152","command":["timeout","-k","10","900","node","--test","packages/cli/tests/other-tree.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gclm","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.3,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"aa7be88cd823a44c8743159006f1d9b61072ebaa04935339d4a875d0997f903e"}
|
||||
{"label":"import-153","command":["timeout","-k","10","900","node","--test","packages/cli/tests/processing-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gvyI","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.367,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"55d67187192edfd5c929713af6a8f40025259429f36a444eb886fd26013a3135"}
|
||||
{"label":"import-154","command":["timeout","-k","10","900","node","--test","packages/cli/tests/project-name-repo.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g3qR","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.431,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9e8364d68d732dbcb9e518ff8dc1cb957d0d254c0a3821711df20e34f6427f07"}
|
||||
{"label":"import-155","command":["timeout","-k","10","900","node","--test","packages/cli/tests/project.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJK9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.908,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7014e206c70053c2eaeb89fa59b38781802e65d2982fee3855772dd9721285a6"}
|
||||
{"label":"import-156","command":["timeout","-k","10","900","node","--test","packages/cli/tests/publish-socket.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQ5m","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":11.807,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e20a380f9e0e0070d2598bd3ae85679f70f59c92e6f8cf1c7c840a0975c253b7"}
|
||||
{"label":"import-157","command":["timeout","-k","10","900","node","--test","packages/cli/tests/reply-limits.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gR4L","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.167,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9339298bbd5ebfb0e033d2b992c69f62c168e124e741bfc0de500c35b8ffc092"}
|
||||
{"label":"import-158","command":["timeout","-k","10","900","node","--test","packages/cli/tests/revoke-window.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHpa","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.868,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"774c1211e7dadeab526d34d50b143c1141ee9f85e3799b644734eeb78c8e9b6f"}
|
||||
{"label":"import-159","command":["timeout","-k","10","900","node","--test","packages/cli/tests/session-clear.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gd9q","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":13.609,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a47caf45da848c1bf1a8456eb89c213df981229dc0765362573ec82e6701b11c"}
|
||||
{"label":"import-160","command":["timeout","-k","10","900","node","--test","packages/cli/tests/session-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gXLB","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.323,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"3d260701a0c4afd1d21effb5ca1db6cdb47803281bde2536853926f56a236955"}
|
||||
{"label":"import-161","command":["timeout","-k","10","900","node","--test","packages/cli/tests/session-launch.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPoX","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":12.34,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9d077d5e2956b1f40de6abba79ebed6504cc61a3821754526a032231e8697271"}
|
||||
{"label":"import-162","command":["timeout","-k","10","900","node","--test","packages/cli/tests/stack-copy.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gb3j","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":32.255,"mutant":false,"tests":18,"pass":18,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a31fda44310b53fcbfbfb5ca037db8bf9209a0235ed951a911358c61c5f4d13b"}
|
||||
{"label":"import-163","command":["timeout","-k","10","900","node","--test","packages/cli/tests/stack-instances.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gVU0","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.223,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"baf388164839b10a5ea8c3e019d6b5095d7951657ee638784701848b69a160cd"}
|
||||
{"label":"import-164","command":["timeout","-k","10","900","node","--test","packages/cli/tests/tester-http.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/geku","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.28,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d06f4abf2476d898d85533318fee23bdfe3fdc6012c40e809ae4f21e1d6e74bb"}
|
||||
{"label":"import-165","command":["timeout","-k","10","900","node","--test","packages/cli/tests/tester-reads.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g7PM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.141,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2f293f7b23b679733870b5d5d2f666570b56fa1335d5b94590046447433225c8"}
|
||||
{"label":"import-166","command":["timeout","-k","10","900","node","--test","packages/cli/tests/tester-threads.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gAdD","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":12.373,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6505ae90432cfcf6c2b74ed4c22ebe6ee1b26055b41f3fdada4e40c54e1124f9"}
|
||||
{"label":"import-167","command":["timeout","-k","10","900","node","--test","packages/cli/tests/tester.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gx0E","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.628,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"abadf2326205ea5ba1e617fd174018995de824d1552f308815e2bc9c3f71e4bc"}
|
||||
{"label":"import-168","command":["timeout","-k","10","900","node","--test","packages/cli/tests/thread-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbFa","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.076,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fc7f5fadded9b52bcebcf80af32a54bfcb85c2a58608e261d839e8c91d473ce4"}
|
||||
{"label":"import-169","command":["timeout","-k","10","900","node","--test","packages/cli/tests/thread-launch.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQNn","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":36.824,"mutant":false,"tests":15,"pass":15,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f4052bf907e300dae2a7d44f3e8b370849e879abf1de9f84e0c74138f41f2640"}
|
||||
{"label":"import-170","command":["timeout","-k","10","900","node","--test","packages/cli/tests/thread-revoke.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gNtT","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.273,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2f66b678922916e9856a6ade3a4524c420d981f39548a6687df77cb95c660d40"}
|
||||
{"label":"import-171","command":["timeout","-k","10","900","node","--test","packages/cli/tests/trackers-boot.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/giDk","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.097,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"dbb78cab0545fe2d18089c4510092562aa5bc16cdc3f1f95784719d8e2dda241"}
|
||||
{"label":"import-172","command":["timeout","-k","10","900","node","--test","packages/cli/tests/transport.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g6h3","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.447,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7b7a41c111670e869d5156d3714a33c7a4e7a675893cff4767c505b658ac0dc8"}
|
||||
{"label":"import-173","command":["timeout","-k","10","900","node","--test","packages/cli/tests/usage.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gERb","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.44,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d39ae2e64f3e78a0d4bd7fc8d4c6f8f087ac80f0ba47d5dbd199d627d826e86f"}
|
||||
{"label":"import-174","command":["timeout","-k","10","900","node","--test","packages/cli/tests/verbs.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gaL4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.562,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6eafbcea30d6c03a2f8dd925ca6b801fb7f2a8475f3b70715ad8a5060f47f0f0"}
|
||||
{"label":"import-175","command":["timeout","-k","10","900","node","--test","packages/harness/tests/bundle.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g8v2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.276,"mutant":false,"tests":22,"pass":22,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"232cba86e5cf956c07e7ac3bce916899fd288db2ef252bf33041c54fa29f6e1b"}
|
||||
{"label":"import-176","command":["timeout","-k","10","900","node","--test","packages/harness/tests/citation-runner.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g6h4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.327,"mutant":false,"tests":21,"pass":21,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ef0a3e5f582524e0f03a3a39b518356af2d180cefcaa64439c828dbfc9ab0555"}
|
||||
{"label":"import-177","command":["timeout","-k","10","900","node","--test","packages/harness/tests/claude-gate.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmnt","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.62,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2b7867d549382bd5943f9f828f7132743abd724b9d6a26f7e7647e5deac1086c"}
|
||||
{"label":"import-178","command":["timeout","-k","10","900","node","--test","packages/harness/tests/claude-session.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gWex","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.983,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e97d2c71fb63346d736d85b37e1bae38708041a7e09b15cc5d64f44d5f87e592"}
|
||||
{"label":"import-179","command":["timeout","-k","10","900","node","--test","packages/harness/tests/creative.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g7fD","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.349,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0a08749c464113ccbc5207cc63ad3cb33ccd7d7af3ebdcb614106f14a38fa8af"}
|
||||
{"label":"import-180","command":["timeout","-k","10","900","node","--test","packages/harness/tests/gate.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gLqE","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.177,"mutant":false,"tests":12,"pass":12,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"8d3cf0837ecb7d8c5be2a02c67fbe1fb1fbf0a7d75b8e79029a6a3530870353f"}
|
||||
{"label":"import-181","command":["timeout","-k","10","900","node","--test","packages/harness/tests/git-tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcPM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.824,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"170299b738f35a5cbce8336dbf37ddd340045c9f12b0d86716dc9764ce692656"}
|
||||
{"label":"import-183","command":["timeout","-k","10","900","node","--test","packages/harness/tests/mcp-server.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gruQ","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.352,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fcbb8ff07441b7458fad73e8f0d2e8c81a37a184244403c46f0db51bcb579d6c"}
|
||||
{"label":"import-184","command":["timeout","-k","10","900","node","--test","packages/harness/tests/pi-session.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQR8","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.664,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"21ef864f6c0608e398001beed596c711eaa16df9830be6e9948d23adaf7ae19b"}
|
||||
{"label":"import-185","command":["timeout","-k","10","900","node","--test","packages/harness/tests/raise-domain.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gkno","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.289,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"258b03d95708255aaf9c53af130e80349d3fb7a15c412f5e99a552d38d273cf4"}
|
||||
{"label":"import-186","command":["timeout","-k","10","900","node","--test","packages/harness/tests/runner.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHpN","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":14.264,"mutant":false,"tests":40,"pass":40,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6b2ed91f2cc0af529b15da7dd1ca38fc4f9024b8838f1ae948bb9fb61f52b1d4"}
|
||||
{"label":"import-187","command":["timeout","-k","10","900","node","--test","packages/harness/tests/skills.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/ge6l","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.322,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a5eb44bb14feab35f8afff44467dd1ab4b6ccd95f0c20e99bd8165e02ab11e94"}
|
||||
{"label":"import-188","command":["timeout","-k","10","900","node","--test","packages/harness/tests/spec-tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqeF","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.392,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"25bef2391ffce43b2ad8c6159fb801bf371064b48998f5212b45043b78a65ab4"}
|
||||
{"label":"import-189","command":["timeout","-k","10","900","node","--test","packages/harness/tests/tools.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gh6I","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.254,"mutant":false,"tests":23,"pass":23,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"032cd4df77581f65cc3d1e3487b542cc2568e40461f34cf345c9e3ccf224d2c0"}
|
||||
{"label":"import-190","command":["timeout","-k","10","900","node","--test","packages/library/tests/guard.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gX5T","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.7,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c5c5e1daabdcbc4830da5472dc584f3095874effa6ed00a5d752ef5a792f433a"}
|
||||
{"label":"import-191","command":["timeout","-k","10","900","node","--test","packages/library/tests/index-build.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDCo","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.794,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"6122712a2a10cd4fc7ad0f29e7581dc27e6d1e5daddb92dc3b9831ccd26c06b5"}
|
||||
{"label":"import-192","command":["timeout","-k","10","900","node","--test","packages/library/tests/links.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gNyj","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.128,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"933818b92437600be0591b784675887f9240915167a6218d9bd5546737c0de1d"}
|
||||
{"label":"import-193","command":["timeout","-k","10","900","node","--test","packages/library/tests/mapping.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gBnG","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.16,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b97b350865814827ad8998f9a24ea1f65749b882dd10531eb79052268769f9d0"}
|
||||
{"label":"import-194","command":["timeout","-k","10","900","node","--test","packages/library/tests/mirror.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfP9","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.763,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ba91652dd7daa182d771e5f8d093769fa009494d0f4080fd697a423b8c8aff4c"}
|
||||
{"label":"import-196","command":["timeout","-k","10","900","node","--test","packages/library/tests/reader.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gvmz","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.028,"mutant":false,"tests":14,"pass":14,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"5b335d4472ccc9aead596840a67909ccf96270c7ccf88e4ad2141eb5953de74c"}
|
||||
{"label":"import-197","command":["timeout","-k","10","900","node","--test","packages/library/tests/render.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfUA","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.211,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f95a831fa8ef95d90f50861d7ebf05fdedc4d3d68d1ea3dec1e17e9392befab9"}
|
||||
{"label":"import-198","command":["timeout","-k","10","900","node","--test","packages/library/tests/scope.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gxAY","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.368,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"3935e31b852d0be272395f8d2af9816e8b8ee3bf75a088be39559e413d58fd1e"}
|
||||
{"label":"import-199","command":["timeout","-k","10","900","node","--test","packages/library/tests/supporting.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gT0U","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.25,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"cfd46a3aaa0167b3adda75bb69095f6328de4cfd43bdb26ae4952e6867c6bf81"}
|
||||
{"label":"import-200","command":["timeout","-k","10","900","node","--test","packages/library/tests/survey.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQVP","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.764,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a20f9ea4cd570def995d73d389f0610621f0198499e60c8f27ada2e952b22bb8"}
|
||||
{"label":"import-201","command":["timeout","-k","10","900","node","--test","packages/library/tests/sync.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGSr","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.838,"mutant":false,"tests":24,"pass":24,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"683e7b2ec581c2d72a6a3edc68913a7092a49c3ac5c15fe9dfa3062fc3d59fe9"}
|
||||
{"label":"import-202","command":["timeout","-k","10","900","node","--test","packages/processing-control/tests/task.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gAOM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.776,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a9c5e79fa8bddcd222359c6b5fb5634ad170ad56babfe3971f22d8f1fbcaceb9"}
|
||||
{"label":"import-203","command":["timeout","-k","10","900","node","--test","packages/seat/tests/sandbox.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcfc","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.076,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9d9e237b00482d14c1173fcdf2ba0770d87c2e77e0a2d7f8b3631531d1fa5da2"}
|
||||
{"label":"import-204","command":["timeout","-k","10","900","node","--test","packages/seat/tests/session.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gpBq","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.478,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2ffb0ee5961f4611d6afde99fd99270dee783b7abde51c9038ee2087dc426c22"}
|
||||
{"label":"import-205","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/adapter.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/guN4","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.512,"mutant":false,"tests":8,"pass":8,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b0441401e2ab0e9593e6d55cca661366e7ee8b51850ac934bfca23de45d2a35a"}
|
||||
{"label":"import-206","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/comment-restart.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gyAw","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.45,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"599ad621c9d89dc1f200ad0e87eb1573e5ae7bfcc6ff9cddb9048855a9f8613f"}
|
||||
{"label":"import-207","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/fields.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gOij","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.617,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2d83b920f5f716537a69555f6bead6b99be1b3c64751305ec8de1a71cadeb56f"}
|
||||
{"label":"import-208","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/processing.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g72u","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.32,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"5d740844a654055345b9e7c69ed4d2a247cd932ad2a5a6fcf329c7801cbd0ad7"}
|
||||
{"label":"import-209","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/shapes.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJAm","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.518,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"3811bcc866161d152d9460cb8bfef2faa9cd3e533de96f1b3f014403dd7fb51e"}
|
||||
{"label":"import-210","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/startup.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGTN","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.541,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b2c08b276e60a676346a7a7a96423939fc50fece24e84f7d31a141414ae9c65e"}
|
||||
{"label":"import-211","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/sync.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gccq","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.994,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7521b57b037d5dfd35e4e7f8b3e0f772e6f09e9a7f218eaa55a95b40798fb3cb"}
|
||||
{"label":"import-212","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/tree.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gKai","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.129,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"035eba7993242c2797c236e2c7f5d41f9248d872984cbfd785bb596bd323721f"}
|
||||
{"label":"import-213","command":["timeout","-k","10","900","node","--test","packages/tasks/tests/verbs.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gcgn","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.767,"mutant":false,"tests":31,"pass":31,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"27cd7e0bb4607ec39ededdc89e4afcb363698eee6dd31ddd5d5a6b2cbabd847b"}
|
||||
{"label":"import-214","command":["timeout","-k","10","900","node","--test","packages/webui/tests/agents-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gtNR","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":17.433,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"e2c213130dbf80c125011ba8d45c016bfb347ebe1d21f1c64d1756e0db82d6f9"}
|
||||
{"label":"import-215","command":["timeout","-k","10","900","node","--test","packages/webui/tests/agents.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQRO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.233,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c94baa2f42b463dee93e00cf1f3b1e60b287f109debf3a5a5133a8363b992d3a"}
|
||||
{"label":"import-216","command":["timeout","-k","10","900","node","--test","packages/webui/tests/assistant.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gCyc","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.233,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1a32bdca8137c6aff24e9eee5c19dcadfef1e3a5f0aab5a45c600cf39c29e56e"}
|
||||
{"label":"import-217","command":["timeout","-k","10","900","node","--test","packages/webui/tests/board-held.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gPDU","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":10.78,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"fb532481a6401e7097d1b7fd8c858885988e37529779c7e989885dd0de21f7e9"}
|
||||
{"label":"import-218","command":["timeout","-k","10","900","node","--test","packages/webui/tests/browser-edge.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gw0B","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.748,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f23507b59a89ff056564e71cda5e73b275ebc4de3130956b9cf69615af5aebe0"}
|
||||
{"label":"import-219","command":["timeout","-k","10","900","node","--test","packages/webui/tests/browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZfS","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.398,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"08f605ea6cfe1ec7b0f9d1a951a359e2e0106892dc56567152ed569548bff757"}
|
||||
{"label":"import-220","command":["timeout","-k","10","900","node","--test","packages/webui/tests/bus-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gjO2","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.795,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c03e5eaab52ea76d3b5ac1ccfbae6c25a2fab9f592aa45cd29bc6e22f3f45c3f"}
|
||||
{"label":"import-221","command":["timeout","-k","10","900","node","--test","packages/webui/tests/bus.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g766","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.937,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"703208aaab3751971784b6266b335c54f41048735650e92f40b6e8bd37ea9a6a"}
|
||||
{"label":"import-222","command":["timeout","-k","10","900","node","--test","packages/webui/tests/channel-chat.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gyou","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.526,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9dd425b57cb427c25265f7e1b4266cc9d9d09892d2de5ddf4c916635b66515c1"}
|
||||
{"label":"import-223","command":["timeout","-k","10","900","node","--test","packages/webui/tests/chat-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g5ri","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":40.593,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4a751781c8e1b9c4e1bbe9e1767d5d897c3cbb09ac4db39ea25d13c276e947cd"}
|
||||
{"label":"import-224","command":["timeout","-k","10","900","node","--test","packages/webui/tests/chat-instances.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gypj","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.248,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c43f61b93bbf092d23c0bfe9c6e85b76e4ded17b18d973c4a37832764df71f72"}
|
||||
{"label":"import-225","command":["timeout","-k","10","900","node","--test","packages/webui/tests/chat-replies-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDNY","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.751,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f919fe31839c0bc40d4860c4f4412480a1016267c00b292fead32b36098031d5"}
|
||||
{"label":"import-226","command":["timeout","-k","10","900","node","--test","packages/webui/tests/chat-sessions-access.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g9LK","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.741,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a4c4116cfd2a752d7efd2897430a9b2b052b6acf868c1ca8ce26b81ba9585812"}
|
||||
{"label":"import-227","command":["timeout","-k","10","900","node","--test","packages/webui/tests/chat.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/go2w","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.849,"mutant":false,"tests":30,"pass":30,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"77d6c675d0a4534e84f4b2ce4eddf2135908dc5014469e74b87b6fdd3f63c130"}
|
||||
{"label":"import-228","command":["timeout","-k","10","900","node","--test","packages/webui/tests/conversation.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/ga85","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.852,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"35d962e50a5a143e4dd8b816414c3044096d8907e807f50ca72eef81df9531ee"}
|
||||
{"label":"import-229","command":["timeout","-k","10","900","node","--test","packages/webui/tests/decide-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gd1n","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":12.017,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"559586deeaa79f7f28185318bf29e7ea28b4536c60bddbfdcdd337850104820a"}
|
||||
{"label":"import-230","command":["timeout","-k","10","900","node","--test","packages/webui/tests/decide-sso.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gTYk","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.998,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f277b7937f563610c111f75d55917ba1a6474b0cbf7edcc417f66ca1db9e77a8"}
|
||||
{"label":"import-231","command":["timeout","-k","10","900","node","--test","packages/webui/tests/decision-http.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gesP","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.149,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1ae4314867f3da3d96bb8bd99bb9e4bb120610e4b4f76f266a4394d2c4cdac3d"}
|
||||
{"label":"import-232","command":["timeout","-k","10","900","node","--test","packages/webui/tests/discord.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gROh","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.126,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d1da3a8a99ae68e4e2c704b993c9f4fac1502f60dc21502abadad75584e212f1"}
|
||||
{"label":"import-233","command":["timeout","-k","10","900","node","--test","packages/webui/tests/docs-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gZtM","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.892,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b126c48278cbe8276b5a1459b14cf00d1047ec686a80a82dfe509169e4d8aa7c"}
|
||||
{"label":"import-234","command":["timeout","-k","10","900","node","--test","packages/webui/tests/editor-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gJnO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":23.444,"mutant":false,"tests":16,"pass":16,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1053f032713f4a82d05003347cb02c6db54f6c554d3d549608615e3dcc835c83"}
|
||||
{"label":"import-235","command":["timeout","-k","10","900","node","--test","packages/webui/tests/editor.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gLje","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.017,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"a1b78738684b0e0049cc5731f55b67cc21d83c0bd117a20ee094efcefbc926b9"}
|
||||
{"label":"import-236","command":["timeout","-k","10","900","node","--test","packages/webui/tests/granted-user.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gH8T","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.001,"mutant":false,"tests":19,"pass":19,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"7e778058c0b4dfc5a44b1c95d146e3628f1401f18e5ca68d0eb5a2af2357fe16"}
|
||||
{"label":"import-237","command":["timeout","-k","10","900","node","--test","packages/webui/tests/history-return-flow.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gOZs","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":56.725,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1e74c166baa23c019edac72a0ce2735e7804112369ef6f6d12b4b30e0ed1a7a1"}
|
||||
{"label":"import-238","command":["timeout","-k","10","900","node","--test","packages/webui/tests/instances-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/goix","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.608,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"20da30c92fc5b9149e84cd2547aceac366f5509e8efbeb346b700d6f8cacc18b"}
|
||||
{"label":"import-239","command":["timeout","-k","10","900","node","--test","packages/webui/tests/instances.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gr2y","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.265,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"0b0782580df886f98f4428ad6f94d33fa2d37d89c58d12c152964b26786d48fe"}
|
||||
{"label":"import-240","command":["timeout","-k","10","900","node","--test","packages/webui/tests/library-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGV8","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.868,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1e3617d918b4d7474e1acf9b5ad32732305aa86f8ad3044d488aac21f551cb4e"}
|
||||
{"label":"import-241","command":["timeout","-k","10","900","node","--test","packages/webui/tests/library-routes.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gWxL","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.532,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d9729aef19f819e8190e6fdc9dbb1d7c4061f2311598f3785678cc81fbaea30e"}
|
||||
{"label":"import-242","command":["timeout","-k","10","900","node","--test","packages/webui/tests/library-status.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gurC","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.265,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"99e68ba123769f5df8b60d9d12546d113f9f1f18f27b26a82738f4ac670fc18f"}
|
||||
{"label":"import-243","command":["timeout","-k","10","900","node","--test","packages/webui/tests/limits-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gq0e","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.598,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4d3b961b33557106779e969bdfb9aa959e01462a521d5368d9e7e560a4bab19b"}
|
||||
{"label":"import-244","command":["timeout","-k","10","900","node","--test","packages/webui/tests/limits-route.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gK8P","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.561,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2283f78868a29c6ebf37b0aaabc2fdfd84d0a381b3fd046d27902adf2710bfae"}
|
||||
{"label":"import-245","command":["timeout","-k","10","900","node","--test","packages/webui/tests/messages.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gaaW","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":6.474,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"c2e137bf0cc8d12832a07cdb1f70f95dd3cc8ce34a500e6b0479f9d94bf4b300"}
|
||||
{"label":"import-246","command":["timeout","-k","10","900","node","--test","packages/webui/tests/pinned-copy.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gG1M","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":7.925,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"ebeca41fa26f042b9e877ddc3315254a60f98b947fb3eb9ccf098c4d455117b4"}
|
||||
{"label":"import-247","command":["timeout","-k","10","900","node","--test","packages/webui/tests/preview.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHU1","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.186,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4f0064f793bb36dbdf294fe77d67530afc0aea22f01b847aa1d00c3844469119"}
|
||||
{"label":"import-248","command":["timeout","-k","10","900","node","--test","packages/webui/tests/processing-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gkgO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.863,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"816a885bb9c45578982d7e43326cb77215e8cb29f557aa06e0efc39a26297e05"}
|
||||
{"label":"import-249","command":["timeout","-k","10","900","node","--test","packages/webui/tests/processing.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gMEO","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.36,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"d0d8b5325152e1919b5838bfd1b83c4551b52d69c60f07d0921eb95af6391222"}
|
||||
{"label":"import-250","command":["timeout","-k","10","900","node","--test","packages/webui/tests/project-file.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g0K1","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.316,"mutant":false,"tests":10,"pass":10,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"52754ce30568e4d818370c3558342ab23d1292a67f692c1ded6a4d4b4121a029"}
|
||||
{"label":"import-251","command":["timeout","-k","10","900","node","--test","packages/webui/tests/project-name-repo.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gRNU","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.132,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"324df0e70027674e99303723c75b02402d6ae43aefc73192e6c723644952fe98"}
|
||||
{"label":"import-252","command":["timeout","-k","10","900","node","--test","packages/webui/tests/proof-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gUya","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.557,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9d0379c0dac670ea3b54331afee0d9da9c4c76a9c62315bd7cdf33458708b9b1"}
|
||||
{"label":"import-253","command":["timeout","-k","10","900","node","--test","packages/webui/tests/proof.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gw3P","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.23,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"4b564ec494d8631518bd5e0a9dafce3492cc3655e90a82f12bc994fb0f48f017"}
|
||||
{"label":"import-254","command":["timeout","-k","10","900","node","--test","packages/webui/tests/reads.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDRG","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.251,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"acd0a107da0270ad86ea4e75d1af8089f2541e1aa1c1613c10c35f47fcc38dea"}
|
||||
{"label":"import-255","command":["timeout","-k","10","900","node","--test","packages/webui/tests/relaunch.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gDNA","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.062,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b717bc82d68a804092878b6f68c73d970519d5dde6d9170a5cc3f417cd108c66"}
|
||||
{"label":"import-256","command":["timeout","-k","10","900","node","--test","packages/webui/tests/return-flow.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/go3N","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":21.066,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"61fa95c4b8c802668f2b144954e8785c1a5d6e5f8d511646c61ae51abfcf899c"}
|
||||
{"label":"import-257","command":["timeout","-k","10","900","node","--test","packages/webui/tests/room-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/geyH","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.015,"mutant":false,"tests":9,"pass":9,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"65cd71916ae9b8b6a8d47a0175d5cca96ed6c3d93d65ea334338cc651c3529e7"}
|
||||
{"label":"import-258","command":["timeout","-k","10","900","node","--test","packages/webui/tests/room-http.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gfgT","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.284,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"32d8f63c7cbf6a67265e3ebb08eeda185061a94d2674c9e79da3e5ec9348ffaa"}
|
||||
{"label":"import-259","command":["timeout","-k","10","900","node","--test","packages/webui/tests/routes-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gqwx","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.226,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"915d721ef9ebb84e963f021957955ce02a7603a048fde2ba61bd7f87e70137ae"}
|
||||
{"label":"import-260","command":["timeout","-k","10","900","node","--test","packages/webui/tests/routes.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gULI","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.499,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"f5cb0cbb1428122e4a826ebf11a304123af5e33696dc7c3c6e9a40105a7f59b5"}
|
||||
{"label":"import-261","command":["timeout","-k","10","900","node","--test","packages/webui/tests/send-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gV7T","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":14.209,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b76ab6c25710827dc2e6c7231b3aa82259cce1a88174a33f83a45c251ff4e8cf"}
|
||||
{"label":"import-262","command":["timeout","-k","10","900","node","--test","packages/webui/tests/send.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbPv","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.077,"mutant":false,"tests":13,"pass":13,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"51a759891344d96c63d9d554c0b0a0cb541acca3d3d139170805723a90f83201"}
|
||||
{"label":"import-263","command":["timeout","-k","10","900","node","--test","packages/webui/tests/serve.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g9AU","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.835,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"38c0c60b3b161bcd2cc3642f551fafd755e7ff57aa3a1f9cfc4329f0333ade9d"}
|
||||
{"label":"import-264","command":["timeout","-k","10","900","node","--test","packages/webui/tests/settings-form.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gp5I","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.17,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"305e2081fd87ffad6bae81ef0ea0a7732f9208a0fcd6ea73c8604de13af86210"}
|
||||
{"label":"import-265","command":["timeout","-k","10","900","node","--test","packages/webui/tests/settings-write.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gQmT","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.2,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"604a5dfa84401b569a004ca35182684d0aefda4da8a34c833953c15d8047c238"}
|
||||
{"label":"import-266","command":["timeout","-k","10","900","node","--test","packages/webui/tests/shell.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/goIy","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.597,"mutant":false,"tests":5,"pass":5,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"aa8226cc8ad92136f875f3a976de37dfc1b0ab30a3c24f2861c34fcd6355d002"}
|
||||
{"label":"import-267","command":["timeout","-k","10","900","node","--test","packages/webui/tests/sso-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gxVE","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.875,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"37b3e8ed9a38b6a66600fee9386b5a414d6179a8630349c6f695075c1fb29806"}
|
||||
{"label":"import-268","command":["timeout","-k","10","900","node","--test","packages/webui/tests/sso.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gsiS","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":8.274,"mutant":false,"tests":28,"pass":28,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2f286ac4644f8789c2ede5261362f4c57bcf02b84671e9b6c2f5c2994368bfbe"}
|
||||
{"label":"import-269","command":["timeout","-k","10","900","node","--test","packages/webui/tests/tester-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g7am","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":4.164,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"92727a4aee749943dc100d1b843f848ef75bbeeda29d693217882c71368c4d42"}
|
||||
{"label":"import-270","command":["timeout","-k","10","900","node","--test","packages/webui/tests/tester-cli.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gz1T","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":11.668,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"1c952ee8767467b1d1d4306e566b9b0f863d68215d30ae8ed3ab46d75ef46e8a"}
|
||||
{"label":"import-271","command":["timeout","-k","10","900","node","--test","packages/webui/tests/tester-listener.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g99a","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":2.294,"mutant":false,"tests":11,"pass":11,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"b07648c44f522c5fa789c03634f248f63e8d312e9b93b7edd90d7951145d5419"}
|
||||
{"label":"import-272","command":["timeout","-k","10","900","node","--test","packages/webui/tests/tester-socket.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gbnC","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.19,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"61704160b72bcd47d1e4166371e3ff65b148b7ef02b785f9427ef133d5ecdfb6"}
|
||||
{"label":"import-273","command":["timeout","-k","10","900","node","--test","packages/webui/tests/thread-claims-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gGv0","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.008,"mutant":false,"tests":6,"pass":6,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9d3d03d3fc2a108a5e1da2c8e153db2a21bc1e08b207698e9c8eb242dff9905a"}
|
||||
{"label":"import-274","command":["timeout","-k","10","900","node","--test","packages/webui/tests/thread-claims.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g09J","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.423,"mutant":false,"tests":4,"pass":4,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"2b031497a6d9d4b18d215d28bc04de28fe26a800c5a7d54af8052aab35eee3be"}
|
||||
{"label":"import-275","command":["timeout","-k","10","900","node","--test","packages/webui/tests/thread-sharing.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gmhU","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":3.736,"mutant":false,"tests":7,"pass":7,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"9f7b307edc31c95fac9ce71f39ea02466a40a6d80c70d9db91f433a07e19adb7"}
|
||||
{"label":"import-276","command":["timeout","-k","10","900","node","--test","packages/webui/tests/usage-browser.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/g1rW","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":1.032,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"819697b7c5cb3918c007b9fe57dd3f101c79afb9b5656905e5e1e1b0bc82de9f"}
|
||||
{"label":"import-277","command":["timeout","-k","10","900","node","--test","packages/webui/tests/usage.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHnS","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.238,"mutant":false,"tests":2,"pass":2,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"555da950dacca5dc85db7172b50aaef5e50e726c6e30bb66c770c0c38d58ab76"}
|
||||
{"label":"import-278","command":["timeout","-k","10","900","node","--test","packages/webui/tests/user-option-swap.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gx24","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":0.38,"mutant":false,"tests":1,"pass":1,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"20bcc3985f5808a2d7f8daa02c5438fbac81c5163c117fde07bea3f46e8fa5b3"}
|
||||
{"label":"import-279","command":["timeout","-k","10","900","node","--test","packages/webui/tests/views.test.mjs"],"TMPDIR":"/mnt/storage/scratch/tmp/gHJv","start_nice":19,"observed_timeout_nice":19,"exit":0,"seconds":5.483,"mutant":false,"tests":3,"pass":3,"fail":0,"cancelled":0,"skipped":0,"todo":0,"log_sha256":"dd69767c233e8eaeeb85ddaaf274380bbb6df73ec6cc7aaaadc6336053e4ddd8"}
|
||||
```
|
||||
|
||||
Exact mutant edits (temporary only, all restored):
|
||||
|
||||
```text
|
||||
{"mutant":"M1","edits":[["const SCOPES = Object.freeze(['canon', 'playground', 'supporting']);","const SCOPES = Object.freeze(['canon', 'playground']);"]],"path":"packages/library/src/query.mjs","oracle":"supporting find/search/get","killed":true,"restored_clean":true}
|
||||
{"mutant":"M2","edits":[["file.scope !== requestedScope || ",""]],"path":"packages/library/src/query.mjs","oracle":"get without scope returns null","killed":true,"restored_clean":true}
|
||||
{"mutant":"M3","edits":[["import { listTree } from './reader.mjs';","import { listTree, headCommit } from './reader.mjs';"],["listTree(source.repo, index.commit)","listTree(source.repo, await headCommit(source.repo))"]],"path":"packages/library/src/query.mjs","oracle":"each get blob equals its served tree object","killed":true,"restored_clean":true}
|
||||
{"mutant":"M4","edits":[["}).sort((a, b) => SCOPE_RANK[index.files.get(a.path).scope] - SCOPE_RANK[index.files.get(b.path).scope]);","});"]],"path":"packages/library/src/query.mjs","oracle":"full outgoing and incoming links stay in scope order","killed":true,"restored_clean":true}
|
||||
{"mutant":"M5","edits":[["return other !== undefined && sees(index.mapping, universe, other);","return other !== undefined && other.scope === requestedScope && sees(index.mapping, universe, other);"]],"path":"packages/library/src/query.mjs","oracle":"full outgoing and incoming links stay in scope order","killed":true,"restored_clean":true}
|
||||
{"mutant":"M6","edits":[["file.scope === scope && sees(index.mapping, universe, file)","file.scope === scope"],["other !== undefined && sees(index.mapping, universe, other)","other !== undefined"]],"path":"packages/library/src/query.mjs","oracle":"full outgoing and incoming links stay in scope order","killed":true,"restored_clean":true}
|
||||
{"mutant":"M7","edits":[["scopeArg(scope, MANUSCRIPT_SCOPES)","scopeArg(scope, SCOPES)"]],"path":"packages/library/src/query.mjs","oracle":"manuscript still refuses supporting","killed":true,"restored_clean":true}
|
||||
{"mutant":"M8","edits":[["'library.get': { method: 'get', fields: ['universe', 'path', 'scope', 'from', 'links_from']","'library.get': { method: 'get', fields: ['universe', 'path', 'from', 'links_from']"]],"path":"packages/bus/src/broker.mjs","oracle":"broker forwards supporting scope","killed":true,"restored_clean":true}
|
||||
{"mutant":"M9","edits":[["const manuscriptScope = str(\"canon by default; playground is opt-in\", { enum: [\"canon\", \"playground\"] });","const manuscriptScope = str(\"canon by default; playground is opt-in\", { enum: [\"canon\", \"playground\", \"supporting\"] });"]],"path":"packages/harness/src/tools.mjs","oracle":"scope schemas expand only find/search/get","killed":true,"restored_clean":true}
|
||||
```
|
||||
|
||||
Sweep summary:
|
||||
|
||||
```text
|
||||
{
|
||||
"root_count": 289,
|
||||
"matches": []
|
||||
}
|
||||
```
|
||||
|
||||
## sage-4310 — row329 landed-base rebase, 2026-10-24
|
||||
|
||||
Branch della/row284-r4 rebased the six commits in 95d4991d2..315e9c84f
|
||||
onto origin/refactor 9e2689dffb24c9881724b67db982bc87d527157f. Old branch
|
||||
della/row284-r2 and its crash handoff remain unchanged. No conflict hunks
|
||||
occurred: Git replayed all six commits automatically; range-diff marks all
|
||||
six patches equal. Thus no manual conflict resolution was required.
|
||||
|
||||
Inspected broker.mjs against the new base: the sole row284 delta adds scope
|
||||
to library.get fields. Row329 proxy verbs and all other base broker code
|
||||
are retained unchanged. No optimization or review-note behavior change added.
|
||||
|
||||
The new eight-path seal is stored outside Git in
|
||||
/mnt/storage/scratch/della-row284-r2-evidence/manifest-r4.txt with sibling
|
||||
manifest-r4.blobs.txt and range-diff-r4.txt. Base, final candidate tip and
|
||||
manifest digest are in seal-r4.txt beside them (avoids a self-referential
|
||||
BUILD hash). Prior test/mutant results above apply to the prior base only;
|
||||
no test, mutant, Node, syntax check, dependency install or queue command
|
||||
was run for this rebase. Explicit sage-4310 authorizes this untested push.
|
||||
Worker runs and Sage landing gate wait for CLEAR after Webby delta review.
|
||||
@@ -0,0 +1,299 @@
|
||||
# Row 332 — P3 harness config from the model proxy
|
||||
|
||||
## Assignment and boundaries
|
||||
|
||||
2026-10-24: Fethry, thread 65673bd9-3bfa-412b-85d5-9b364187d8b6, branch fethry/row332, baseline c8a9bcf94. Sage assignment sage-4292; accepted brief plus full pi-routes amendment c8a9bcf94 (mos-1616). Gladstone first review, Dewey landing review; landing waits for P1/329 and P2/331, rebase on both and Sage's gate. No tests before Sage's CLEAR. No live proxy, host credential directories, real proxy data, management key, cutover, policy edits, or Codex harness changes.
|
||||
|
||||
Queue next in canonical checkout returned `nothing` during assignment. Starting row with op fethry-332-start met Sage's queue update lock; retry through the queue only. Root npm ci --ignore-scripts --no-audit --no-fund completed in this worktree (128 packages); no canonical node_modules use.
|
||||
|
||||
## Design note (line numbers at c8a9bcf94)
|
||||
|
||||
- packages/seat/src/session.mjs:242-247 defines ENV_ALLOW; keep it unchanged. sessionEnv:256-262 gains optional proxy context and drops CLAUDE_CODE_OAUTH_TOKEN, every passed ANTHROPIC_* variable, OPENAI_API_KEY, OPENROUTER_API_KEY and ZAI_API_KEY before adding harness env. Non-proxy results retain current behavior exactly.
|
||||
- packages/plugins/harness/claude-code/index.mjs:56-67 preflight accepts the session proxy credential; env:119-126 sets ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN from that context.
|
||||
- packages/plugins/harness/pi/index.mjs:33-36 preflight requires its own provider credential or proxy key, never a Claude OAuth token. env:63-70 sets only the session's proxy key as ANTHROPIC_API_KEY and selects the generated provider. Fresh run-local home/.pi/agent/models.json is private (0600; parent directories 0700). Every apiKey is the literal reference $ANTHROPIC_API_KEY; recursively forbid values beginning with !. Nothing stores the key in models.json or a manifest.
|
||||
- packages/harness/src/bundle.mjs:313 buildBundle accepts transient proxy context; :379 harness.env call needs it plus run location and launch.models. Context must never be added to session metadata, source digests, or manifest. The run-local file regenerates on each launch.
|
||||
- packages/cli/src/launcher.mjs:391,400 preflight, :412 account checks, :529 bundle creation and :592 child env must agree on the same session credential. Coordinate its acquisition with P2; build/test now against the specified { baseUrl, key } stand-in, not a management client or a key-store implementation.
|
||||
|
||||
Exact business setting keys remain launch.models.<selection>.provider, launch.models.<selection>.model, launch.account.name and launch.account.credential (launch.mjs:12-24,81-89). Provider already accepts proxy. Proposed account credential sentinel is the literal proxy (add alongside existing uppercase environment-set syntax), with launch.account.name a human-readable id such as proxy. No new fields. Existing provider anthropic selects the Anthropic route, zai selects GLM, and proxy selects the stack-owned GPT route; send this interpretation to Sage before implementation because the brief doesn't specify route encoding for provider proxy.
|
||||
|
||||
## Build-time API choice and pinned binary
|
||||
|
||||
P1's committed magica/row329 has CLIProxyAPI 8.0.42 in packages/model-proxy/PIN. Use that commit's fetchPinned({dataRoot:<fresh temporary root>}) implementation, copied from Git objects to this seat's temp tooling directory with its relative dependencies and PIN, until P1 lands. Never inspect another seat's worktree/scratch. It fetches only pinned GitHub release assets and checks archive, executable and panel hashes. No production instance config is needed and nothing under a real dataRoot/proxy is read.
|
||||
|
||||
After CLEAR, try actual pinned pi requests with both openai-responses and openai-completions through that binary under unshare -rn, against stand-in upstreams with made-up credentials under 24 characters. Record version, API path, safe request fields, response status and turn result. Choose one shape once from those results and hard-code it; no runtime fallback. Real Codex OAuth cannot be simulated as a real authenticated turn: first real Codex turn remains row209 phase A step7. Distinguish the offline compatibility evidence from that deferred real-auth proof.
|
||||
|
||||
The separate offline GLM acceptance script (outside scripts/test-*.sh) uses pinned pi and proxy, checks the upstream sees the model id from /v1/models, and records whether thinkingFormat/zaiToolStream-derived fields survive translation. All configs/auth placeholders belong to its fresh temp root.
|
||||
|
||||
## Implementation and test sequence
|
||||
|
||||
1. Add tests first for env isolation, Claude proxy env and preflight, pi credential refusal and each generated route/file invariant, and business account acceptance. Do not run until CLEAR; first new-test red is reported afterward, old-test red or second red is reported before changing anything.
|
||||
2. Implement harness/bundle/env handling against P2's transient interface. Add launcher boundary integration once its exact P2 acquisition seam is agreed. Keep secrets out of session.json and bundle manifests.
|
||||
3. With CLEAR, run the offline API-shape probe and GLM turn, then whole touched test files. Before each whole-file run report the list derived by parsing imports and traversing local dependencies; include harness plug-in dynamic loading explicitly. packages/cli/tests/case1-accept.test.mjs remains excluded without Mos approval.
|
||||
4. Kill named mutants; restore production source and verify. Record exact output and nice. Use a fresh shell mktemp -d /mnt/storage/scratch/tmp/XXXXXX TMPDIR for each run, absolute nice 19, and timeout -k 10 for each scripts/test-*.sh. No hidden skips; Sage owns the package/script landing gate.
|
||||
5. After dependency landings, rebase, complete review and gate stages, update queue only through its CLI, and append session/build receipts. Push only fethry/* when ready for authorized review; no force-push or attribution trailers.
|
||||
|
||||
Planned tests:
|
||||
- Each forbidden environment variable is absent in proxy mode; all existing allowed env is identical without a proxy; two launches receive distinct own keys and no other agent's key.
|
||||
- Claude env has exactly the supplied proxy base URL/auth token; proxy credential satisfies preflight without host upstream credentials.
|
||||
- pi refuses no-session-credential for no key or Claude OAuth alone, accepts an own provider key and a proxy key.
|
||||
- models.json covers Anthropic anthropic-messages at root URL, GLM openai-completions at /v1, and a stack-owned GPT provider at /v1 with the chosen API; routes use configured model ids.
|
||||
- Every apiKey is $ANTHROPIC_API_KEY; no key value occurs in file; recursively no value starts with !; mode 0600 and private parents; next launch uses changed port/models/key reference with no stale content.
|
||||
- Business accepts provider proxy and account credential proxy while preserving existing valid and invalid account behavior.
|
||||
- Launcher/bundle integration keeps context transient and passes only the launch's own key.
|
||||
- Every new refusal code gets a separate test.
|
||||
- Offline GLM pinned-pi turn and z.ai compat observation; both GPT API-shape requests recorded with limitations.
|
||||
|
||||
Named gate mutants:
|
||||
1. Proxy mode still passes CLAUDE_CODE_OAUTH_TOKEN (original brief).
|
||||
2. models.json receives the key value instead of $ANTHROPIC_API_KEY (amendment).
|
||||
|
||||
No tests have run. API-shape choice is pending evidence, not claimed.
|
||||
|
||||
## Progress 22:27Z
|
||||
|
||||
Placed initial RED tests (not executed): packages/seat/tests/proxy-session-env.test.mjs and packages/plugins/tests/proxy-harness.test.mjs. These exercise real sessionEnv and loader-loaded harness exports. Production source remains untouched pending the first authorized RED run. Removed no assertions and ran no tests. Correct baseline bundle harness.env line is 376 (not 379 in the initial design note).
|
||||
|
||||
Sage reporting attempts fethry-0001 (including same-key retry) and fethry-0002 all returned `T3 GET /api/orchestration/threads/<sage> timed out after 30s`. Delivery is unconfirmed. Queue move retry also met a Sage queue update lock (sage-333-reviewers-1024a); no bypass.
|
||||
|
||||
Additional test-first placement: packages/business/tests/proxy-launch.test.mjs covers existing proxy model acceptance, proposed proxy account credential literal, preserved environment account forms, and rejection of mixed/literal credential strings. Pending Sage's route/account interpretation and CLEAR; no production edits or tests run.
|
||||
|
||||
## Import audit and queue status
|
||||
|
||||
The non-evaluating import audit uses Node vm.SourceTextModule.dependencySpecifiers, not a text-path grep, plus explicit computed-import edges from the plug-in loader to both harness modules. Source: import-run-list.mjs; output: IMPORT-RUN-LIST.txt (211 entries, including the explicitly EXCLUDED case1-accept file). This is a candidate impact list for the planned source changes, not an executed test list. Before a whole-file run, report the actual authorized subset to Sage. Parsing executes no repository modules and runs no tests. The first audit invocation had a path-depth setup error (ENOENT); corrected the audit's own repository root and regenerated successfully.
|
||||
|
||||
At 22:28:19Z the canonical start operation returned `queue: only the owner (sage) may start row 332`. Per assignment, wait at least two minutes before repeating this same op. No queue state was edited manually.
|
||||
|
||||
## Design correction after D9 re-read
|
||||
|
||||
The initial route-encoding proposal (provider proxy for GPT only) is not sufficient: design D9 explicitly defines provider proxy as any model through the instance proxy. Do not implement the earlier proposal. Two viable encodings need resolving before route-dependent tests/production: exact model-id lookup in pinned pi's provider catalogs (no new business fields, but refuses proxy-only aliases/unknown models), or explicit route metadata in launch.models (additive schema, needs Sage to confirm it is within the approved brief). Recommend exact catalog membership if all intended configured model ids are in pinned pi; otherwise ask Sage to define/approve an explicit route field. Never guess by model prefix or silently choose a wire API. Independent env/preflight tests already placed remain valid.
|
||||
|
||||
Reporting recovered: fethry-0004 was accepted by t3_send_message at approximately 22:29:51Z. It delivered the D9 route correction, route-encoding/P2-seam question, import-manifest location and no-tests status to Sage. Earlier failed-message deliveries remain unconfirmed.
|
||||
|
||||
22:32:18Z: The start retry issued at 22:30:40Z (over two minutes after first owner refusal) also exited 2: `queue: only the owner (sage) may start row 332`. This is an ownership boundary; row was not started and no code/test execution proceeds through it. Sage's assignment must take effect before the same op can succeed. The full design report fethry-0005 again timed out; fethry-0004 is the confirmed delivered report. git diff --check passed; no test, probe, commit or push has run.
|
||||
|
||||
## Route ruling accepted — sage-4293, 22:37Z
|
||||
|
||||
Sage settled explicit metadata, superseding both initial encoding proposals and the catalog proposal. Exact new setting: launch.models.<selection>.route; permitted values anthropic, glm, codex, required only when provider is proxy. Nonproxy entries still allow provider/model only. Missing route refuses proxy-route-missing; present unknown/nonstring route refuses proxy-route-unknown. Both get independent code assertions; each valid value gets a test using a proxy-only model id absent from any catalog. The GPT route's generated pi provider will be mosaic-proxy-codex, never openai-codex. Its wire API remains a build-time choice after the pinned-binary probe. P2 passes only {baseUrl,key}; no route belongs to that seam.
|
||||
|
||||
A key persistence hazard found during source inspection: launcher.mjs:571 writes bundle.env as session.harnessEnv. Adding the key to harness.env must not retain this behavior for credentials. P3 will keep generated key env transient for spawnSession and omit those credential values from serialized harnessEnv. runner.mjs:390 already inherits the spawn environment before applying nonsecret harnessEnv. Test the on-disk session/bundle boundary, not only models.json.
|
||||
|
||||
The old launch-settings.test.mjs already uses provider proxy fixtures without route. Update those fixtures to explicit anthropic routes before any full-file run; preserve their existing authorization assertions. This is the new approved validation shape, not permission to loosen tests. No tests have run and no production edits exist.
|
||||
|
||||
Additional test-first placement after route ruling: packages/harness/tests/proxy-bundle.test.mjs exercises real buildBundle with explicit provider proxy entries and proxy-only model ids, three generated providers, run-local file mode, environment references, recursive no-! values, no key in bundle files/manifest, fresh model/port/key on next launch. The exact GPT API assertion must be added from the authorized pinned-binary probe before this test file's first run; it deliberately makes no unverified wire-shape claim now. No skip is introduced.
|
||||
|
||||
Canonical queue show returned owner sage and after=331 at 22:40Z; it also warned `view unknown` for the rendered table. No repair or queue bypass attempted; wait for Sage's announced batch. Queue metadata identifies shared proxy Gitea issue #1830.
|
||||
|
||||
## STOPPED — mos-1630, 2026-10-24T22:48Z
|
||||
|
||||
Jason's relayed crash instruction supersedes active work: no long-job restart, commit/push safe documentation only, handoff in this worktree, no other thread messages, then stop. See HANDOFF.md for complete state, next steps, uncommitted tests/audit script, and reruns needed. No tests or probes ever ran; no production implementation exists. Latest design is explicit launch.models route metadata per sage-4293; earlier catalog/GPT-only proposals are superseded. The original 211-entry import manifest predates the fourth new test file and is historical, not run authorization. Full inline resends still hit T3 timeouts. Crash commit will exclude every unrun test and the audit script.
|
||||
|
||||
## Resumed — sage-4298, 2026-10-24T23:12Z
|
||||
|
||||
Resume authorized; crash-stop state above is historical. Sage accepts route spellings, refusal codes, mosaic-proxy-codex and launch.account.credential=proxy. Added third named mutant: **proxy key serialized into session.json**. Added an unrun real-launcher integration test in packages/cli/tests/launcher.test.mjs: a stand-in `{baseUrl,key}` enters via proposed createLauncher proxy option; real harness generation, session writer and runner must pass the key transiently while disk session/bundle files omit it. Adapter alone is fake. This catches restoring harnessEnv:bundle.env without credential separation. Existing test assertions are unchanged.
|
||||
|
||||
Regenerated IMPORT-RUN-LIST.txt with the non-evaluating import audit (static module dependencies plus explicit computed harness-loader edges). It now includes proxy-bundle.test.mjs; case1-accept remains explicitly EXCLUDED (mos-1612). Full manifest, touched tests and all three named mutants delivered inline to Sage using t3_code t3_thread_send, clientRequestId fethry-row332-resume-report-001, delivery steered. No unresolved route question remains. GPT API selection awaits CLEAR and pinned-binary evidence. Production implementation remains held for required first RED; tests/probes/fetches remain held for CLEAR. git diff --check clean.
|
||||
|
||||
Canonical queue next fethry started without timeout; no start retry until Sage confirms after-none write. Initial local-worktree queue invocation refused because queue requires canonical checkout; rerouted to canonical as required, no state bypass.
|
||||
|
||||
## Queue start retry — sage-4301, 2026-10-24T23:15Z
|
||||
|
||||
Sage reports after=none at rev4057. Retried canonical `scripts/mosaic queue move 332 in-progress --op fethry-332-start --by fethry` without a timeout. Awaiting its result; no duplicate command or manual queue edit. Lane B remains held and all tests/probes/fetches remain forbidden until CLEAR. Static review of test fixtures confirms launcher test uses the existing real-harness fake-adapter setup; initial RED remains unrun.
|
||||
|
||||
Start result: `ok fethry-332-start rev 4059 row 332 briefed→in-progress` (exit0). No tests/probes/fetches run.
|
||||
|
||||
## P1 rebase and pre-run reader stop — sage-4312/4313
|
||||
|
||||
Rebased onto 9e2689dff; current documentation checkpoint efe3e4697. Saved/restored all uncommitted notes/tests with named stash (retained for recovery). BUILD-LOG.md and SESSIONS.md append conflicts preserve both upstream and row332 entries. No production edits or force-push. git diff --check clean.
|
||||
|
||||
CLEAR received in sage-4313, conditional on pre-step reader check. STOP condition found before any test/probe/fetch: packages/cli/tests/launcher.test.mjs imports ./helpers.mjs, whose line10 imports BusError/Broker from ../../bus/src/broker.mjs (P1-changed path). The P3 test also starts the real broker through startHost. Report delivered to Sage as fethry-resume-0003, clientRequestId fethry-row332-p1-reader-stop. Await specific reader-chain authorization. No runs, counts or mutant outcomes exist. Mutant execution requires implementation reaching GREEN first; baseline RED will not be claimed as mutant evidence.
|
||||
|
||||
## First execution — sage-4316/4319, lane B, 2026-10-24
|
||||
|
||||
Reader chain authorized by sage-4316. Every run below used fresh shell `mktemp -d /mnt/storage/scratch/tmp/gXXX`, absolute nice19 (recorded), timeout -k10 (180s new files/300s whole launcher). No probes/fetches/mutants or case1-accept run. Logs are plain text in red/ beside this note.
|
||||
|
||||
| File | UTC start/end | pass/fail/skip | Classification |
|
||||
| --- | --- | --- | --- |
|
||||
| business proxy-launch | 23:41:37/23:41:37 | 2/4/0 | Expected missing route validation/account support |
|
||||
| harness proxy-bundle | 23:41:42/23:41:42 | 0/5/0 | Fixture ERROR: assignment to frozen resolved.vars, not feature RED |
|
||||
| plugins proxy-harness | 23:41:44/23:41:44 | 0/5/0 | Fixture ERROR: missing createLoader options, not feature RED |
|
||||
| seat proxy-session-env | 23:41:50/23:41:50 | 1/1/0 | Expected instance OAuth leak |
|
||||
| cli launcher (whole) | 23:41:55/23:42:25 | 34/1/0 | New P3 route rejected; all34 old tests pass |
|
||||
|
||||
Per sage-4319, fixed only the two new-file fixtures and committed b285e581e `fixture fix, untested` before rerunning. resolvedFor uses its mutation callback; createLoader receives {log(){}}. Existing launcher assertions were not changed.
|
||||
|
||||
| Corrected file | UTC start/end | pass/fail/skip | Classification |
|
||||
| --- | --- | --- | --- |
|
||||
| harness proxy-bundle | 23:42:41/23:42:41 | 0/5/0 | Another fixture ERROR: pm selects a/z/g absent from fixture launch.models; not valid feature RED |
|
||||
| plugins proxy-harness | 23:42:41/23:42:41 | 1/4/0 | Valid feature REDs: missing Claude proxy URL/key and preflight; pi missing-credential refusals absent. Acceptance test already passes because existing pi preflight only checks binary; not proof of proxy credential behavior |
|
||||
|
||||
Stopped after exactly one authorized corrected run each. No edits/reruns after second harness fixture error; report to Sage before changes. Proposed follow-up: preserve valid fixture business routing, then overlay a test-local resolved vars object for buildBundle, or supply a coherent model table in callback. GPT API assertion still awaits authorized evidence and must precede a GREEN claim.
|
||||
|
||||
Stash created before rebase: 69ad35ec79805a0303ede4454f8d6815ddfa7bb3. Shared refs/stash must not be used again; entry remains untouched for Sage to clear. Future checkpoints use branch WIP commits.
|
||||
|
||||
Own-worktree node/chromium process sweep at23:42:57Z found only six tool-service processes predating tests (started23:12:08–23:12:10Z), no test node/chromium leftovers. Preserved tool services. No process killed. Lane B returned; mutants deferred until RED→fix→GREEN and later CLEAR with tip.
|
||||
|
||||
## Corrected bundle first valid RED — sage-4320
|
||||
|
||||
Only proxy-bundle.test.mjs edited: resolve a valid existing fixture business first, then copy resolved and vars locally, overlay harness/model, and assert selection exists in the supplied declared models table. Frozen original is untouched. Commit56701f715 `fixture fix, untested`, directly atop b285e581e, before execution.
|
||||
|
||||
Exactly one whole proxy-bundle run at23:44:40Z (start/end), fresh gXXX TMPDIR, nice19, timeout-k10/180s: 5tests,0pass,5fail,0skip,exit1. All five now reach real buildBundle and fail ENOENT on the required run/home/.pi/agent/models.json: missing production generation, valid feature RED rather than fixture errors. Earlier frozen-vars and unknown-model errors remain separately recorded. Log red/harness-corrected-2.txt. No production edits, further runs, mutants, probes or fetches. Lane B free.
|
||||
|
||||
Rebase made original origin/fethry/row332 diverge from local; publish current history on fethry/row332-p1 without force, preserving original remote checkpoint. Shared stash69ad35ec79805a0303ede4454f8d6815ddfa7bb3 remains untouched. Remaining uncommitted business/seat tests, launcher addition and audit source are not included in this two-fixture checkpoint.
|
||||
|
||||
## P3 implementation checkpoint — sage-4323/4325, UNRUN
|
||||
|
||||
Scope correction: sage-4322's P1 meant P3; no P1 code changed. Source edits authorized by sage-4323; all runs remain held. This is an implementation checkpoint, not GREEN or acceptance. Executing the established plan inline; user lane restrictions supersede skill test-run/commit defaults for this checkpoint.
|
||||
|
||||
Latest route ruling sage-4325 supersedes sage-4293/4298 and all earlier route-required notes: omitted proxy route means Anthropic and preserves the stored provider/model shape. Explicit anthropic/glm/codex routes remain accepted; unknown/present-invalid route refuses proxy-route-unknown. proxy-route-missing is withdrawn, not implemented. Other providers keep provider/model-only schema. Own business test updated for default; new bundle test exercises default generation without changing existing explicit-route assertions. launch-settings.test.mjs remains byte-unchanged.
|
||||
|
||||
Implementation in six production files:
|
||||
- business launch validates optional proxy route, preserves omission, accepts account credential literal proxy.
|
||||
- seat sessionEnv leaves ENV_ALLOW unchanged and filters provider variables only with proxy context.
|
||||
- Claude accepts proxy credential preflight and returns proxy base/auth env; pi requires own provider key or proxy key, never Claude OAuth.
|
||||
- bundle carries transient proxy/models to harness calls and propagates proxyRoute separately from primary/fallback route; no context in manifest.
|
||||
- pi groups declared routes into run-local private models.json, references only $ANTHROPIC_API_KEY, refuses executable-looking model ids/key collisions, exclusive create and0700 parents/0600 file. No host auth reads. Generated file digest included in bundle manifest. Models use pi's documented default sizes/costs and reasoning support, with explicit z.ai compat for GLM; no catalog membership inference.
|
||||
- launcher accepts the specified context stand-in or a per-agent factory, copies only baseUrl/key, carries it through repeated preflight checks and final bundle/spawn. Factory receives business/instance; P2 owns acquisition and may be called twice due to existing launch recheck. No P2 store/client calls invented. Provider credential variables split out at actual session.json serialization and delivered only through spawn env. Account proxy source validates against the supplied context, not host upstream variables.
|
||||
|
||||
### Old-test changes authorized by sage-4325 (baseline1e47b0919)
|
||||
|
||||
P3 item4 (rows brief pi preflight bullet, lines250-252) mandates refusal without proxy/own credential:
|
||||
- plugins/tests/harness.test.mjs:102 before `assert.equal(pi.preflight({ env: {} }), null)`; after asserts `.code === no-session-credential`. Other assertions unchanged.
|
||||
- cli/tests/launcher.test.mjs prepare():84 before only fake Claude OAuth; after additionally supplies ZAI_API_KEY=fx332-pi only when chief primary/fallback names pi. Other tests' assertions unchanged; Claude-only preparation does not receive it.
|
||||
- cli/tests/launcher.test.mjs old no-credential pi test (sage reference697): before deletes OAuth then expects launch/pi and launch-log event; after also deletes newly supplied fake ZAI key, expects no-session-credential refusal, refused log code and no registered session. Test renamed to reflect mandated behavior. Existing no-session-credential Claude test unchanged.
|
||||
|
||||
No other old test was changed. Static review found these conflicts before execution and authorization preceded edits. No old-test RED occurred; baseline whole launcher had34 old passes.
|
||||
|
||||
### GPT wire API: PENDING
|
||||
|
||||
Single build-time value PROXY_CODEX_API=null in pi/index.mjs. A declared codex route refuses generation with a plain pending-evidence error until that value is settled; no guessed wire API, environment switch or runtime fallback. Consequently existing all-three-route bundle tests are not expected GREEN yet. P2 integration, full tests, pinned evidence, mutants and reviews remain pending.
|
||||
|
||||
Planned separate 4c evidence run (outside scripts/test-*.sh), requiring its own lane B CLEAR:
|
||||
1. Use landed P1 fetchPinned only under a fresh owned temp root for the exact PIN (8.0.42). Fetch is a separately approved preparation, not part of offline networking. Verify hashes via P1; never use host installation or another seat's scratch.
|
||||
2. Run the pinned proxy and local stand-in upstream inside unshare -rn with loopback enabled, empty private HOME/auth dir and a sanitized environment. No real auth file or network. All fake credentials under24 chars. Private test-only proxy config points only at the stand-in.
|
||||
3. Generate two private probe-only pi model configs, one openai-responses and one openai-completions, both baseUrl=the isolated proxy/v1. Run pinned pi turns and record safe path/body shape fields, statuses, stream result and upstream observations, omitting auth/header values. These probe configs do not select the production constant.
|
||||
4. Separately run the GLM completions turn under the same isolation and record whether thinkingFormat=zai/zaiToolStream-derived fields survive proxy translation.
|
||||
5. If the offline stand-in cannot distinguish the two GPT shapes for the Codex-login route, report inconclusive evidence to Sage for Mos; do not select a value. A compatibility route cannot be reported as a real Codex-auth turn. First real Codex turn remains row209 phaseA step7.
|
||||
|
||||
No tests, probes, binary invocation or fetch ran during implementation. Import audit below is source parsing only, never repository evaluation. New run list includes the old harness.test.mjs touched under ruling; case1-accept remains EXCLUDED. Shared stash already cleared by Sage after1e47b0919 confirmation; no further stash operation used.
|
||||
|
||||
## Six whole files on a5330386c — sage-4326 lane B
|
||||
|
||||
Each ran exactly once, in requested order, no edits between runs and no reruns. Fresh shell gXXX TMPDIR per file; every log records nice19; timeout-k10/180s (launcher300s). No mutants/probes/fetches or extra impact files. Logs green-attempt/*.txt.
|
||||
|
||||
| File | pass/fail/skip | exit | UTC start/end |
|
||||
| --- | --- | --- | --- |
|
||||
| business | 6/0/0 | 0 | 23:57:06Z/23:57:06Z |
|
||||
| seat | 2/0/0 | 0 | 23:57:06Z/23:57:06Z |
|
||||
| proxy-harness | 5/0/0 | 0 | 23:57:06Z/23:57:06Z |
|
||||
| harness | 9/0/0 | 0 | 23:57:12Z/23:57:12Z |
|
||||
| proxy-bundle | 1/5/0 | 1 | 23:57:12Z/23:57:12Z |
|
||||
| launcher | 34/1/0 | 1 | 23:57:12Z/23:57:42Z |
|
||||
|
||||
Expected-PENDING failures (each shared declared table includes codex), all stop before assertions with `Error: proxy GPT API is PENDING build-time evidence`:
|
||||
- P3 Anthropic route uses messages at proxy root and the declared model id
|
||||
- P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility
|
||||
- P3 GPT route selects a stack-owned provider instead of pi Codex OAuth
|
||||
- P3 models file is private, references the one session key, and stores no executable values or keys
|
||||
- P3 every launch regenerates proxy port, declared models and own key without caching
|
||||
|
||||
The omitted-route-only bundle case passed. Five pending failures do not establish the remaining route/file assertions; no claim of GREEN.
|
||||
|
||||
Real old-test RED: `row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason` (launcher.test.mjs:714). First expected operation `await launcher.launchPm()` throws before the result assertions: `PM launch refused: no-session-credential (fallback fixture: pi needs its own provider key or a session proxy key (primary down: fixture preflight fails))`. Fixture harness re-exports real pi; prepare() recognized literal pi primary/fallback only, so it did not supply the needed own key. Reported to Sage as fethry-resume-0012 before any edit; no fix or rerun authorized/performed. P3 serialization test and all other launcher tests passed.
|
||||
|
||||
After all runs finished, changed only harness.test.mjs:100 title per sage-4326 to `row 65 pi preflight refuses missing credentials, and its version is the package pin`; assertion unchanged, no rerun for title. Sweep after end23:57:42Z found the same six pre-existing tool services (2699602,2699605,2700525,2700526,2700531,2700931), no test node/chromium leftovers; no process killed. Lane B free. No other source/test fixes in this follow-up.
|
||||
|
||||
## Fixture correction authorized — sage-4327
|
||||
|
||||
Old-test list addition: launcher.test.mjs row65 fallback test (line714 at e9fc105ac), before: no own pi credential before setup; after: this test alone sets given.f.env.ZAI_API_KEY=fx332-pi immediately before setup. All assertions unchanged; prepare() condition unchanged. Reason: P3 item4 requires pi own/proxy credential; this fixture inherits pi preflight. Prior real RED and first thrown error preserved above.
|
||||
|
||||
New proxy-bundle tests now supply explicit per-test declared tables: Anthropic only, omitted/default only, GLM only, GPT only; privacy/regeneration use Anthropic+GLM and retain every key/mode/no-executable assertion applicable to those routes. Regeneration additionally checks changed GLM endpoint/model. Added expected refusal test for declared Codex with pending build-time API; no production source changes. Only GPT generation test should remain expected-PENDING. Fixture fixes committed untested before exactly two authorized whole-file runs.
|
||||
|
||||
### Two-file fixture verification — sage-4327
|
||||
|
||||
Fixture checkpoint f1e8cda07, no source change. Exactly one run each, no edits between runs or reruns. nice19, fresh gXXX TMPDIR per file, timeout-k10/180s bundle and300s launcher. Logs fixture-r3/*.txt.
|
||||
- proxy-bundle23:59:16Z:7tests,6pass,1fail,0skip,exit1. Sole expected-PENDING failure: `P3 GPT route selects a stack-owned provider instead of pi Codex OAuth`, error `proxy GPT API is PENDING build-time evidence`. All other route/privacy/regeneration cases and explicit pending-refusal case pass.
|
||||
- launcher23:59:16–23:59:45Z:35tests,35pass,0fail,0skip,exit0. Row65 fallback assertions unchanged and now pass; P3 transient serialization case passes.
|
||||
|
||||
No failure other than expected GPT generation; GPT wire evidence, P2 integration/rebase, mutants and reviews still pending. Sweep shows only same six pre-existing node/chrome tool services, no test leftovers. Lane B free after23:59:45Z. No probes/fetches/mutants or extra tests run.
|
||||
|
||||
## Route-required correction — sage-4328 restores sage-4293
|
||||
|
||||
sage-4325 default-Anthropic ruling withdrawn. Explicit route required again: missing proxy-route-missing, present invalid proxy-route-unknown, distinct own tests. Removed generation/session-model defaults; bundle omitted-route test now asserts missing-route code. Active plug-in documentation corrected. No catalog/prefix inference.
|
||||
|
||||
Old-test list (baseline1da28a7bd): launch-settings.test.mjs41,154,161,188,198 object fixtures before provider:proxy/model only; after identical objects plus route:anthropic. Line45 before assignment models.opus.provider=proxy; after adds models.opus.route=anthropic. Every assertion byte-unchanged; no assertion relaxed. Authority/reason sage-4293 restored by sage-4328: D9 proxy is any upstream route and omission cannot select Anthropic silently.
|
||||
|
||||
Pre-run git-grep audit scoped 'packages/*/tests/*', saved route-required/proxy-fixture-grep.txt:16 model/assignment lines in four files. Positive controls matched launch-settings41 literal,45 assignment and intentional missing inputs proxy-launch14/proxy-bundle47. Broader quoted-proxy literal audit saved proxy-literal-grep.txt, manually reviewed for multiline entries. Remaining route omissions only intentional refusal cases (proxy-launch14,proxy-bundle47); unknown-route test uses route variable. All six old fixtures explicit; launcher155 and remaining bundle model literals explicit. Other broad hits are account sentinels, CLI argv or filesystem strings, not model table entries. Findings sent inline as fethry-resume-0015 BEFORE any tests. No other missing-route positive fixture found.
|
||||
|
||||
Committed untested per instruction; four whole-file runs follow under lane B CLEAR, no reruns or extra files. GPT offline run and P1 fetch remain unstarted and require separate explicit go.
|
||||
|
||||
### Required-route four-file verification — sage-4328
|
||||
|
||||
Tested9563fbc8b, exactly once per whole file in authorized order. No edits between runs, no reruns/extra tests. Each fresh gXXX TMPDIR,nice19,timeout-k10/180s (launcher300s). Plain logs route-required/*.txt.
|
||||
|
||||
| File | pass/fail/skip | exit | UTC start/end (2026-10-25) |
|
||||
| --- | --- | --- | --- |
|
||||
| proxy-launch | 6/0/0 | 0 | 00:01:47Z/00:01:47Z |
|
||||
| launch-settings | 18/0/0 | 0 | 00:01:55Z/00:01:56Z |
|
||||
| proxy-bundle | 6/1/0 | 1 | 00:01:56Z/00:01:56Z |
|
||||
| launcher | 35/0/0 | 0 | 00:01:56Z/00:02:27Z |
|
||||
|
||||
Only failure: `P3 GPT route selects a stack-owned provider instead of pi Codex OAuth`, expected-PENDING error before assertions: proxy GPT API is PENDING build-time evidence. No other failures; missing-route and unknown-route separate-code tests pass; six old launch-settings fixture metadata changes preserve all assertions. All35 launcher tests pass.
|
||||
|
||||
Sweep after00:02:27Z: only same six pre-existing tool services; no test node/chromium leftovers and no process killed. Lane B free. GPT wire-shape evidence and P1 fetch NOT started; each still needs Sage explicit go/CLEAR. No mutants.
|
||||
|
||||
## GPT offline attempt1 and static diagnosis — sage-4329/4330
|
||||
|
||||
One authorized landed-P1 fetchPinned invocation succeeded, exact PIN8.0.42 executable SHA74661f8cf949977870231359e8bf4344e07946766a673c08fa25a3e5f72fc95e, panel1.26.7 SHA8c9c6b7d3fb311e6aad5d06e1993e53a2d28389e640448a1bc6304ed20b057b5. Fresh owned root named in evidence/root.txt, no alternate binary/new fetch. Fetch entry required nice19, end log observed16 due host renice; disclosed before continuing. Static-inspection invocation then failed entry nice guard before any binary read/launch; no turn. Main isolated attempt1 setPriority19 explicitly, but static binary tag scan again observed host renice16; subsequent child starts explicitly set19.
|
||||
|
||||
Attempt1 unshare-rn showed interfaces[lo], empty private HOME/auth and sanitized env. Proxy booted version8.0.42 commitbc064340, built2026-10-24T14:21:38Z. GET/v1/models response200 with modelIds[], script refused `stand-in routes absent from proxy catalog`; zero GPT-responses/GPT-completions/GLM pi turns ran, so zero compatibility evidence. Cleanup remainingManagedChildren0. No rerun under that CLEAR; reported0018. Raw sanitized receipt evidence/offline.txt preserved.
|
||||
|
||||
Startup network finding for P7/unit, plain text from isolated proxy log:
|
||||
`failed to fetch latest Grok CLI version from npm, keeping fallback/cached version error=npm registry request failed: Get https://registry.npmjs.org/@xai-official/grok/latest: dial tcp [2606:4700::6810:122]:443: connect: network is unreachable`.
|
||||
The namespace blocked external egress. Panel auto-update was disabled; this separate Grok version check still attempted startup egress. No real auth or host proxy touched.
|
||||
|
||||
### Static cause recorded BEFORE attempt2 (sage-4330)
|
||||
|
||||
No executable/probe invocation for diagnosis. Read the hash-pinned bundled management.html's config reader/serializer and P1 initialConfig in packages/model-proxy/src/settings.mjs. P1 produces nested server/management/access/oauth/observability/routing but adds no upstream provider config. Bundled panel Ip explicitly reads `api-keys.openai-compatibility`; zee reads e['api-keys'][provider]; Fp rejects groups without array group.keys; Np reads group name/base-url/keys/models; xv serializes a group with name,base-url,keys; hv serializes each key as api-key. Therefore the version8 payload is ROOT `api-keys: { openai-compatibility: [{name,base-url,keys:[{api-key}],models:[{name}]}] }`, distinct from the client allowlist under access.api-keys. Source excerpts/character offsets in evidence/bundled-panel-shape.txt; no header/auth values in receipts. This is actual pinned bundled UI reader/writer source, not a guessed provider nesting or an external/unpinned example.
|
||||
|
||||
Cause of first setup failure: my test used providers.openai-compatibility with api-key-entries, neither the root key nor the group-key field expected by that pinned writer. Initial readiness also stopped at first200 instead of waiting for required models; fixed to30s bound,1s intervals, model count logged per poll. Under sage-4330 one further isolated attempt only: reuse fetched binary and re-hash with P1 verifyInstall before launch; separate attempt2 test roots; actual pi turns each once, retry disabled in pi settings; API constant remains PENDING. Record/restore niceness for own descendants when host policy changes it. No actual turn has yet run as of this pre-attempt note.
|
||||
|
||||
## Offline attempt2 evidence — sage-4330, API STILL PENDING
|
||||
|
||||
Static diagnosis above preceded this one extra attempt. No new fetch. P1 verifyInstall recomputed existing executable/panel hashes before use and matched PIN8.0.42/panel1.26.7. unshare-rn verified only lo, empty private HOME/auth, sanitized env. Test config uses bundled writer's root api-keys.openai-compatibility/groups.keys shape. Readiness poll1 not-ready/modelCount0; poll2 status200/modelCount2; proxy lists gpt-fixture and glm-fixture. No setup failure on attempt2.
|
||||
|
||||
A transparent loopback HTTP tap captures pi's method/path and a whitelist of body shape fields; forwards original body bytes to pinned proxy; no header/auth values recorded. Upstream stand-in receives proxy output. Both remain inside network namespace. Each actual pi invocation once,50s timeout-k10; retry.enabled=false and provider.maxRetries=0 in private pi settings. Proxy has request-retry0. Outer isolation240s timeout-k10; no reruns. All three turn exits0 and marker P332_OFFLINE_OK observed:
|
||||
|
||||
| Turn | Pi request to proxy through transparent tap | Proxy response | Stand-in upstream observation |
|
||||
| --- | --- | --- | --- |
|
||||
| GPT responses | POST/v1/responses, modelgpt-fixture,streamtrue,reasoning={effort:low,summary:auto} |200,response.completed event, marker |POST/v1/chat/completions,reasoning_effort=low,max_tokens=16384,streamtrue |
|
||||
| GPT completions | POST/v1/chat/completions, modelgpt-fixture,roles[developer,user],reasoning_effort=low,max_completion_tokens=16384 |200,completion stream marker |POST/v1/chat/completions,roles[developer,user],reasoning_effort=low,max_tokens=16384 |
|
||||
| GLM completions | POST/v1/chat/completions,modelglm-fixture,thinking={type:enabled,clear_thinking:false},reasoning_effort=low,max_completion_tokens=16384 |200,completion stream marker |POST/v1/chat/completions,same thinking object and reasoning_effort retained,max_tokens=16384 |
|
||||
|
||||
GLM compatibility finding: thinkingFormat=zai-generated thinking.type=enabled/clear_thinking=false survives proxy translation, as does reasoning_effort=low. zaiToolStream-derived tool_stream was NOT emitted, because this turn disabled tools; its survival is NOT proven. Static pinned pi source node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js:612-618 sets params.tool_stream=true only with active tools and compat.zaiToolStream. No tool-call stream was exercised. This limitation is reported, not silently interpreted as pass or drop.
|
||||
|
||||
Both GPT shapes pass on the stand-in openai-compatibility credential route. This does not distinguish them for the Codex-login route; no Codex OAuth/auth file exists in this experiment. Evidence is INCONCLUSIVE for the production GPT choice. PROXY_CODEX_API remains null/PENDING; no source or API selection changed. Sage rules or takes to Mos per plan item5; first real Codex-auth turn stays row209 phaseA step7.
|
||||
|
||||
Niceness: attempt2 entry/emitted turn values19, explicit setPriority at entry/child start and100ms restore over owned descendants. Host policy temporarily changed processes to16 eight times; corrections restored19, disclosed here. Initial fetch end16 and failed inspection guard are retained separately, not represented as clean19 throughout. Full safe request/response receipts in evidence/offline-attempt2.txt; no auth/header value recorded. Process cleanup reports remainingManagedChildren0. Sweep over worktree and owned evidence root found same six pre-existing tool services only, no proxy/pi/timeout/chromium test leftovers. Lane B free. No mutants or other test files run.
|
||||
|
||||
## API choice and active-tool follow-up — sage-4331
|
||||
|
||||
Sage's ruling: PROXY_CODEX_API=openai-responses. The evidence does not separate the two shapes: both pass through pinned8.0.42. This is a tie broken on reasoning; it is NOT an evidence-decided pick. Sage's reason: Codex upstream speaks Responses natively and Responses carries pi's reasoning summary field, while completions drops that field; expected fewer translations/lost fields on the real route. This reasoning is a lead decision, not a claim of an authenticated Codex experiment. Row209 phaseA step7 verifies first real Codex turn; change the single constant if it fails there, with no runtime fallback/env switch. Earlier PENDING logs/notes remain historical evidence.
|
||||
|
||||
Set constant/remove pending refusal; GPT route test asserts openai-responses on mosaic-proxy-codex. Replaced temporary pending-refusal test with generated single-provider/responses/key-reference assertions per ruling. No other production change. Active plug-in docs updated.
|
||||
|
||||
Evidence script adds glm-tool mode: one GLM turn only, same pinned verified binary and isolated setup, distinct attempt3-tool root, active built-in read tool but stand-in still returns text only. Capture tool_stream and tool names before/after proxy, never header/auth values. No actual tool execution is demanded by stand-in, so this checks wire-field survival, not arbitrary tool-call semantics. Rehash before launch, no fetch,30s catalog readiness with counts,50s timeout-k10 for one turn,own descendants restored nice19. Commit untested before cleared run; then proxy-bundle and proxy-harness each whole once. No other runs/mutants.
|
||||
|
||||
### sage-4331 single active-tool GLM turn and two-file results
|
||||
|
||||
Tested ef0939e35. No fetch. P1 verifyInstall rehashed existing binary/panel and matched both PIN hashes before use. One isolated glm-tool run, unshare-rn interfaces[lo],empty private HOME/auth,sanitized env. Readiness poll1 not-ready/count0;poll2 status200/count2. One pi invocation with one active builtin read tool,exit0,markerP332_OFFLINE_OK; no rerun. Outer timeout-k10/140s,inner120s,pi50s;nice19 explicitly at entry/child starts and guard restores observed16→19 three times. No production API chosen by script.
|
||||
|
||||
Plain request/response evidence (full safe receipt evidence/glm-tool.txt):
|
||||
- pi POST/v1/chat/completions modelglm-fixture,streamtrue,tools=[read],tool_stream=true,thinking={type:enabled,clear_thinking:false},reasoning_effort=low,max_completion_tokens=16384.
|
||||
- pinned proxy200 completion stream,marker.
|
||||
- stand-in receives POST/v1/chat/completions,tools=[read],tool_stream=true and same thinking/reasoning_effort fields;max_tokens=16384. Thus zaiToolStream-derived tool_stream survives this proxy route. No tool invocation or tool-call delta sequence was requested by the stand-in; this proves field survival with active tool, not every tool-call streaming semantic.
|
||||
|
||||
Then exactly once each whole file, fresh gXXX TMPDIR,nice19,timeout-k10/180s:
|
||||
- packages/harness/tests/proxy-bundle.test.mjs00:14:20Z:7pass,0fail,0skip,exit0.
|
||||
- packages/plugins/tests/proxy-harness.test.mjs00:14:20Z:5pass,0fail,0skip,exit0.
|
||||
|
||||
No failures, no extra runs/mutants. Cleanup managed children0. Own-worktree/evidence-root sweep found only same six pre-existing tool services,no proxy/pi/test/timeout/chromium leftovers. Lane B free. P3 now waits for P2/row331 landing before rebase,mutants,Gladstone review and further gates; no landing/merge requested or performed.
|
||||
@@ -0,0 +1,51 @@
|
||||
# STOPPED — row 332 (P3), T3 crash handoff
|
||||
|
||||
Stopped on 2026-10-24 under Mos mos-1630, relaying Jason's instruction: do not restart long jobs; commit/push safe work, leave a handoff, then stop. No further thread messages, tests, probes, queue operations, or implementation will run in this session.
|
||||
|
||||
## Branch and completed work
|
||||
|
||||
- Worktree: /home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332
|
||||
- Branch: fethry/row332, based on refactor c8a9bcf94. No implementation commits, rebases, merges or production source edits.
|
||||
- Read P3 brief, rules, full pi amendment, gate template, design and named source files. Detailed notes in BUILD.md beside this handoff.
|
||||
- Root npm ci --ignore-scripts --no-audit --no-fund completed in this worktree only (128 packages). No canonical node_modules used.
|
||||
- Initial test files written before implementation; none executed. Sage has not sent CLEAR. No proxy fetch, binary probe, offline turn, mutant, or suite has run.
|
||||
- No real proxy, management key, host auth directory or live instance was accessed. No production service was started/stopped.
|
||||
- Canonical queue next returned nothing during the assignment. Queue start op fethry-332-start refused on locks, then owner sage, including a retry after two minutes. Latest completed queue show still had owner sage, state briefed, after 331; it also warned that the rendered table was unknown. Did not repair or bypass it. Sage sage-4293 says an assign/after=none batch is running. Queue metadata identifies shared Gitea issue #1830.
|
||||
|
||||
## Latest accepted design
|
||||
|
||||
Sage sage-4293 supersedes all earlier route proposals: explicit route metadata, never catalog membership or model-prefix inference. Selected spelling: launch.models.<selection>.route = anthropic | glm | codex, required only with provider proxy. Missing route: proxy-route-missing; unknown/nonstring route: proxy-route-unknown. Other providers keep provider/model-only entries. Proposed launch.account.credential literal proxy; existing name/credential field names retained. GPT generated provider: mosaic-proxy-codex, never openai-codex. GPT wire API is still undecided pending the authorized pinned-binary requests. P2's seam stays exactly { baseUrl, key }.
|
||||
|
||||
Important implementation finding: launcher.mjs:571 serializes bundle.env into session.harnessEnv. Harness env will contain the session key in proxy mode, so credentials must instead reach spawnSession through transient environment variables and be omitted from serialized harnessEnv. runner.mjs:390 already inherits the spawn environment. Preserve ENV_ALLOW; filter instance provider variables in proxy mode only.
|
||||
|
||||
## Uncommitted work, intentionally left for the next session
|
||||
|
||||
These are unrun, incomplete tests/audit code, excluded from the documentation-only crash commit:
|
||||
|
||||
- packages/business/tests/proxy-launch.test.mjs — explicit routes and refusal codes, proxy account credential, existing nonproxy/account behavior.
|
||||
- packages/plugins/tests/proxy-harness.test.mjs — Claude env/preflight, own-key isolation, pi preflight and OAuth-only refusal.
|
||||
- packages/seat/tests/proxy-session-env.test.mjs — instance credential filtering and unchanged nonproxy env.
|
||||
- packages/harness/tests/proxy-bundle.test.mjs — real bundle generation, all three providers, key reference/no-key/no-! invariants, file modes and launch freshness. Exact GPT API assertion deliberately pending probe evidence; add before its first run.
|
||||
- agents/fethry/work/queue-332/import-run-list.mjs — non-evaluating static import audit using vm.SourceTextModule plus explicit computed loader edges. It ran successfully after correcting its own root-depth setup error. It is not a test runner.
|
||||
|
||||
IMPORT-RUN-LIST.txt is a historical 211-entry candidate impact list, generated before proxy-bundle.test.mjs was added. It includes case1-accept as explicitly EXCLUDED (mos-1612). Regenerate the list after resuming and report the actual authorized run list inline before any whole-file run. Do not treat the historical manifest as a current run authorization.
|
||||
|
||||
## Reporting status
|
||||
|
||||
T3 reporting repeatedly failed during GET with a 30-second timeout. fethry-0004 was confirmed delivered. Some later short numeric keys returned reused:true unexpectedly; do not rely on them as delivery evidence. A row-scoped detailed design resend and the inline 211-line import manifest also timed out, including the manifest's same-key retry. Sage may not have those messages. This handoff and BUILD.md are being pushed so they can be read with git show; no new thread message is sent under mos-1630.
|
||||
|
||||
## Next session, after restart authorization
|
||||
|
||||
1. Read this handoff/BUILD.md and recover queue state from canonical checkout. Wait for owner fethry and no after, then retry the same start op. Never bypass a refusal.
|
||||
2. Recover Sage's slot status. Still NO tests or probes until Sage sends CLEAR. No job needs restarting merely to preserve current state.
|
||||
3. Review the four uncommitted test files. Add the pinned-proxy API probe and exact GPT assertion before the first relevant run. Initial RED has not happened; production implementation must follow the authorized first RED.
|
||||
4. Rebuild the import-derived run list and send it inline or in a reviewed pushed commit before runs. case1-accept remains off without Mos approval. Existing launch-settings.test.mjs proxy fixtures need explicit route metadata with their authorization assertions preserved; no old-test red has occurred.
|
||||
5. Use P1's committed fetchPinned code under an owned fresh temporary root (8.0.42 at the inspected magica/row329 revision), never live proxy assets or another seat's scratch. After CLEAR, try pi's responses and completions requests under unshare -rn against stand-in upstream, record evidence, choose one GPT API at build time. Separately prove offline GLM and record z.ai compat survival. Real Codex auth proof remains row209 phase A step7.
|
||||
6. Implement transient P2 context, model validation/route propagation, harness config, preflight, spawn env/serialization separation and tests. Named mutants: OAuth token leak; literal key in models.json. No policy or real credentials involved.
|
||||
7. Land only after 329 and 331 land, rebasing on both, Gladstone first review, Dewey landing review and Sage's required gate. No force-push or merge authority is added by the crash instruction.
|
||||
|
||||
All future tests use a fresh shell-created short TMPDIR, absolute nice 19, and timeout -k 10 for scripts/test-*.sh. First new-test red is reportable afterward; old-test red or a second red goes to Sage before changes/reruns. No test outcomes are claimed here.
|
||||
|
||||
## Crash commit
|
||||
|
||||
Only documentation and the historical plain-text import manifest are committed. The final STOPPED reply records the exact pushed commit. The uncommitted files above remain deliberately available in this worktree because they have never run and test-slot authorization has not arrived.
|
||||
@@ -0,0 +1,213 @@
|
||||
packages/bus/tests/access-revoke.test.mjs
|
||||
packages/bus/tests/broker.test.mjs
|
||||
packages/bus/tests/channel-proof.test.mjs
|
||||
packages/bus/tests/chief-of-staff.test.mjs
|
||||
packages/bus/tests/citation-guard.test.mjs
|
||||
packages/bus/tests/citation-runtime.test.mjs
|
||||
packages/bus/tests/creative.test.mjs
|
||||
packages/bus/tests/credential-verbs.test.mjs
|
||||
packages/bus/tests/grant-scope-runtime.test.mjs
|
||||
packages/bus/tests/host-run.test.mjs
|
||||
packages/bus/tests/land.test.mjs
|
||||
packages/bus/tests/library-credential.test.mjs
|
||||
packages/bus/tests/library-lookups.test.mjs
|
||||
packages/bus/tests/library-sync.test.mjs
|
||||
packages/bus/tests/library.test.mjs
|
||||
packages/bus/tests/lifecycle-revoke.test.mjs
|
||||
packages/bus/tests/limit-checks.test.mjs
|
||||
packages/bus/tests/messages.test.mjs
|
||||
packages/bus/tests/processing-runtime.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/bus/tests/reload.test.mjs
|
||||
packages/bus/tests/tasks.test.mjs
|
||||
packages/bus/tests/tester-writes.test.mjs
|
||||
packages/bus/tests/tester.test.mjs
|
||||
packages/bus/tests/usage-runtime.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/bus/tests/workflow-roles.test.mjs
|
||||
packages/business/tests/access-levels.test.mjs
|
||||
packages/business/tests/access.test.mjs
|
||||
packages/business/tests/agent-identity.test.mjs
|
||||
packages/business/tests/assistant.test.mjs
|
||||
packages/business/tests/business.test.mjs
|
||||
packages/business/tests/case1-business-file.test.mjs
|
||||
packages/business/tests/chief-library-credentials.test.mjs
|
||||
packages/business/tests/chief-of-staff.test.mjs
|
||||
packages/business/tests/cli.test.mjs
|
||||
packages/business/tests/credentials.test.mjs
|
||||
packages/business/tests/csuite.test.mjs
|
||||
packages/business/tests/grant-scope.test.mjs
|
||||
packages/business/tests/hard-waits.test.mjs
|
||||
packages/business/tests/hosts.test.mjs
|
||||
packages/business/tests/instance-credential-transitions.test.mjs
|
||||
packages/business/tests/instance-settings.test.mjs
|
||||
packages/business/tests/launch-settings.test.mjs
|
||||
packages/business/tests/library-projects-protected.test.mjs
|
||||
packages/business/tests/library-seats.test.mjs
|
||||
packages/business/tests/lifecycle-settings.test.mjs
|
||||
packages/business/tests/optional-tracker.test.mjs
|
||||
packages/business/tests/plugin-settings.test.mjs
|
||||
packages/business/tests/project-repo.test.mjs
|
||||
packages/business/tests/project.test.mjs
|
||||
packages/business/tests/proxy-launch.test.mjs
|
||||
packages/business/tests/record-grants.test.mjs
|
||||
packages/business/tests/reply-limits.test.mjs
|
||||
packages/business/tests/resolve.test.mjs
|
||||
packages/business/tests/role.test.mjs
|
||||
packages/business/tests/token-limit-settings.test.mjs
|
||||
packages/business/tests/vars.test.mjs
|
||||
packages/business/tests/workflow-roles.test.mjs
|
||||
packages/cli/tests/access-boot.test.mjs
|
||||
packages/cli/tests/access.test.mjs
|
||||
packages/cli/tests/app.test.mjs
|
||||
packages/cli/tests/boot-status.test.mjs
|
||||
EXCLUDED (mos-1612) packages/cli/tests/case1-accept.test.mjs
|
||||
packages/cli/tests/case1-hostcheck.test.mjs
|
||||
packages/cli/tests/case2-install.test.mjs
|
||||
packages/cli/tests/case2-persona-import.test.mjs
|
||||
packages/cli/tests/case2-unit.test.mjs
|
||||
packages/cli/tests/channel-cli.test.mjs
|
||||
packages/cli/tests/channel-recovery.test.mjs
|
||||
packages/cli/tests/cli.test.mjs
|
||||
packages/cli/tests/compactions-launch.test.mjs
|
||||
packages/cli/tests/config.test.mjs
|
||||
packages/cli/tests/credentials.test.mjs
|
||||
packages/cli/tests/federation-acceptance.test.mjs
|
||||
packages/cli/tests/follow.test.mjs
|
||||
packages/cli/tests/git-socket.test.mjs
|
||||
packages/cli/tests/grants-scope.test.mjs
|
||||
packages/cli/tests/grants.test.mjs
|
||||
packages/cli/tests/host.test.mjs
|
||||
packages/cli/tests/hosts.test.mjs
|
||||
packages/cli/tests/idle-stop-race.test.mjs
|
||||
packages/cli/tests/instances.test.mjs
|
||||
packages/cli/tests/launch-account.test.mjs
|
||||
packages/cli/tests/launch-limit-checks.test.mjs
|
||||
packages/cli/tests/launch-limits.test.mjs
|
||||
packages/cli/tests/launch-routes.test.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/lifecycle.test.mjs
|
||||
packages/cli/tests/limits-tokens.test.mjs
|
||||
packages/cli/tests/limits.test.mjs
|
||||
packages/cli/tests/mark-read.test.mjs
|
||||
packages/cli/tests/model-proxy.test.mjs
|
||||
packages/cli/tests/names.test.mjs
|
||||
packages/cli/tests/notifier.test.mjs
|
||||
packages/cli/tests/optional-tracker.test.mjs
|
||||
packages/cli/tests/other-tree.test.mjs
|
||||
packages/cli/tests/processing-cli.test.mjs
|
||||
packages/cli/tests/project-name-repo.test.mjs
|
||||
packages/cli/tests/project.test.mjs
|
||||
packages/cli/tests/publish-socket.test.mjs
|
||||
packages/cli/tests/reply-limits.test.mjs
|
||||
packages/cli/tests/revoke-window.test.mjs
|
||||
packages/cli/tests/session-clear.test.mjs
|
||||
packages/cli/tests/session-cli.test.mjs
|
||||
packages/cli/tests/session-launch.test.mjs
|
||||
packages/cli/tests/stack-copy.test.mjs
|
||||
packages/cli/tests/stack-instances.test.mjs
|
||||
packages/cli/tests/tester-reads.test.mjs
|
||||
packages/cli/tests/tester-threads.test.mjs
|
||||
packages/cli/tests/tester.test.mjs
|
||||
packages/cli/tests/thread-cli.test.mjs
|
||||
packages/cli/tests/thread-launch.test.mjs
|
||||
packages/cli/tests/thread-revoke.test.mjs
|
||||
packages/cli/tests/trackers-boot.test.mjs
|
||||
packages/cli/tests/transport.test.mjs
|
||||
packages/cli/tests/usage.test.mjs
|
||||
packages/cli/tests/verbs.test.mjs
|
||||
packages/control-board/tests/creative-hidden.test.mjs
|
||||
packages/control-board/tests/discord.test.mjs
|
||||
packages/control-board/tests/serve.test.mjs
|
||||
packages/conversation/tests/flows.test.mjs
|
||||
packages/harness/tests/bundle.test.mjs
|
||||
packages/harness/tests/claude-gate.test.mjs
|
||||
packages/harness/tests/claude-session.test.mjs
|
||||
packages/harness/tests/creative.test.mjs
|
||||
packages/harness/tests/gate.test.mjs
|
||||
packages/harness/tests/git-tools.test.mjs
|
||||
packages/harness/tests/library-tools.test.mjs
|
||||
packages/harness/tests/mcp-server.test.mjs
|
||||
packages/harness/tests/pi-session.test.mjs
|
||||
packages/harness/tests/proxy-bundle.test.mjs
|
||||
packages/harness/tests/raise-domain.test.mjs
|
||||
packages/harness/tests/runner.test.mjs
|
||||
packages/harness/tests/skills.test.mjs
|
||||
packages/harness/tests/spec-tools.test.mjs
|
||||
packages/harness/tests/tools.test.mjs
|
||||
packages/plugins/tests/channel.test.mjs
|
||||
packages/plugins/tests/harness-compactions.test.mjs
|
||||
packages/plugins/tests/harness.test.mjs
|
||||
packages/plugins/tests/loader.test.mjs
|
||||
packages/plugins/tests/proxy-harness.test.mjs
|
||||
packages/plugins/tests/searxng.test.mjs
|
||||
packages/processing-control/tests/task.test.mjs
|
||||
packages/seat/tests/compactions-budget.test.mjs
|
||||
packages/seat/tests/compactions-ledger.test.mjs
|
||||
packages/seat/tests/compactions.test.mjs
|
||||
packages/seat/tests/proxy-session-env.test.mjs
|
||||
packages/seat/tests/sandbox.test.mjs
|
||||
packages/seat/tests/session-workspace.test.mjs
|
||||
packages/seat/tests/session.test.mjs
|
||||
packages/tasks/tests/fields.test.mjs
|
||||
packages/webui/tests/agents-browser.test.mjs
|
||||
packages/webui/tests/agents.test.mjs
|
||||
packages/webui/tests/assistant.test.mjs
|
||||
packages/webui/tests/board-held.test.mjs
|
||||
packages/webui/tests/browser-edge.test.mjs
|
||||
packages/webui/tests/browser.test.mjs
|
||||
packages/webui/tests/bus-browser.test.mjs
|
||||
packages/webui/tests/bus.test.mjs
|
||||
packages/webui/tests/channel-chat.test.mjs
|
||||
packages/webui/tests/chat-browser.test.mjs
|
||||
packages/webui/tests/chat-instances.test.mjs
|
||||
packages/webui/tests/chat-replies-browser.test.mjs
|
||||
packages/webui/tests/chat.test.mjs
|
||||
packages/webui/tests/conversation.test.mjs
|
||||
packages/webui/tests/decide-browser.test.mjs
|
||||
packages/webui/tests/decide-sso.test.mjs
|
||||
packages/webui/tests/discord.test.mjs
|
||||
packages/webui/tests/docs-browser.test.mjs
|
||||
packages/webui/tests/editor-browser.test.mjs
|
||||
packages/webui/tests/editor.test.mjs
|
||||
packages/webui/tests/granted-user.test.mjs
|
||||
packages/webui/tests/history-return-flow.test.mjs
|
||||
packages/webui/tests/instances-browser.test.mjs
|
||||
packages/webui/tests/instances.test.mjs
|
||||
packages/webui/tests/library-cli.test.mjs
|
||||
packages/webui/tests/library-routes.test.mjs
|
||||
packages/webui/tests/limits-browser.test.mjs
|
||||
packages/webui/tests/limits-route.test.mjs
|
||||
packages/webui/tests/messages.test.mjs
|
||||
packages/webui/tests/pinned-copy.test.mjs
|
||||
packages/webui/tests/preview.test.mjs
|
||||
packages/webui/tests/processing-browser.test.mjs
|
||||
packages/webui/tests/processing.test.mjs
|
||||
packages/webui/tests/project-file.test.mjs
|
||||
packages/webui/tests/proof-cli.test.mjs
|
||||
packages/webui/tests/proof.test.mjs
|
||||
packages/webui/tests/reads.test.mjs
|
||||
packages/webui/tests/relaunch.test.mjs
|
||||
packages/webui/tests/return-flow.test.mjs
|
||||
packages/webui/tests/room-browser.test.mjs
|
||||
packages/webui/tests/room-http.test.mjs
|
||||
packages/webui/tests/routes-browser.test.mjs
|
||||
packages/webui/tests/routes.test.mjs
|
||||
packages/webui/tests/send-browser.test.mjs
|
||||
packages/webui/tests/send.test.mjs
|
||||
packages/webui/tests/serve.test.mjs
|
||||
packages/webui/tests/settings-form.test.mjs
|
||||
packages/webui/tests/settings-write.test.mjs
|
||||
packages/webui/tests/shell.test.mjs
|
||||
packages/webui/tests/sso-browser.test.mjs
|
||||
packages/webui/tests/sso.test.mjs
|
||||
packages/webui/tests/tester-browser.test.mjs
|
||||
packages/webui/tests/tester-cli.test.mjs
|
||||
packages/webui/tests/tester-listener.test.mjs
|
||||
packages/webui/tests/thread-claims-browser.test.mjs
|
||||
packages/webui/tests/thread-claims.test.mjs
|
||||
packages/webui/tests/thread-sharing.test.mjs
|
||||
packages/webui/tests/usage-browser.test.mjs
|
||||
packages/webui/tests/usage.test.mjs
|
||||
packages/webui/tests/user-option-swap.test.mjs
|
||||
packages/webui/tests/views.test.mjs
|
||||
@@ -0,0 +1,19 @@
|
||||
00:14:20Z
|
||||
nice=19
|
||||
✔ P3 Anthropic route uses messages at proxy root and the declared model id (12.070131ms)
|
||||
✔ P3 omitted route refuses proxy-route-missing before model config generation (2.197623ms)
|
||||
✔ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (3.390562ms)
|
||||
✔ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (4.240948ms)
|
||||
✔ P3 a declared Codex route generates only the single build-time responses provider (3.37448ms)
|
||||
✔ P3 models file is private, references the one session key, and stores no executable values or keys (3.305299ms)
|
||||
✔ P3 every launch regenerates proxy port, declared models and own key without caching (6.287121ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 128.759611
|
||||
exit=0
|
||||
00:14:20Z
|
||||
@@ -0,0 +1,17 @@
|
||||
00:14:20Z
|
||||
nice=19
|
||||
✔ P3 Claude env receives the session proxy URL and key, without another agent or host credential (3.096286ms)
|
||||
✔ P3 Claude preflight accepts a proxy key without a host provider credential (1.305258ms)
|
||||
✔ P3 pi refuses no-session-credential with no provider key (1.23137ms)
|
||||
✔ P3 pi refuses no-session-credential with only a Claude OAuth token (3.659409ms)
|
||||
✔ P3 pi accepts its own provider key or a session proxy key (0.590987ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 68.648537
|
||||
exit=0
|
||||
00:14:20Z
|
||||
@@ -0,0 +1,17 @@
|
||||
Ip=e=> @ char 1054606:
|
||||
Ip=e=>{let t={raw:Dc(e)?e:{}};if(!Dc(e))return t;let n=t=>t.split(`.`).reduce((e,t)=>Dc(e)?e[t]:void 0,e);t.debug=wp(n(`observability.logs.debug`)),t.requestLog=wp(n(`observability.logs.request-log`)),t.loggingToFile=wp(n(`observability.logs.logging-to-file`));let r=n(`observability.logs.logs-max-total-size-mb`);typeof r==`number`&&(t.logsMaxTotalSizeMb=r);let i=n(`requests.proxy-url`);typeof i==`string`&&(t.proxyUrl=i);let a=n(`routing.retry.request-retry`);typeof a==`number`&&(t.requestRetry=a),t.wsAuth=wp(n(`oauth.providers.aistudio.ws-auth`))??!0,t.forceModelPrefix=wp(n(`routing.force-model-prefix`));let o=n(`routing.strategy`);typeof o==`string`&&(t.routingStrategy=o);let s=n(`access.api-keys`);return t.apiKeys=Array.isArray(s)?s.filter(e=>typeof e==`string`):[],t.quotaExceeded={antigravityCredits:wp(n(`oauth.providers.antigravity.antigravity-credits`))??!1},t.providerGroups=Dc(e[`api-keys`])?e[`api-keys`]:{},t.geminiApiKeys=Fp(n(`api-keys.gemini`)),t.interactionsApiKeys=Fp(n(`api-keys.interactions`)),t.codexApiKeys=Fp(n(`api-keys.codex`)),t.metaApiKeys=Fp(n(`api-keys.meta`)),t.xaiApiKeys=Fp(n(`api-keys.xai`)),t.claudeApiKeys=Fp(n(`api-keys.claude`)),t.vertexApiKeys=Fp(n(`api-keys.vertex`)),t.openaiCompatibility=Fp(n(`api-keys.openai-compatibility`),!0),t.oauthExcludedModels=Pp(n(`oauth.excluded-models`)),t},Lp={async getConfig(){return Ip(await W.get(`/config`))},updateRequestLog:e=>W.put(`/config/observability/logs/request-log`,e)},Rp=0,zp=null,Bp=null,Vp=()=>Bp!==null&&Date.now()-Bp.timestamp<3e4,Hp=Tc((e,t)=>({config:null,fetchConfig:async(t=!1)=>{if(!t&&Bp&&Vp())return Bp.data;if(zp)return zp.promise;let n=Rp+=1;try{let t=Lp.getConfig();zp={id:n,promise:t};let r
|
||||
|
||||
Fp=(e,t= @ char 1054198:
|
||||
Fp=(e,t=!1)=>Array.isArray(e)?e.flatMap((n,r)=>{if(!Dc(n)||!Array.isArray(n.keys))return[];if(t){let t=Np(n,r);return t?[{...t,source:{groupIndex:r,group:n,groups:e}}]:[]}return n.keys.flatMap((t,i)=>{if(!Dc(t))return[];let a={...n};delete a.keys,delete a.name,Object.entries(t).forEach(([e,t])=>{t!==null&&(a[e]=t)});let o=Mp(a);return o?[{...o,source:{groupIndex:r,keyIndex:i,group:n,groups:e}}]:[]})}):[],Ip=e=>{let t={raw:Dc(e)?e:{}};if(!Dc(e))return t;let n=t=>t.split(`.`).reduce((e,t)=>Dc(e)?e[t]:void 0,e);t.debug=wp(n(`observability.logs.debug`)),t.requestLog=wp(n(`observability.logs.reques
|
||||
|
||||
Np=(e,t)=> @ char 1053331:
|
||||
Np=(e,t)=>{if(!Dc(e))return null;let n=e.name,r=e[`base-url`];if(!n||!r)return null;let i=Array.isArray(e.keys)?e.keys.map((e,t)=>{let n=Ap(e);return n?{...n,sourceIndex:t}:null}).filter(Boolean):[],a=Ep(e.headers),o=Tp(e.models),s=e.priority,c={name:String(n),baseUrl:String(r),apiKeyEntries:i,...jp(e)},l=wp(e[`support-prompt-cache-key`]);l!==void 0&&(c.supportPromptCacheKey=l);let u=wp(e.disabled);u!==void 0&&(c.disabled=u);let d=wp(e[`disable-cooling`]);d!==void 0&&(c.disableCooling=d);let f=Op(e.prefix);f&&(c.prefix=f),a&&(c.headers=a),o.length&&(c.models=o),s!==void 0&&(c.priority=Number(s));let p=kp(e[`auth-index`]);return p&&(c.authIndex=p),t!==void 0&&(c.sourceIndex=t),c},Pp=e=>{if(!Dc(e))return;let t=e;if(!Dc(t))return;let n={};return Object.entries(t).forEach(([e,t])=>{let r=String(e||``).trim();if(!r)return;let i=Dp(t);n[r.toLow
|
||||
|
||||
xv=e=> @ char 1129493:
|
||||
xv=e=>{let t={name:e.name,"base-url":e.baseUrl,...gv(e),keys:Array.isArray(e.apiKeyEntries)?e.apiKeyEntries.map(e=>hv(e)):[]};e.prefix?.trim()&&(t.prefix=e.prefix.trim()),e.disabled!==void 0&&(t.disabled=e.disabled),e.supportPromptCacheKey!==void 0&&(t[`support-prompt-cache-key`]=e.supportPromptCacheKey);let n=pv(e.headers);n&&(t.headers=n);let r=mv(e.models,!0);return r&&r.length&&(t.models=r),e.priority!==void 0&&(t.priority=e.priority),e.disableCooling!==void 0&&(t[`disable-cooling`]=e.disableCooling),t},Sv=(e,t)=>{if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>Sv(e,t[n]));if(Dc(e)&&Dc(t)){let n=Object.keys(e).filter(t=>e[t]!==void 0);re
|
||||
|
||||
hv=e=> @ char 1126395:
|
||||
hv=e=>{let t={"api-key":e.apiKey};return e.proxyUrl&&(t[`proxy-url`]=e.proxyUrl),e.weight!==void 0&&(t.weight=e.weight),t},gv=(e,t=!0)=>{let n={};return e.requestRetry!==void 0&&(n[`request-retry`]=e.requestRetry),t&&e.r
|
||||
|
||||
zee=(e,t)=> @ char 1130380:
|
||||
zee=(e,t)=>{if(!Dc(e)||!Dc(e[`api-keys`]))return[];let n=e[`api-keys`][t];if(n===void 0)return[];if(!Array.isArray(n)||!n.every(e=>Dc(e)&&Array.isArray(e.keys)))throw Cv();return n},wv=async e=>{let t=cv(),n=Nm.getState(),r=await W.get(`/config`);t();let i=Nm.getState();if(n.apiBase!==i.apiBase||n.managementKey!==i.managementKey||n.isAuthenticated!==i.isAuthenticated)throw Cv();return zee(r,e)},Tv
|
||||
@@ -0,0 +1,11 @@
|
||||
file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/agents/fethry/work/queue-332/proxy-evidence.mjs:9
|
||||
if (getPriority(0) !== 19) throw Error('nice19 required');
|
||||
^
|
||||
|
||||
Error: nice19 required
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/agents/fethry/work/queue-332/proxy-evidence.mjs:9:34
|
||||
at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
|
||||
at async node:internal/modules/esm/loader:650:26
|
||||
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
|
||||
|
||||
Node.js v26.8.1
|
||||
@@ -0,0 +1 @@
|
||||
{"phase":"fetch","version":"8.0.42","binarySha256":"74661f8cf949977870231359e8bf4344e07946766a673c08fa25a3e5f72fc95e","panelVersion":"1.26.7","panelSha256":"8c9c6b7d3fb311e6aad5d06e1993e53a2d28389e640448a1bc6304ed20b057b5","nice":16,"verified":true}
|
||||
@@ -0,0 +1,8 @@
|
||||
{"phase":"isolation","interfaces":["lo"],"enteredNice":19,"nice":19,"version":"8.0.42","binarySha256":"74661f8cf949977870231359e8bf4344e07946766a673c08fa25a3e5f72fc95e","panelSha256":"8c9c6b7d3fb311e6aad5d06e1993e53a2d28389e640448a1bc6304ed20b057b5","reverified":true}
|
||||
{"phase":"readiness","poll":1,"status":"not-ready","modelCount":0}
|
||||
{"phase":"readiness","poll":2,"status":200,"modelCount":2}
|
||||
{"phase":"catalog","modelIds":["gpt-fixture","glm-fixture"]}
|
||||
{"phase":"turn","name":"glm-completions-tool","api":"openai-completions","exit":0,"signal":null,"marker":true,"piRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_completion_tokens","messages","model","reasoning_effort","store","stream","stream_options","thinking","tool_stream","tools"],"model":"glm-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","thinking":{"type":"enabled","clear_thinking":false},"reasoning_effort":"low","tool_stream":true,"toolNames":["read"],"stream_options":{"include_usage":true},"max_completion_tokens":16384}],"proxyResponses":[{"request":0,"status":200,"events":[],"marker":true}],"upstreamRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_tokens","messages","model","reasoning_effort","store","stream","stream_options","thinking","tool_stream","tools"],"model":"glm-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","thinking":{"type":"enabled","clear_thinking":false},"reasoning_effort":"low","tool_stream":true,"toolNames":["read"],"stream_options":{"include_usage":true},"max_tokens":16384}],"nice":19}
|
||||
{"phase":"conclusion","limitation":"Stand-in openai-compatibility credential only; no Codex OAuth credential or real-auth turn. This script never selects the production API."}
|
||||
{"phase":"nice-corrections","restoredTo":19,"observedBeforeRestore":{"16":3}}
|
||||
{"phase":"cleanup","remainingManagedChildren":0}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"phase":"isolation","interfaces":["lo"],"enteredNice":19,"nice":19,"version":"8.0.42","binarySha256":"74661f8cf949977870231359e8bf4344e07946766a673c08fa25a3e5f72fc95e","panelSha256":"8c9c6b7d3fb311e6aad5d06e1993e53a2d28389e640448a1bc6304ed20b057b5","reverified":true}
|
||||
{"phase":"readiness","poll":1,"status":"not-ready","modelCount":0}
|
||||
{"phase":"readiness","poll":2,"status":200,"modelCount":2}
|
||||
{"phase":"catalog","modelIds":["gpt-fixture","glm-fixture"]}
|
||||
{"phase":"turn","name":"gpt-responses","api":"openai-responses","exit":0,"signal":null,"marker":true,"piRequests":[{"method":"POST","path":"/v1/responses","keys":["include","input","max_output_tokens","model","prompt_cache_key","reasoning","store","stream"],"model":"gpt-fixture","stream":true,"inputTypes":[null,null],"reasoning":{"effort":"low","summary":"auto"}}],"proxyResponses":[{"request":0,"status":200,"events":["response.created","response.in_progress","response.output_item.added","response.content_part.added","response.output_text.delta","response.output_text.done","response.content_part.done","response.output_item.done","response.completed"],"marker":true}],"upstreamRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_tokens","messages","model","reasoning_effort","stream","stream_options"],"model":"gpt-fixture","stream":true,"roles":["user","user"],"inputTypes":"undefined","reasoning_effort":"low","stream_options":{"include_usage":true},"max_tokens":16384}],"nice":19}
|
||||
{"phase":"turn","name":"gpt-completions","api":"openai-completions","exit":0,"signal":null,"marker":true,"piRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_completion_tokens","messages","model","reasoning_effort","store","stream","stream_options"],"model":"gpt-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","reasoning_effort":"low","stream_options":{"include_usage":true},"max_completion_tokens":16384}],"proxyResponses":[{"request":1,"status":200,"events":[],"marker":true}],"upstreamRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_tokens","messages","model","reasoning_effort","store","stream","stream_options"],"model":"gpt-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","reasoning_effort":"low","stream_options":{"include_usage":true},"max_tokens":16384}],"nice":19}
|
||||
{"phase":"turn","name":"glm-completions","api":"openai-completions","exit":0,"signal":null,"marker":true,"piRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_completion_tokens","messages","model","reasoning_effort","store","stream","stream_options","thinking"],"model":"glm-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","thinking":{"type":"enabled","clear_thinking":false},"reasoning_effort":"low","stream_options":{"include_usage":true},"max_completion_tokens":16384}],"proxyResponses":[{"request":2,"status":200,"events":[],"marker":true}],"upstreamRequests":[{"method":"POST","path":"/v1/chat/completions","keys":["max_tokens","messages","model","reasoning_effort","store","stream","stream_options","thinking"],"model":"glm-fixture","stream":true,"roles":["developer","user"],"inputTypes":"undefined","thinking":{"type":"enabled","clear_thinking":false},"reasoning_effort":"low","stream_options":{"include_usage":true},"max_tokens":16384}],"nice":19}
|
||||
{"phase":"conclusion","limitation":"Stand-in openai-compatibility credential only; no Codex OAuth credential or real-auth turn. API value remains PENDING."}
|
||||
{"phase":"nice-corrections","restoredTo":19,"observedBeforeRestore":{"16":8}}
|
||||
{"phase":"cleanup","remainingManagedChildren":0}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"phase":"isolation","interfaces":["lo"],"enteredNice":19,"nice":16,"version":"8.0.42","configTags":["ntptr; X0 []string } \"*struct { F uintptr; X0 net.Conn } Models yaml:\"models\" json:\"models\" \"*config.DisableImageGene","ubscriptionCommand $*struct { F uintptr; R *api.Server } APIKey yaml:\"api-key\" json:\"api-key\" $EffectiveSignInWithChat","on:\\\"type\\\"\" } '*struct { F uintptr; X0 *bufio.Reader } BaseURL yaml:\"base-url\" json:\"base-url\" '*config.CodexWebSearch","ise-management\" json:\"advertise-management\" OpenAICompatibility7yaml:\"openai-compatibility\" json:\"openai-compatibility\" K*struct { "]}
|
||||
{"phase":"catalog","modelIds":[]}
|
||||
{"phase":"error","message":"stand-in routes absent from proxy catalog","proxyDiagnostic":"CLIProxyAPI Version: 8.0.42, Commit: bc064340, BuiltAt: 2026-10-24T14:21:38Z\n[2026-10-24 19:07:27] [--------] [info ] [main.go:641] CLIProxyAPI Version: 8.0.42, Commit: bc064340, BuiltAt: 2026-10-24T14:21:38Z\n[2026-10-24 19:07:27] [--------] [info ] [main.go:752] Local model mode: using embedded catalogs unless an explicit catalog source is configured\n[2026-10-24 19:07:27] [--------] [info ] [antigravity_version.go:71] periodic antigravity version refresh started (interval=3h0m0s)\n[2026-10-24 19:07:27] [--------] [info ] [service_lifecycle.go:103] core auth auto-refresh started (interval=15m0s)\n[2026-10-24 19:07:27] [--------] [info ] [server_management.go:22] management routes registered after secret key configuration\n[2026-10-24 19:07:27] [--------] [warn ] [xai_version.go:96] failed to fetch latest Grok CLI version from npm, keeping fallback/cached version error=npm registry request failed: Get \"https://registry.npmjs.org/@xai-official/grok/latest\": dial tcp [2606:4700::6810:122]:443: connect: network is unreachable\n[2026-10-24 19:07:27] [--------] [info ] [xai_version.go:79] periodic Grok CLI version refresh started (interval=3h0m0s)\n[2026-10-24 19:07:27] [b7852b37] [info ] [gin_logger.go:113] 200 | 0s | 127.0.0.1 | GET \"/v1/models\"\n"}
|
||||
{"phase":"cleanup","remainingManagedChildren":0}
|
||||
@@ -0,0 +1 @@
|
||||
/mnt/storage/scratch/tmp/g2Ta
|
||||
@@ -0,0 +1,63 @@
|
||||
23:59:16Z
|
||||
nice=19
|
||||
✔ C2-04: launcher workspace clones code but never the library (1450.400805ms)
|
||||
✔ P3 proxy key reaches the spawned runner but never session.json or the bundle (1347.117393ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1362.533548ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r5c4bfddc2d03","instance":"chief","turn":"2ce6282a-5e4f-4276-851e-3d8dd2d53a7a","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf9b4b14789bc","instance":"coder","turn":"d7a0db99-cce3-417f-8e7d-9910641f0860","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (842.489432ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd5fa76df3fb0","instance":"chief","turn":"f739ef1e-c01f-401f-9a89-cf45bc15b976","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r2c414ea1d43f","instance":"pm","turn":"8852a197-c1be-4108-a3af-34dad0232264","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd5fa76df3fb0","instance":"chief","turn":"6ccde05e-202a-43af-8556-43481f552676","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd5fa76df3fb0","instance":"chief","turn":"4a8f168b-8676-4b54-9404-174a2a703fcf","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r2c414ea1d43f","instance":"pm","turn":"67ee96fd-1338-48aa-a4fc-edbb7e0aef0e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r2c414ea1d43f","instance":"pm","turn":"ead68527-7bf4-49a1-8fd7-0107b9c6dfdf","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd5fa76df3fb0","instance":"chief","turn":"c1cc3a5e-1afe-4994-aea4-a3ea811a8f30","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r2c414ea1d43f","instance":"pm","turn":"e60723f6-187d-4b55-bd81-66189ae014c0","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rd5fa76df3fb0","instance":"chief","turn":"1b7721ee-a337-4623-9fcc-1e05277336ce","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 (1152.112093ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (4210.704487ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (713.043698ms)
|
||||
✔ 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 (456.475273ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r0e259f41ad4d","instance":"coder","turn":"52bb41d8-5eb6-4c72-9c5c-0b8abf8eae42","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 (838.095383ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (721.283915ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (963.365086ms)
|
||||
✔ 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 (708.305295ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (300.51414ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (380.448961ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (206.153531ms)
|
||||
✔ a pi launch with no own credential refuses no-session-credential (207.22057ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/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 (398.352887ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (418.567314ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (211.208923ms)
|
||||
✔ 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 (215.670064ms)
|
||||
✔ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (321.498853ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (208.543617ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r1f065863b517","instance":"chief","turn":"2c19dcc1-343e-4c12-93e3-4cd6dd65c4d9","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"reae1621f7ddf","instance":"coder","turn":"03cc3667-aab3-4f55-9e57-bf637e1be0dc","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 (1566.080686ms)
|
||||
✔ 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 (1164.65123ms)
|
||||
✔ 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 (4189.297007ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (258.381919ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (219.378242ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1236.400078ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (198.129142ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (200.659094ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (211.221353ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1398.582123ms)
|
||||
✔ kill switch refuses chief and hire before launch work and a clear permits a later request (373.807885ms)
|
||||
✔ kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle (372.1022ms)
|
||||
✔ a launch waiting across halt and resume cannot use its stale admission (236.835216ms)
|
||||
ℹ tests 35
|
||||
ℹ suites 0
|
||||
ℹ pass 35
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 29398.149477
|
||||
exit=0
|
||||
23:59:45Z
|
||||
@@ -0,0 +1,35 @@
|
||||
23:59:16Z
|
||||
nice=19
|
||||
✔ P3 Anthropic route uses messages at proxy root and the declared model id (9.965114ms)
|
||||
✔ P3 omitted route generates the Anthropic provider at proxy root (3.050792ms)
|
||||
✔ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (2.833686ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.980797ms)
|
||||
✔ P3 a declared Codex route refuses generation while the build-time API is PENDING (4.028363ms)
|
||||
✔ P3 models file is private, references the one session key, and stores no executable values or keys (3.814909ms)
|
||||
✔ P3 every launch regenerates proxy port, declared models and own key without caching (7.841047ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 117.036157
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:68:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.980797ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:69: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)
|
||||
exit=1
|
||||
23:59:16Z
|
||||
@@ -0,0 +1,18 @@
|
||||
23:57:06Z
|
||||
nice=19
|
||||
✔ P3 proxy model validation preserves each explicit wire route and the proxy model id (1.161459ms)
|
||||
✔ P3 a proxy model without route preserves its stored shape for the default Anthropic route (0.134804ms)
|
||||
✔ P3 an unknown proxy route refuses proxy-route-unknown (0.823069ms)
|
||||
✔ P3 nonproxy models retain their provider/model-only shape and reject route metadata (0.170037ms)
|
||||
✔ P3 launch.account accepts the proxy credential source without naming host variables (0.132947ms)
|
||||
✔ P3 existing environment-set accounts retain their validated representation (0.200363ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 52.197696
|
||||
exit=0
|
||||
23:57:06Z
|
||||
@@ -0,0 +1,21 @@
|
||||
23:57:12Z
|
||||
nice=19
|
||||
✔ row 65 both harness modules load through the loader with every export the kind names (7.907431ms)
|
||||
✔ row 65 each module answers for its own harness: adapter, levels, account, web, turn end and session files (0.745524ms)
|
||||
✔ row 65 claude-code preflight: a missing credential, then a missing or relative binary, each refuse with their code (3.501824ms)
|
||||
✔ row 65 claude-code version asks MOSAIC_CLAUDE_BIN when set, else claude on PATH, else null (3.715209ms)
|
||||
✔ row 65 pi preflight passes with the repository's pi, and its version is the package pin (0.570287ms)
|
||||
✔ row 65 env passes the thinking level to both adapters, and claude-code's bundle writes its hook and MCP files (1.263458ms)
|
||||
✔ row 65 a route's thinking reaches pi as --thinking and claude as --effort, through each module's env and adapter (14.961799ms)
|
||||
✔ row 65 no core source outside packages/plugins names a harness, apart from the listed exceptions (14.014352ms)
|
||||
✔ row 65 the grep's pattern catches a quoted name and a regex alternation, and not a word in prose (0.144087ms)
|
||||
ℹ tests 9
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 95.780618
|
||||
exit=0
|
||||
23:57:12Z
|
||||
@@ -0,0 +1,74 @@
|
||||
23:57:12Z
|
||||
nice=19
|
||||
✔ C2-04: launcher workspace clones code but never the library (1409.48354ms)
|
||||
✔ P3 proxy key reaches the spawned runner but never session.json or the bundle (1360.002763ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1355.188394ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r77c2d6253086","instance":"chief","turn":"492fcf7a-ee92-4637-b1ee-de6d29c5f536","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r0caee85973df","instance":"coder","turn":"a8f6e869-e911-4e61-8913-9bcb8c84bca5","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (844.874148ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rdd1124f17d39","instance":"chief","turn":"99cbfb5d-a0b1-4de7-b94b-855285416cea","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r3ee360b6ea6f","instance":"pm","turn":"3299c709-0616-4d80-878e-589213b2833a","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rdd1124f17d39","instance":"chief","turn":"aaef40d5-2c04-4a58-8019-3a9fed2740d3","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rdd1124f17d39","instance":"chief","turn":"f7697cc5-383e-41e4-8f48-ca8032cb501f","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r3ee360b6ea6f","instance":"pm","turn":"b6f5d1de-a58e-40de-9d2c-9e79472bc8f5","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r3ee360b6ea6f","instance":"pm","turn":"7a8278f1-c934-418d-a62a-34528048a50c","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rdd1124f17d39","instance":"chief","turn":"c8f0554c-b415-4b2c-aa8e-8eebf3253c12","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r3ee360b6ea6f","instance":"pm","turn":"d5084f6b-43d9-48b4-ada8-14c78f9a6472","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rdd1124f17d39","instance":"chief","turn":"2b8f60d0-5e87-4823-a4c8-e7a13fdffae2","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 (1499.426496ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (4214.335578ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (731.541713ms)
|
||||
✔ 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 (452.219971ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r8dca21c7af83","instance":"coder","turn":"b0a65410-42a5-495d-a881-d7828ea5dc69","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 (859.92414ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (813.442124ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (1026.204746ms)
|
||||
✔ 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 (698.000891ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (333.63354ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (392.682058ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (219.352153ms)
|
||||
✔ a pi launch with no own credential refuses no-session-credential (202.834512ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/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 (214.464488ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (437.720138ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (240.940882ms)
|
||||
✔ 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 (220.344629ms)
|
||||
✔ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (288.705681ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (211.010194ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r31e317a9ff60","instance":"chief","turn":"bf22f39d-2bf0-48ec-849b-bf8665a262af","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rcb1b05afaad6","instance":"coder","turn":"40f65cf7-8938-4265-949a-c816ef7084cd","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 (1532.310766ms)
|
||||
✔ 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 (1163.295788ms)
|
||||
✔ 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 (4129.096956ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (253.012747ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (210.12322ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1206.988059ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (200.617792ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (208.31407ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (210.5977ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1396.242105ms)
|
||||
✔ kill switch refuses chief and hire before launch work and a clear permits a later request (356.328128ms)
|
||||
✔ kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle (411.659934ms)
|
||||
✔ a launch waiting across halt and resume cannot use its stale admission (248.122427ms)
|
||||
ℹ tests 35
|
||||
ℹ suites 0
|
||||
ℹ pass 34
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 29678.41987
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:714:1
|
||||
✖ row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason (214.464488ms)
|
||||
Error [CliError]: PM launch refused: no-session-credential (fallback fixture: pi needs its own provider key or a session proxy key (primary down: fixture preflight fails))
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/cli/src/launcher.mjs:1189:23
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
|
||||
exitCode: 3,
|
||||
code: 'no-session-credential'
|
||||
}
|
||||
exit=1
|
||||
23:57:42Z
|
||||
@@ -0,0 +1,88 @@
|
||||
23:57:12Z
|
||||
nice=19
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (8.82863ms)
|
||||
✔ P3 omitted route generates the Anthropic provider at proxy root (3.493006ms)
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (2.169226ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.321456ms)
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (2.285532ms)
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (2.062519ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 94.962091
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:35:1
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (8.82863ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:36: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:57:1
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (2.169226ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:58: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:68:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.321456ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:69: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:79:1
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (2.285532ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:81: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:94:1
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (2.062519ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:354:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:95:17)
|
||||
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)
|
||||
exit=1
|
||||
23:57:12Z
|
||||
@@ -0,0 +1,17 @@
|
||||
23:57:06Z
|
||||
nice=19
|
||||
✔ P3 Claude env receives the session proxy URL and key, without another agent or host credential (2.459573ms)
|
||||
✔ P3 Claude preflight accepts a proxy key without a host provider credential (1.019636ms)
|
||||
✔ P3 pi refuses no-session-credential with no provider key (0.965529ms)
|
||||
✔ P3 pi refuses no-session-credential with only a Claude OAuth token (0.264623ms)
|
||||
✔ P3 pi accepts its own provider key or a session proxy key (0.345262ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 56.359357
|
||||
exit=0
|
||||
23:57:06Z
|
||||
@@ -0,0 +1,14 @@
|
||||
23:57:06Z
|
||||
nice=19
|
||||
✔ P3 proxy sessionEnv removes every instance provider credential without widening ENV_ALLOW (0.976855ms)
|
||||
✔ P3 no proxy retains the full existing allowlist and run environment (0.214793ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 47.349955
|
||||
exit=0
|
||||
23:57:06Z
|
||||
@@ -0,0 +1,42 @@
|
||||
// Parse static imports without evaluating any repository module. This is an audit tool, not a test runner.
|
||||
// Usage: node --experimental-vm-modules agents/fethry/work/queue-332/import-run-list.mjs
|
||||
import { readdirSync, readFileSync } from 'node:fs';
|
||||
import { dirname, join, relative, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { SourceTextModule } from 'node:vm';
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
|
||||
const files = [];
|
||||
function walk(dir) {
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
if (['node_modules', '.git', 'dist'].includes(entry.name)) continue;
|
||||
const path = join(dir, entry.name);
|
||||
if (entry.isDirectory()) walk(path);
|
||||
else if (entry.isFile() && path.endsWith('.mjs')) files.push(path);
|
||||
}
|
||||
}
|
||||
for (const dir of ['packages', 'scripts', 'adapters']) walk(join(root, dir));
|
||||
const graph = new Map();
|
||||
for (const file of files) {
|
||||
const module = new SourceTextModule(readFileSync(file, 'utf8'), { identifier: file });
|
||||
graph.set(file, module.dependencySpecifiers.filter(spec => spec.startsWith('.')).map(spec => resolve(dirname(file), spec)));
|
||||
}
|
||||
// The loader imports the configured harness via a computed path. Explicit runtime import edges:
|
||||
const loader = join(root, 'packages/plugins/src/loader.mjs');
|
||||
graph.get(loader).push(...['claude-code', 'pi'].map(name => join(root, 'packages/plugins/harness', name, 'index.mjs')));
|
||||
const changed = new Set([
|
||||
'packages/seat/src/session.mjs', 'packages/business/src/launch.mjs',
|
||||
'packages/plugins/harness/claude-code/index.mjs', 'packages/plugins/harness/pi/index.mjs',
|
||||
'packages/harness/src/bundle.mjs', 'packages/cli/src/launcher.mjs',
|
||||
].map(file => join(root, file)));
|
||||
function affected(file, seen = new Set()) {
|
||||
if (changed.has(file)) return true;
|
||||
if (seen.has(file)) return false;
|
||||
seen.add(file);
|
||||
return (graph.get(file) ?? []).some(dep => affected(dep, seen));
|
||||
}
|
||||
const excluded = 'packages/cli/tests/case1-accept.test.mjs';
|
||||
for (const file of files.filter(file => file.endsWith('.test.mjs')).sort()) {
|
||||
if (!affected(file)) continue;
|
||||
const path = relative(root, file);
|
||||
console.log(`${path === excluded ? 'EXCLUDED (mos-1612) ' : ''}${path}`);
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
// Row332 evidence. The only network-capable phase is the single authorized fetch.
|
||||
// offline runs in unshare -rn; a transparent local tap records pi payload shapes
|
||||
// without retaining headers, then pipes bytes unchanged to the pinned proxy.
|
||||
import { mkdirSync, readFileSync, readlinkSync, writeFileSync } from 'node:fs';
|
||||
import { dirname, join, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { getPriority, setPriority, networkInterfaces } from 'node:os';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { once } from 'node:events';
|
||||
import http from 'node:http';
|
||||
import { fetchPinned } from '../../../../packages/model-proxy/src/fetch.mjs';
|
||||
import { PIN } from '../../../../packages/model-proxy/src/common.mjs';
|
||||
import { initialConfig, verifyInstall } from '../../../../packages/model-proxy/src/settings.mjs';
|
||||
const root = process.env.P3_EVIDENCE_ROOT;
|
||||
if (!root || !root.startsWith('/mnt/storage/scratch/') || resolve(root) !== root) throw Error('owned evidence root required');
|
||||
const enteredNice = getPriority(0);
|
||||
setPriority(0, 19);
|
||||
const repo = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
|
||||
const mode = process.argv[2];
|
||||
const fakeKeys = ['fx332-client', 'fx332-upstream', 'fx332-manage'];
|
||||
function redact(value) {
|
||||
let text = String(value);
|
||||
for (const key of fakeKeys) text = text.split(key).join('[redacted]');
|
||||
return text;
|
||||
}
|
||||
const emit = (value) => console.log(redact(JSON.stringify(value)));
|
||||
if (mode === 'fetch') {
|
||||
const dataRoot = join(root, 'data');
|
||||
mkdirSync(dataRoot, { mode: 0o700 });
|
||||
const installed = await fetchPinned({ dataRoot, pin: PIN });
|
||||
writeFileSync(join(root, 'installed.json'), JSON.stringify(installed) + '\n', { mode: 0o600, flag: 'wx' });
|
||||
emit({ phase: 'fetch', version: PIN.version, binarySha256: PIN.binary.sha256,
|
||||
panelVersion: PIN.panel.version, panelSha256: PIN.panel.sha256, enteredNice, nice: getPriority(0), verified: true });
|
||||
} else if (mode === 'offline' || mode === 'glm-tool') {
|
||||
const withTool = mode === 'glm-tool';
|
||||
if (readlinkSync('/proc/self/ns/net') === process.env.P3_HOST_NET_NS) throw Error('network namespace was not isolated');
|
||||
if (Object.keys(networkInterfaces()).some(name => name !== 'lo')) throw Error('loopback-only namespace required');
|
||||
// Re-hash the already fetched assets; this function performs no network I/O.
|
||||
const installed = verifyInstall(join(root, 'data'), PIN);
|
||||
const attemptRoot = join(root, withTool ? 'attempt3-tool' : 'attempt2');
|
||||
mkdirSync(attemptRoot, { mode: 0o700 });
|
||||
setPriority(0, 19);
|
||||
emit({ phase: 'isolation', interfaces: Object.keys(networkInterfaces()), enteredNice, nice: getPriority(0), version: PIN.version,
|
||||
binarySha256: PIN.binary.sha256, panelSha256: PIN.panel.sha256, reverified: true });
|
||||
const requests = [], responses = [], upstreamRequests = [], children = new Set();
|
||||
const managed = (args, options = {}) => {
|
||||
setPriority(0, 19);
|
||||
const child = spawn('/usr/bin/timeout', ['-k', '10', ...args], { env: {
|
||||
PATH: '/usr/bin:/bin', HOME: join(root, 'home'), TMPDIR: process.env.TMPDIR,
|
||||
LANG: 'C.UTF-8', ...options.env,
|
||||
}, cwd: root, stdio: ['ignore', 'pipe', 'pipe'] });
|
||||
children.add(child);
|
||||
setPriority(child.pid, 19);
|
||||
child.once('close', () => children.delete(child));
|
||||
return child;
|
||||
};
|
||||
const summary = body => ({ keys: Object.keys(body).sort(), model: body.model, stream: body.stream,
|
||||
roles: Array.isArray(body.messages) ? body.messages.map(message => message.role) : undefined,
|
||||
inputTypes: Array.isArray(body.input) ? body.input.map(item => item.type) : typeof body.input,
|
||||
...(Object.hasOwn(body, 'reasoning') ? { reasoning: body.reasoning } : {}),
|
||||
...(Object.hasOwn(body, 'thinking') ? { thinking: body.thinking } : {}),
|
||||
...(Object.hasOwn(body, 'reasoning_effort') ? { reasoning_effort: body.reasoning_effort } : {}),
|
||||
...(Object.hasOwn(body, 'enable_thinking') ? { enable_thinking: body.enable_thinking } : {}),
|
||||
...(Object.hasOwn(body, 'tool_stream') ? { tool_stream: body.tool_stream } : {}),
|
||||
...(Array.isArray(body.tools) ? { toolNames: body.tools.map(tool => tool.function?.name) } : {}),
|
||||
...(Object.hasOwn(body, 'stream_options') ? { stream_options: body.stream_options } : {}),
|
||||
...(Object.hasOwn(body, 'max_tokens') ? { max_tokens: body.max_tokens } : {}),
|
||||
...(Object.hasOwn(body, 'max_completion_tokens') ? { max_completion_tokens: body.max_completion_tokens } : {}) });
|
||||
const payload = async req => { let text = ''; for await (const part of req) text += part; return JSON.parse(text || '{}'); };
|
||||
const listen = async server => { await new Promise((ok, no) => { server.once('error', no); server.listen(0, '127.0.0.1', ok); }); return server.address().port; };
|
||||
const marker = 'P332_OFFLINE_OK';
|
||||
const upstream = http.createServer(async (req, res) => {
|
||||
const body = await payload(req);
|
||||
upstreamRequests.push({ method: req.method, path: req.url, ...summary(body) });
|
||||
const item = { id: 'msg_fixture', type: 'message', role: 'assistant', status: 'completed', content: [{ type: 'output_text', text: marker, annotations: [] }] };
|
||||
if (req.url.endsWith('/chat/completions')) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
|
||||
const chunk = (delta, finish_reason = null) => res.write(`data: ${JSON.stringify({ id: 'chat_fixture', object: 'chat.completion.chunk', created: 1, model: body.model, choices: [{ index: 0, delta, finish_reason }] })}\n\n`);
|
||||
chunk({ role: 'assistant', content: marker }); chunk({}, 'stop');
|
||||
res.write(`data: ${JSON.stringify({ id: 'chat_fixture', object: 'chat.completion.chunk', created: 1, model: body.model, choices: [], usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 } })}\n\n`);
|
||||
res.end('data: [DONE]\n\n');
|
||||
} else if (req.url.endsWith('/responses')) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
|
||||
const event = (type, more) => res.write(`event: ${type}\ndata: ${JSON.stringify({ type, ...more })}\n\n`);
|
||||
const response = { id: 'resp_fixture', object: 'response', model: body.model, status: 'in_progress', output: [] };
|
||||
event('response.created', { response });
|
||||
event('response.output_item.added', { output_index: 0, item: { ...item, status: 'in_progress', content: [] } });
|
||||
event('response.content_part.added', { item_id: item.id, output_index: 0, content_index: 0, part: { type: 'output_text', text: '', annotations: [] } });
|
||||
event('response.output_text.delta', { item_id: item.id, output_index: 0, content_index: 0, delta: marker });
|
||||
event('response.output_text.done', { item_id: item.id, output_index: 0, content_index: 0, text: marker });
|
||||
event('response.output_item.done', { output_index: 0, item });
|
||||
event('response.completed', { response: { ...response, status: 'completed', output: [item], usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 } } });
|
||||
res.end();
|
||||
} else { res.writeHead(404); res.end('{"error":"stand-in path refused"}'); }
|
||||
});
|
||||
let proxy, tap;
|
||||
let proxyText = '';
|
||||
const corrections = {};
|
||||
const restoreNice = pid => {
|
||||
try {
|
||||
const priority = getPriority(pid);
|
||||
if (priority !== 19) { corrections[priority] = (corrections[priority] ?? 0) + 1; setPriority(pid, 19); }
|
||||
const descendants = readFileSync(`/proc/${pid}/task/${pid}/children`, 'utf8').trim().split(/\s+/).filter(Boolean);
|
||||
for (const child of descendants) restoreNice(Number(child));
|
||||
} catch {}
|
||||
};
|
||||
const keepNice = setInterval(() => restoreNice(process.pid), 100);
|
||||
keepNice.unref();
|
||||
try {
|
||||
const upstreamPort = await listen(upstream);
|
||||
const reservation = http.createServer(); const proxyPort = await listen(reservation);
|
||||
await new Promise(ok => reservation.close(ok));
|
||||
if (proxyPort === 8317 || upstreamPort === 8317) throw Error('reserved host-proxy port excluded');
|
||||
const dataRoot = join(attemptRoot, 'offline');
|
||||
mkdirSync(dataRoot, { mode: 0o700 });
|
||||
mkdirSync(join(dataRoot, 'proxy'), { mode: 0o700 });
|
||||
mkdirSync(join(dataRoot, 'proxy', 'auth'), { mode: 0o700 });
|
||||
const config = initialConfig({ dataRoot, port: proxyPort, key: fakeKeys[2], sentinel: fakeKeys[0] });
|
||||
config.management['disable-control-panel'] = true;
|
||||
config.observability.logs['logging-to-file'] = false;
|
||||
// Bundled panel1.26.7: Ip reads api-keys.openai-compatibility;
|
||||
// Fp/Np require group.keys; xv/hv serialize keys:[{"api-key":...}].
|
||||
config['api-keys'] = { 'openai-compatibility': [{ name: 'p332-standin', 'base-url': `http://127.0.0.1:${upstreamPort}/v1`,
|
||||
keys: [{ 'api-key': fakeKeys[1] }], models: [{ name: 'gpt-fixture' }, { name: 'glm-fixture' }] }] };
|
||||
const configFile = join(dataRoot, 'config.yaml');
|
||||
writeFileSync(configFile, JSON.stringify(config, null, 2) + '\n', { mode: 0o600, flag: 'wx' });
|
||||
proxy = managed(['200', installed.binary, '-config', configFile, '-local-model'], { env: { MANAGEMENT_STATIC_PATH: dirname(installed.panel) } });
|
||||
proxy.stdout.on('data', bytes => { proxyText += bytes; });
|
||||
proxy.stderr.on('data', bytes => { proxyText += bytes; });
|
||||
let catalog, ids = [];
|
||||
const readinessDeadline = Date.now() + 30000;
|
||||
for (let poll = 1; Date.now() < readinessDeadline; poll++) {
|
||||
if (proxy.exitCode !== null) throw Error('proxy exited before readiness');
|
||||
try {
|
||||
const result = await fetch(`http://127.0.0.1:${proxyPort}/v1/models`, { headers: { Authorization: `Bearer ${fakeKeys[0]}` }, signal: AbortSignal.timeout(1000) });
|
||||
catalog = result.ok ? await result.json() : null;
|
||||
ids = (catalog?.data ?? []).map(model => model.id);
|
||||
emit({ phase: 'readiness', poll, status: result.status, modelCount: ids.length });
|
||||
if (['gpt-fixture', 'glm-fixture'].every(id => ids.includes(id))) break;
|
||||
} catch { emit({ phase: 'readiness', poll, status: 'not-ready', modelCount: 0 }); }
|
||||
await new Promise(ok => setTimeout(ok, 1000));
|
||||
}
|
||||
if (!catalog) throw Error('proxy readiness failed');
|
||||
emit({ phase: 'catalog', modelIds: ids });
|
||||
if (!['gpt-fixture', 'glm-fixture'].every(id => ids.includes(id))) throw Error('stand-in routes absent from proxy catalog');
|
||||
tap = http.createServer(async (req, res) => {
|
||||
let raw = ''; for await (const part of req) raw += part;
|
||||
const body = JSON.parse(raw || '{}');
|
||||
const index = requests.push({ method: req.method, path: req.url, ...summary(body) }) - 1;
|
||||
const outgoing = http.request({ hostname: '127.0.0.1', port: proxyPort, method: req.method, path: req.url,
|
||||
headers: { ...req.headers, host: `127.0.0.1:${proxyPort}` } }, incoming => {
|
||||
const chunks = [];
|
||||
res.writeHead(incoming.statusCode, incoming.headers);
|
||||
incoming.on('data', bytes => { chunks.push(bytes); res.write(bytes); });
|
||||
incoming.on('end', () => {
|
||||
const text = Buffer.concat(chunks).toString();
|
||||
const events = text.split('\n').filter(line => line.startsWith('event: ')).map(line => line.slice(7));
|
||||
responses.push({ request: index, status: incoming.statusCode, events, marker: text.includes(marker),
|
||||
...(incoming.statusCode >= 400 ? { errorBody: redact(text).slice(0, 800) } : {}) });
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
outgoing.on('error', () => { res.writeHead(502); res.end(); });
|
||||
// Preserve exact body bytes and never log a header value.
|
||||
outgoing.end(raw);
|
||||
});
|
||||
const tapPort = await listen(tap);
|
||||
if (tapPort === 8317) throw Error('reserved host-proxy port excluded');
|
||||
const scenarios = [
|
||||
['gpt-responses', 'openai-responses', 'gpt-fixture', null],
|
||||
['gpt-completions', 'openai-completions', 'gpt-fixture', null],
|
||||
['glm-completions', 'openai-completions', 'glm-fixture', { thinkingFormat: 'zai', zaiToolStream: true }],
|
||||
];
|
||||
for (const [name, api, model, compat] of (withTool ? scenarios.filter(([name]) => name === 'glm-completions') : scenarios)) {
|
||||
const turnHome = join(attemptRoot, name, 'home');
|
||||
const agentDir = join(turnHome, '.pi', 'agent');
|
||||
mkdirSync(agentDir, { recursive: true, mode: 0o700 });
|
||||
const models = { providers: { 'p332-probe': { baseUrl: `http://127.0.0.1:${tapPort}/v1`, api,
|
||||
apiKey: '$ANTHROPIC_API_KEY', ...(compat ? { compat } : {}), models: [{ id: model, reasoning: true }] } } };
|
||||
writeFileSync(join(agentDir, 'models.json'), JSON.stringify(models) + '\n', { mode: 0o600, flag: 'wx' });
|
||||
writeFileSync(join(agentDir, 'settings.json'), JSON.stringify({ retry: { enabled: false, maxRetries: 0, provider: { maxRetries: 0 } } }) + '\n', { mode: 0o600, flag: 'wx' });
|
||||
const reqStart = requests.length, upstreamStart = upstreamRequests.length, responseStart = responses.length;
|
||||
const pi = managed(['50', '/usr/bin/node', join(repo, 'node_modules/@earendil-works/pi-coding-agent/dist/cli.js'),
|
||||
'--no-extensions', '--no-skills', '--no-prompt-templates', '--no-themes', '--no-context-files', '--no-session',
|
||||
...(withTool ? ['--tools', 'read'] : ['--no-tools']),
|
||||
'--provider', 'p332-probe', '--model', model, '--thinking', 'low', '-p', 'Reply P332_OFFLINE_OK only.'],
|
||||
{ env: { HOME: turnHome, PI_CODING_AGENT_DIR: agentDir, ANTHROPIC_API_KEY: fakeKeys[0] } });
|
||||
let stdout = '', stderr = '';
|
||||
pi.stdout.on('data', bytes => { stdout += bytes; });
|
||||
pi.stderr.on('data', bytes => { stderr += bytes; });
|
||||
const [exit, signal] = await once(pi, 'close');
|
||||
emit({ phase: 'turn', name: withTool ? `${name}-tool` : name, api, exit, signal, marker: stdout.includes(marker),
|
||||
piRequests: requests.slice(reqStart), proxyResponses: responses.slice(responseStart), upstreamRequests: upstreamRequests.slice(upstreamStart),
|
||||
...(exit !== 0 ? { stderr: redact(stderr).slice(0, 1200), stdout: redact(stdout).slice(0, 1200) } : {}), nice: getPriority(0) });
|
||||
}
|
||||
emit({ phase: 'conclusion', limitation: 'Stand-in openai-compatibility credential only; no Codex OAuth credential or real-auth turn. This script never selects the production API.' });
|
||||
emit({ phase: 'nice-corrections', restoredTo: 19, observedBeforeRestore: corrections });
|
||||
} catch (error) {
|
||||
emit({ phase: 'error', message: error.message, proxyDiagnostic: redact(proxyText).slice(-3000) });
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
clearInterval(keepNice);
|
||||
for (const child of [...children]) child.kill('SIGTERM');
|
||||
for (const child of [...children]) {
|
||||
await Promise.race([once(child, 'close'), new Promise(ok => setTimeout(ok, 1200))]);
|
||||
if (child.exitCode === null) child.kill('SIGKILL');
|
||||
}
|
||||
for (const server of [tap, upstream].filter(Boolean)) { server.closeAllConnections(); await new Promise(ok => server.close(ok)); }
|
||||
emit({ phase: 'cleanup', remainingManagedChildren: children.size });
|
||||
}
|
||||
} else { throw Error('fetch, offline or glm-tool phase required'); }
|
||||
@@ -0,0 +1,104 @@
|
||||
23:41:37Z
|
||||
nice=19
|
||||
✖ P3 proxy model validation preserves each explicit wire route and the proxy model id (0.843397ms)
|
||||
✖ P3 a proxy model without route refuses proxy-route-missing (0.621133ms)
|
||||
✖ P3 an unknown proxy route refuses proxy-route-unknown (1.448927ms)
|
||||
✔ P3 nonproxy models retain their provider/model-only shape and reject route metadata (0.541212ms)
|
||||
✖ P3 launch.account accepts the proxy credential source without naming host variables (0.159973ms)
|
||||
✔ P3 existing environment-set accounts retain their validated representation (0.209852ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 4
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 58.617716
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/proxy-launch.test.mjs:6:1
|
||||
✖ P3 proxy model validation preserves each explicit wire route and the proxy model id (0.843397ms)
|
||||
Error [BusinessError]: unsupported launch.models.selected key: "route"
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at rejectUnknownKeys (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/util.mjs:17:33)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/launch.mjs:18:5
|
||||
at Array.map (<anonymous>)
|
||||
at checkModels (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/launch.mjs:15:51)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:9:22)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/proxy-launch.test.mjs:13:1
|
||||
✖ P3 a proxy model without route refuses proxy-route-missing (0.621133ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:14:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'proxy-route-missing' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/proxy-launch.test.mjs:19:1
|
||||
✖ P3 an unknown proxy route refuses proxy-route-unknown (1.448927ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
+ Comparison {}
|
||||
- Comparison {
|
||||
- code: 'proxy-route-unknown'
|
||||
- }
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:21:12)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: BusinessError: unsupported launch.models.selected key: "route"
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at rejectUnknownKeys (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/util.mjs:17:33)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/launch.mjs:18:5
|
||||
at Array.map (<anonymous>)
|
||||
at checkModels (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/launch.mjs:15:51)
|
||||
at assert.throws.code (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:21:25)
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:21:12)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14),
|
||||
expected: { code: 'proxy-route-unknown' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/proxy-launch.test.mjs:34:1
|
||||
✖ P3 launch.account accepts the proxy credential source without naming host variables (0.159973ms)
|
||||
Error [BusinessError]: launch.account.credential must name environment variables, joined with "+"
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkAccount (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/launch.mjs:86:5)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/tests/proxy-launch.test.mjs:35:20)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
exit=1
|
||||
23:41:37Z
|
||||
@@ -0,0 +1,107 @@
|
||||
23:44:40Z
|
||||
nice=19
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (10.834783ms)
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (3.078049ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.606176ms)
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (2.917109ms)
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (2.778195ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 117.630612
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:35:1
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (10.834783ms)
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/gxWP/p332-ddGpq6/run/home/.pi/agent/models.json'
|
||||
at readFileSync (node:fs:621:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:28:43)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:36: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) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/gxWP/p332-ddGpq6/run/home/.pi/agent/models.json'
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:45:1
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (3.078049ms)
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/gxWP/p332-7vqUkh/run/home/.pi/agent/models.json'
|
||||
at readFileSync (node:fs:621:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:28:43)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:46: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) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/gxWP/p332-7vqUkh/run/home/.pi/agent/models.json'
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:56:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.606176ms)
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/gxWP/p332-xqR4OI/run/home/.pi/agent/models.json'
|
||||
at readFileSync (node:fs:621:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:28:43)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.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) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/gxWP/p332-xqR4OI/run/home/.pi/agent/models.json'
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:67:1
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (2.917109ms)
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/gxWP/p332-jAVWvp/run/home/.pi/agent/models.json'
|
||||
at readFileSync (node:fs:621:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:28:43)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:69: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) {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/gxWP/p332-jAVWvp/run/home/.pi/agent/models.json'
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:82:1
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (2.778195ms)
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/gxWP/p332-yUgdwP/run/home/.pi/agent/models.json'
|
||||
at readFileSync (node:fs:621:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:28:43)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:83:17)
|
||||
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: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/gxWP/p332-yUgdwP/run/home/.pi/agent/models.json'
|
||||
}
|
||||
exit=1
|
||||
23:44:40Z
|
||||
@@ -0,0 +1,99 @@
|
||||
23:42:41Z
|
||||
nice=19
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (6.017482ms)
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (1.65735ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (1.23753ms)
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (1.202284ms)
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (1.210998ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 88.02888
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:35:1
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (6.017482ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/gQE5/mosaic-harness-biz-FaxPH3/businesses/acme.json launch: instance pm selects unknown model a
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:204:125)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:310:57)
|
||||
at resolvedFor (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/helpers.mjs:46:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:17:20)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:36: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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:45:1
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (1.65735ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/gQE5/mosaic-harness-biz-rtXOnL/businesses/acme.json launch: instance pm selects unknown model z
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:204:125)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:310:57)
|
||||
at resolvedFor (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/helpers.mjs:46:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:17:20)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:46: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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:56:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (1.23753ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/gQE5/mosaic-harness-biz-IGXaeo/businesses/acme.json launch: instance pm selects unknown model g
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:204:125)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:310:57)
|
||||
at resolvedFor (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/helpers.mjs:46:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:17:20)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:67:1
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (1.202284ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/gQE5/mosaic-harness-biz-z5VTgc/businesses/acme.json launch: instance pm selects unknown model a
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:204:125)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:310:57)
|
||||
at resolvedFor (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/helpers.mjs:46:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:17:20)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:69: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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:82:1
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (1.210998ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/gQE5/mosaic-harness-biz-83xrrf/businesses/acme.json launch: instance pm selects unknown model a
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:204:125)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/business/src/business.mjs:310:57)
|
||||
at resolvedFor (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/helpers.mjs:46:20)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:17:20)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:83:17)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
exit=1
|
||||
23:42:41Z
|
||||
@@ -0,0 +1,77 @@
|
||||
23:41:42Z
|
||||
nice=19
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (8.181278ms)
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (1.652506ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (1.297337ms)
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (1.318875ms)
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (1.353193ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 104.116628
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:34:1
|
||||
✖ P3 Anthropic route uses messages at proxy root and the declared model id (8.181278ms)
|
||||
TypeError: Cannot assign to read only property 'vars' of object '#<Object>'
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:18:17)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:35: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:44:1
|
||||
✖ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (1.652506ms)
|
||||
TypeError: Cannot assign to read only property 'vars' of object '#<Object>'
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:18:17)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:45: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:55:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (1.297337ms)
|
||||
TypeError: Cannot assign to read only property 'vars' of object '#<Object>'
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:18:17)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:56: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:66:1
|
||||
✖ P3 models file is private, references the one session key, and stores no executable values or keys (1.318875ms)
|
||||
TypeError: Cannot assign to read only property 'vars' of object '#<Object>'
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:18:17)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:68: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)
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:81:1
|
||||
✖ P3 every launch regenerates proxy port, declared models and own key without caching (1.353193ms)
|
||||
TypeError: Cannot assign to read only property 'vars' of object '#<Object>'
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:18:17)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:82:17)
|
||||
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)
|
||||
exit=1
|
||||
23:41:42Z
|
||||
@@ -0,0 +1,78 @@
|
||||
23:41:55Z
|
||||
nice=19
|
||||
✔ C2-04: launcher workspace clones code but never the library (1499.521161ms)
|
||||
✖ P3 proxy key reaches the spawned runner but never session.json or the bundle (40.623657ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1361.267044ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r61b9e08ebd95","instance":"chief","turn":"a017a278-0466-41ec-b7d4-d05d7bb2b4e8","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r786eccbac72a","instance":"coder","turn":"5f857a62-f7e6-4662-a745-852935445baf","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (853.066ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"raa425c1d9f99","instance":"chief","turn":"94eec92a-4189-4188-abf0-c0dd27eb3f7a","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r91d263cb44fe","instance":"pm","turn":"b3030547-e499-4465-ba6f-387ca92e7b2e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"raa425c1d9f99","instance":"chief","turn":"2bb5f36b-953e-4f27-8368-d3cb77b0e68d","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r91d263cb44fe","instance":"pm","turn":"f393963d-90db-4cc3-ada0-9749bbe898e9","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r91d263cb44fe","instance":"pm","turn":"0fca073a-da7d-4cf2-953f-d590f37c6a9c","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"raa425c1d9f99","instance":"chief","turn":"9afffc56-5aca-4ac9-a8e9-ef50b859e54e","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r91d263cb44fe","instance":"pm","turn":"555642ca-00ee-4665-89ab-e68eee143f82","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"raa425c1d9f99","instance":"chief","turn":"1dad33fc-cbe9-404b-8752-3b68753ab199","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 (1303.262398ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (4218.830472ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (747.37249ms)
|
||||
✔ 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 (463.557222ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r18be47008dae","instance":"coder","turn":"52cd9cf6-57bd-41bf-96c0-fedd9ff9c092","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 (763.066104ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (706.701053ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (956.687674ms)
|
||||
✔ 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 (721.85447ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (395.757947ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (463.349261ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (235.420433ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (443.687348ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/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 (477.875324ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (491.276085ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (257.904073ms)
|
||||
✔ 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 (271.706852ms)
|
||||
✔ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (374.032091ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (266.897065ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r505be704086e","instance":"chief","turn":"d3144fd2-644c-4bf1-95b5-5914f45dd040","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r505be704086e","instance":"chief","turn":"c61a5cf2-9714-4e2a-a335-a48d0d1dc430","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r96a1ff87bc5e","instance":"coder","turn":"bc58500e-35cc-47b5-b849-a56aa0438ace","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 (1866.534461ms)
|
||||
✔ 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 (1438.787679ms)
|
||||
✔ 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 (4207.748283ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (275.473348ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (235.254265ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1246.476055ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (188.603222ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (194.710702ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (204.602445ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1400.602264ms)
|
||||
✔ kill switch refuses chief and hire before launch work and a clear permits a later request (396.558108ms)
|
||||
✔ kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle (362.427202ms)
|
||||
✔ a launch waiting across halt and resume cannot use its stale admission (218.641499ms)
|
||||
ℹ tests 35
|
||||
ℹ suites 0
|
||||
ℹ pass 34
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 29700.689398
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:150:1
|
||||
✖ P3 proxy key reaches the spawned runner but never session.json or the bundle (40.623657ms)
|
||||
Error [CliError]: unsupported /mnt/storage/scratch/tmp/gmDV/mosaic-launch-PVUXgr/config/businesses/acme.json launch.models.claude-opus-5-5 key: "route"
|
||||
at business (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/cli/src/config.mjs:45:47)
|
||||
at bootConfig (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/cli/src/config.mjs:126:10)
|
||||
at setup (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/cli/tests/launcher.test.mjs:99:16)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/cli/tests/launcher.test.mjs:156:34)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
exit=1
|
||||
23:42:25Z
|
||||
@@ -0,0 +1,98 @@
|
||||
23:42:41Z
|
||||
nice=19
|
||||
✖ P3 Claude env receives the session proxy URL and key, without another agent or host credential (3.24785ms)
|
||||
✖ P3 Claude preflight accepts a proxy key without a host provider credential (1.57681ms)
|
||||
✖ P3 pi refuses no-session-credential with no provider key (1.085777ms)
|
||||
✖ P3 pi refuses no-session-credential with only a Claude OAuth token (0.464216ms)
|
||||
✔ P3 pi accepts its own provider key or a session proxy key (0.351842ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 4
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 71.435137
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:24:1
|
||||
✖ P3 Claude env receives the session proxy URL and key, without another agent or host credential (3.24785ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ undefined
|
||||
- 'http://127.0.0.1:12345'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:30:12)
|
||||
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: undefined,
|
||||
expected: 'http://127.0.0.1:12345',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:39:1
|
||||
✖ P3 Claude preflight accepts a proxy key without a host provider credential (1.57681ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ {
|
||||
+ code: 'no-session-credential',
|
||||
+ message: "the bus host has none of CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL; the bus unit's EnvironmentFile sets one when the bus starts"
|
||||
+ }
|
||||
- null
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:44:10)
|
||||
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: { code: 'no-session-credential', message: "the bus host has none of CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL; the bus unit's EnvironmentFile sets one when the bus starts" },
|
||||
expected: null,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:49:1
|
||||
✖ P3 pi refuses no-session-credential with no provider key (1.085777ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ undefined
|
||||
- 'no-session-credential'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:51:10)
|
||||
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: undefined,
|
||||
expected: 'no-session-credential',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:54:1
|
||||
✖ P3 pi refuses no-session-credential with only a Claude OAuth token (0.464216ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ undefined
|
||||
- 'no-session-credential'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:56:10)
|
||||
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: undefined,
|
||||
expected: 'no-session-credential',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
exit=1
|
||||
23:42:41Z
|
||||
@@ -0,0 +1,82 @@
|
||||
23:41:44Z
|
||||
nice=19
|
||||
✖ P3 Claude env receives the session proxy URL and key, without another agent or host credential (0.739622ms)
|
||||
✖ P3 Claude preflight accepts a proxy key without a host provider credential (0.187719ms)
|
||||
✖ P3 pi refuses no-session-credential with no provider key (0.161237ms)
|
||||
✖ P3 pi refuses no-session-credential with only a Claude OAuth token (0.154227ms)
|
||||
✖ P3 pi accepts its own provider key or a session proxy key (0.168061ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 52.551274
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:24:1
|
||||
✖ P3 Claude env receives the session proxy URL and key, without another agent or host credential (0.739622ms)
|
||||
TypeError: Cannot destructure property 'log' of 'undefined' as it is undefined.
|
||||
at createLoader (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/src/loader.mjs:88:32)
|
||||
at harness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:11:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:25:24)
|
||||
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)
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:39:1
|
||||
✖ P3 Claude preflight accepts a proxy key without a host provider credential (0.187719ms)
|
||||
TypeError: Cannot destructure property 'log' of 'undefined' as it is undefined.
|
||||
at createLoader (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/src/loader.mjs:88:32)
|
||||
at harness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:11:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:40:24)
|
||||
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)
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:49:1
|
||||
✖ P3 pi refuses no-session-credential with no provider key (0.161237ms)
|
||||
TypeError: Cannot destructure property 'log' of 'undefined' as it is undefined.
|
||||
at createLoader (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/src/loader.mjs:88:32)
|
||||
at harness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:11:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:50:20)
|
||||
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)
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:54:1
|
||||
✖ P3 pi refuses no-session-credential with only a Claude OAuth token (0.154227ms)
|
||||
TypeError: Cannot destructure property 'log' of 'undefined' as it is undefined.
|
||||
at createLoader (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/src/loader.mjs:88:32)
|
||||
at harness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:11:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:55:20)
|
||||
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)
|
||||
|
||||
test at packages/plugins/tests/proxy-harness.test.mjs:59:1
|
||||
✖ P3 pi accepts its own provider key or a session proxy key (0.168061ms)
|
||||
TypeError: Cannot destructure property 'log' of 'undefined' as it is undefined.
|
||||
at createLoader (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/src/loader.mjs:88:32)
|
||||
at harness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:11:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/tests/proxy-harness.test.mjs:60:20)
|
||||
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)
|
||||
exit=1
|
||||
23:41:44Z
|
||||
@@ -0,0 +1,35 @@
|
||||
23:41:50Z
|
||||
nice=19
|
||||
✖ P3 proxy sessionEnv removes every instance provider credential without widening ENV_ALLOW (1.019646ms)
|
||||
✔ P3 no proxy retains the full existing allowlist and run environment (0.564867ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 46.658896
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/seat/tests/proxy-session-env.test.mjs:16:1
|
||||
✖ P3 proxy sessionEnv removes every instance provider credential without widening ENV_ALLOW (1.019646ms)
|
||||
AssertionError [ERR_ASSERTION]: CLAUDE_CODE_OAUTH_TOKEN
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/seat/tests/proxy-session-env.test.mjs:19:40)
|
||||
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: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
exit=1
|
||||
23:41:50Z
|
||||
@@ -0,0 +1,30 @@
|
||||
00:01:55Z
|
||||
nice=19
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (22.211777ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.666965ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (19.091287ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (15.98515ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (4.713343ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (20.35829ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (2.568186ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (9.763289ms)
|
||||
✔ Q169 assistants: vars and definition change and log the actor; tracker null leaves no tracker (16.756637ms)
|
||||
✔ Q169 assistants: refuses other instances, other definitions, holder and credentials, empty entries, a tracker the definition has no credential for and a stale revision (19.737439ms)
|
||||
✔ Q169 assistants: a definition with a vikunja credential takes a tracker change and refuses its removal or a used bot (12.898928ms)
|
||||
✔ row 65 routes lists every instance with harness, model, thinking and fallback, the switched-on harnesses, the model keys and each harness's levels (2.552837ms)
|
||||
✔ row 65 setRoutes saves a harness, model, thinking and whole fallback, reads each back from the file, logs the actor, and a null fallback clears all three (16.235475ms)
|
||||
✔ row 65 setRoutes refuses a partial fallback, a switched-off harness, a level the harness doesn't apply, an unloaded module, an unknown model or instance, a malformed route, no change and a stale revision, with the file unchanged (20.272464ms)
|
||||
✔ row 65 a file with harness vars and no plugins.harness loads and its views read; a model change still saves, and a route change refuses harness-off (10.564122ms)
|
||||
✔ B7 kept instance: the models keys it names and the instances key are the human's (26.878317ms)
|
||||
✔ B7 kept instance: its route is the human's (10.786018ms)
|
||||
✔ M10 creative instance: models keys it names, the instances key and its route are the human's (35.64373ms)
|
||||
ℹ tests 18
|
||||
ℹ suites 0
|
||||
ℹ pass 18
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 331.736961
|
||||
exit=0
|
||||
00:01:56Z
|
||||
@@ -0,0 +1,62 @@
|
||||
00:01:56Z
|
||||
nice=19
|
||||
✔ C2-04: launcher workspace clones code but never the library (1457.042303ms)
|
||||
✔ P3 proxy key reaches the spawned runner but never session.json or the bundle (1365.062806ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1374.325436ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"ra78486da0ed8","instance":"chief","turn":"9402e726-ac22-4423-aea9-cf7dcc35c134","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r49e89e37520e","instance":"coder","turn":"6bf40609-ae81-49b3-96d0-de2d5811b135","source":"@none","code":"baseline-unknown"}
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (836.256914ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf8408ce6a5b4","instance":"chief","turn":"e773abb1-268c-4404-a5da-81acd979905f","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r42524dd77612","instance":"pm","turn":"58e2bf95-0793-4495-bcdc-b27aa651caa1","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf8408ce6a5b4","instance":"chief","turn":"cb53fe60-e24f-4760-b284-d3b1d3620050","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r42524dd77612","instance":"pm","turn":"7460fc5d-aea2-4343-98a5-00d063c730c5","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r42524dd77612","instance":"pm","turn":"1ee4cbc7-90b7-4275-b3ac-4cbbd0394912","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf8408ce6a5b4","instance":"chief","turn":"1573dcc7-1d85-4783-b8c9-1a25c6ff71ac","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r42524dd77612","instance":"pm","turn":"bcb2aa05-7af5-4d9e-b085-c631754554ae","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"rf8408ce6a5b4","instance":"chief","turn":"9c77b01a-8f82-4d76-8e86-3eccdf5c05bc","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 (1399.028095ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (4193.990785ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (707.949813ms)
|
||||
✔ 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 (438.968553ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r33b3a0a89f29","instance":"coder","turn":"54d42057-6aeb-4460-bbbb-11bb7d96f6a0","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 (784.946481ms)
|
||||
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (733.626616ms)
|
||||
✔ after a restart, the new host's first tick starts a holder whose decision is still held (1104.180428ms)
|
||||
✔ 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 (766.099638ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (314.836965ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (380.228742ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (206.698491ms)
|
||||
✔ a pi launch with no own credential refuses no-session-credential (194.63649ms)
|
||||
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/down is missing","kept":[]}
|
||||
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/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 (395.760187ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (404.215037ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (204.482756ms)
|
||||
✔ 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 (223.681469ms)
|
||||
✔ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (294.218836ms)
|
||||
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (216.464613ms)
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r4b699771c38c","instance":"chief","turn":"77969cf2-7fc8-41ff-8d52-7569e054b6f8","source":"@none","code":"baseline-unknown"}
|
||||
usage: {"event":"usage-unknown","business":"acme","run":"r6e6168e49a89","instance":"coder","turn":"e6dfb039-1843-41b7-8111-7992cfddac3d","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 (2155.647443ms)
|
||||
✔ 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 (1620.990125ms)
|
||||
✔ 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 (4336.758535ms)
|
||||
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (279.143242ms)
|
||||
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (229.339371ms)
|
||||
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1236.511266ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (212.151607ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (201.563393ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (203.041695ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1399.240682ms)
|
||||
✔ kill switch refuses chief and hire before launch work and a clear permits a later request (362.776444ms)
|
||||
✔ kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle (400.610758ms)
|
||||
✔ a launch waiting across halt and resume cannot use its stale admission (221.918115ms)
|
||||
ℹ tests 35
|
||||
ℹ suites 0
|
||||
ℹ pass 35
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 30999.3545
|
||||
exit=0
|
||||
00:02:27Z
|
||||
@@ -0,0 +1,35 @@
|
||||
00:01:56Z
|
||||
nice=19
|
||||
✔ P3 Anthropic route uses messages at proxy root and the declared model id (11.574291ms)
|
||||
✔ P3 omitted route refuses proxy-route-missing before model config generation (2.072933ms)
|
||||
✔ P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility (2.699568ms)
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.510206ms)
|
||||
✔ P3 a declared Codex route refuses generation while the build-time API is PENDING (2.334352ms)
|
||||
✔ P3 models file is private, references the one session key, and stores no executable values or keys (3.084202ms)
|
||||
✔ P3 every launch regenerates proxy port, declared models and own key without caching (5.343868ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 108.561079
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/proxy-bundle.test.mjs:62:1
|
||||
✖ P3 GPT route selects a stack-owned provider instead of pi Codex OAuth (2.510206ms)
|
||||
Error: proxy GPT API is PENDING build-time evidence
|
||||
at Module.bundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/plugins/harness/pi/index.mjs:78:62)
|
||||
at buildBundle (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/src/bundle.mjs:359:23)
|
||||
at build (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:20:18)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332/packages/harness/tests/proxy-bundle.test.mjs:63: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)
|
||||
exit=1
|
||||
00:01:56Z
|
||||
@@ -0,0 +1,16 @@
|
||||
packages/business/tests/launch-settings.test.mjs:41: assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'missing',sonnet:'sonnet'}},f.file,{rolesDir:f.rolesDir}));assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.throws(()=>migrateLaunch(old,{...mapping,models:{...mapping.models,proxy:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}},instances:{pm:'proxy'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);const onlyOpus=structuredClone(old);onlyOpus.launch.max={opus:4};assert.throws(()=>migrateLaunch(onlyOpus,mapping,f.file,{rolesDir:f.rolesDir}),/unknown or ambiguous/);const allOpus=structuredClone(old);for(const r of Object.values(allOpus.roles))r.vars.model='claude-opus-5-5';assert.throws(()=>migrateLaunch(allOpus,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.equal(readFileSync(f.file,'utf8'),bytes);assert.equal(statSync(f.file).mtimeMs,mtime);
|
||||
packages/business/tests/launch-settings.test.mjs:45: const result=settings.set('acme',{revision:view.revision,limits:{total:0},instances:{coder:'opus'}},'jason');assert.equal(result.limits.total,0);assert.equal(result.instances.coder.modelKey,'opus');const models=structuredClone(result.models);models.opus.provider='proxy';models.opus.route='anthropic';const updated=settings.set('acme',{revision:result.revision,models},'jason');assert.equal(updated.instances.pm.provider,'proxy');assert.throws(()=>settings.set('acme',{revision:result.revision,instances:{coder:'ghost'}},'jason'));assert.throws(()=>settings.set('acme',{revision:result.revision,roles:{}},'jason'));
|
||||
packages/business/tests/launch-settings.test.mjs:154: const moved={...models,[key]:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
packages/business/tests/launch-settings.test.mjs:161: ({revision}=settings.set('acme',{revision,models:{...models,spare:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
packages/business/tests/launch-settings.test.mjs:188: const sonnet={...models,sonnet:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
packages/business/tests/launch-settings.test.mjs:198: ({revision}=settings.set('acme',{revision,models:{...models,opus:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
packages/business/tests/proxy-launch.test.mjs:8: const models = { selected: { provider: 'proxy', model: 'proxy-only-id', route } };
|
||||
packages/business/tests/proxy-launch.test.mjs:14: assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id' } }), {
|
||||
packages/business/tests/proxy-launch.test.mjs:21: assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id', route } }), {
|
||||
packages/cli/tests/launcher.test.mjs:155: doc.launch.models['claude-opus-5-5'] = { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' };
|
||||
packages/harness/tests/proxy-bundle.test.mjs:10: a: { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:11: z: { provider: 'proxy', model: 'glm-fixture', route: 'glm' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:12: g: { provider: 'proxy', model: 'gpt-fixture', route: 'codex' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:47: a: { provider: 'proxy', model: 'claude-fixture' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:97: a: { provider: 'proxy', model: 'changed-model-id', route: 'anthropic' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:98: z: { provider: 'proxy', model: 'changed-glm-id', route: 'glm' },
|
||||
@@ -0,0 +1,18 @@
|
||||
00:01:47Z
|
||||
nice=19
|
||||
✔ P3 proxy model validation preserves each explicit wire route and the proxy model id (1.21495ms)
|
||||
✔ P3 a proxy model without route refuses proxy-route-missing (0.356994ms)
|
||||
✔ P3 an unknown proxy route refuses proxy-route-unknown (0.767073ms)
|
||||
✔ P3 nonproxy models retain their provider/model-only shape and reject route metadata (0.17626ms)
|
||||
✔ P3 launch.account accepts the proxy credential source without naming host variables (0.179844ms)
|
||||
✔ P3 existing environment-set accounts retain their validated representation (0.312195ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 57.913873
|
||||
exit=0
|
||||
00:01:47Z
|
||||
@@ -0,0 +1,31 @@
|
||||
packages/business/tests/launch-settings.test.mjs:41: assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'missing',sonnet:'sonnet'}},f.file,{rolesDir:f.rolesDir}));assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.throws(()=>migrateLaunch(old,{...mapping,models:{...mapping.models,proxy:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}},instances:{pm:'proxy'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);const onlyOpus=structuredClone(old);onlyOpus.launch.max={opus:4};assert.throws(()=>migrateLaunch(onlyOpus,mapping,f.file,{rolesDir:f.rolesDir}),/unknown or ambiguous/);const allOpus=structuredClone(old);for(const r of Object.values(allOpus.roles))r.vars.model='claude-opus-5-5';assert.throws(()=>migrateLaunch(allOpus,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.equal(readFileSync(f.file,'utf8'),bytes);assert.equal(statSync(f.file).mtimeMs,mtime);
|
||||
packages/business/tests/launch-settings.test.mjs:45: const result=settings.set('acme',{revision:view.revision,limits:{total:0},instances:{coder:'opus'}},'jason');assert.equal(result.limits.total,0);assert.equal(result.instances.coder.modelKey,'opus');const models=structuredClone(result.models);models.opus.provider='proxy';models.opus.route='anthropic';const updated=settings.set('acme',{revision:result.revision,models},'jason');assert.equal(updated.instances.pm.provider,'proxy');assert.throws(()=>settings.set('acme',{revision:result.revision,instances:{coder:'ghost'}},'jason'));assert.throws(()=>settings.set('acme',{revision:result.revision,roles:{}},'jason'));
|
||||
packages/business/tests/launch-settings.test.mjs:154: const moved={...models,[key]:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
packages/business/tests/launch-settings.test.mjs:161: ({revision}=settings.set('acme',{revision,models:{...models,spare:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
packages/business/tests/launch-settings.test.mjs:188: const sonnet={...models,sonnet:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
packages/business/tests/launch-settings.test.mjs:198: ({revision}=settings.set('acme',{revision,models:{...models,opus:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
packages/business/tests/proxy-launch.test.mjs:8: const models = { selected: { provider: 'proxy', model: 'proxy-only-id', route } };
|
||||
packages/business/tests/proxy-launch.test.mjs:14: assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id' } }), {
|
||||
packages/business/tests/proxy-launch.test.mjs:21: assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id', route } }), {
|
||||
packages/business/tests/proxy-launch.test.mjs:35: assert.deepEqual(checkAccount({ name: 'proxy', credential: 'proxy' }), { name: 'proxy', credential: 'proxy' });
|
||||
packages/business/tests/proxy-launch.test.mjs:43: assert.throws(() => checkAccount({ name: 'proxy', credential }), /launch\.account\.credential/);
|
||||
packages/cli/tests/launcher.test.mjs:155: doc.launch.models['claude-opus-5-5'] = { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' };
|
||||
packages/cli/tests/model-proxy.test.mjs:11:test('proxy init agent and tester refuse before prompting or transport',async()=>{for(const args of [['proxy','init','--tester'],['proxy','init']]){const x=io(args.includes('--tester')?{}:{CODEX_THREAD_ID:'fixture'});await assert.rejects(main(args,x,{promptProxyKey:()=>{throw Error('must not prompt');}}),code('human-required'));}});
|
||||
packages/cli/tests/model-proxy.test.mjs:12:test('proxy init prompts twice through no-echo seam and sends key only through human transport',async()=>{const x=io();x.stdin.isTTY=true;x.stdout.isTTY=true;const prompts=[],calls=[];await main(['proxy','init','--business','demo','--port','18432'],x,{system:fakeSystem(),promptProxyKey:async()=>{prompts.push('hidden');return 'p1-management';},transport:b=>async(verb,args)=>{calls.push({b,verb,args});return {port:18432,binary:'/fixture'};}});assert.equal(prompts.length,2);assert.deepEqual(calls,[{b:'demo',verb:'proxy.init',args:{key:'p1-management',port:18432}}]);assert.equal(x.out.text.includes('p1-management'),false);});
|
||||
packages/cli/tests/model-proxy.test.mjs:13:test('proxy-key-mismatch: confirmation refuses without bus call',async()=>{const x=io();x.stdin.isTTY=true;x.stdout.isTTY=true;let count=0;await assert.rejects(main(['proxy','init','--business','demo'],x,{system:fakeSystem(),promptProxyKey:async()=>++count===1?'p1-one':'p1-two',transport:()=>()=>{throw Error('must not call');}}),code('proxy-key-mismatch'));});
|
||||
packages/cli/tests/model-proxy.test.mjs:14:test('proxy-terminal-required: stdin redirection refuses',async()=>{await assert.rejects(main(['proxy','init'],io(),{system:fakeSystem()}),code('proxy-terminal-required'));});
|
||||
packages/cli/tests/model-proxy.test.mjs:15:test('proxy-usage: invalid verb and repeated flags refuse',async()=>{for(const args of [['proxy','unknown'],['proxy','init','--port','18432','--port','18433']])await assert.rejects(main(args,io(),{system:fakeSystem()}),code('proxy-usage'));});
|
||||
packages/cli/tests/model-proxy.test.mjs:16:test('proxy-config-invalid: port 8317 refuses before prompting',async()=>await assert.rejects(main(['proxy','init','--port','8317'],io(),{system:fakeSystem()}),code('proxy-config-invalid')));
|
||||
packages/cli/tests/model-proxy.test.mjs:17:test('proxy-key-invalid: empty prompt refuses without printing input',async()=>{const x=io();x.stdin.isTTY=true;x.stdout.isTTY=true;await assert.rejects(main(['proxy','init','--business','demo'],x,{system:fakeSystem(),promptProxyKey:async()=>'',transport:()=>()=>{throw Error('must not call');}}),code('proxy-key-invalid'));});
|
||||
packages/harness/tests/proxy-bundle.test.mjs:10: a: { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:11: z: { provider: 'proxy', model: 'glm-fixture', route: 'glm' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:12: g: { provider: 'proxy', model: 'gpt-fixture', route: 'codex' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:47: a: { provider: 'proxy', model: 'claude-fixture' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:97: a: { provider: 'proxy', model: 'changed-model-id', route: 'anthropic' },
|
||||
packages/harness/tests/proxy-bundle.test.mjs:98: z: { provider: 'proxy', model: 'changed-glm-id', route: 'glm' },
|
||||
packages/model-proxy/tests/config-unit.test.mjs:14:test('loader proxy absent is byte-compatible; present validates sidecar and preserves config.json',()=>{const f=fixture(),before=readFileSync(f.file);let r=run(f,'scripts/mosaic-config.mjs',['validate']);assert.equal(r.status,0,r.stderr);assert.equal(Object.hasOwn(JSON.parse(r.stdout),'proxy'),false);const value=proxy(f);r=run(f,'scripts/mosaic-config.mjs',['validate']);assert.equal(r.status,0,r.stderr);assert.deepEqual(JSON.parse(r.stdout).proxy,value);assert.deepEqual(readFileSync(f.file),before);});
|
||||
packages/model-proxy/tests/config-unit.test.mjs:23:test('historical no-proxy config loader works without new package dependency',()=>{const f=fixture();const copy=join(f.root,'historical/scripts');mkdirSync(copy,{recursive:true});writeFileSync(join(copy,'mosaic-config.mjs'),readFileSync(join(repo,'scripts/mosaic-config.mjs')));const r=spawnSync(process.execPath,[join(copy,'mosaic-config.mjs'),'validate'],{env:f.env,encoding:'utf8',timeout:10000});assert.equal(r.status,0,r.stderr);assert.equal(Object.hasOwn(JSON.parse(r.stdout),'proxy'),false);});
|
||||
packages/model-proxy/tests/management-key-encoding.test.mjs:71: assert.deepEqual(added('data'), ['proxy', 'proxy/auth', 'proxy/config.yaml', 'proxy/logs']);
|
||||
packages/model-proxy/tests/runner.test.mjs:9:test('runner verifies before spawning and supplies pinned panel and local model without ambient secrets',()=>{const {root,config,install}=fixture();const calls=[],child=new EventEmitter();startVerifiedProxy(config,{env:{HOME:join(root,'home'),MANAGEMENT_PASSWORD:'p1-management',OPENAI_API_KEY:'p1-upstream'},verify:dir=>{calls.push(['verify',dir]);return install;},spawnImpl:(...args)=>{calls.push(['spawn',...args]);return child;}});assert.equal(calls[0][0],'verify');assert.deepEqual(calls[1],['spawn',install.binary,['-config',join(config.dataRoot,'proxy/config.yaml'),'-local-model'],{cwd:join(config.dataRoot,'proxy'),stdio:'inherit',env:{HOME:join(root,'home'),PATH:'/usr/bin:/bin',MANAGEMENT_STATIC_PATH:join(root,'pin/static')}}]);});
|
||||
packages/model-proxy/tests/settings.test.mjs:19:test('exclusive initialization writes private sentinel config, never rewrites config.json or exposes key',async()=>{const f=fixture();installed(f);const key='p1-management';const result=await initializeProxy({...f,pin,key});assert.ok(result.port>=1024&&result.port!==8317);assert.equal(JSON.stringify(result).includes(key),false);const conf=JSON.parse(readFileSync(join(f.dataRoot,'proxy/config.yaml'),'utf8'));assert.equal(conf.server.host,'127.0.0.1');assert.equal(conf.management['allow-remote'],false);assert.equal(conf.management['disable-auto-update-panel'],true);assert.equal(conf.routing.strategy,'fill-first');assert.equal(conf.routing.retry['request-retry'],0);assert.match(conf.access['api-keys'][0],/^msk-.*-sentinel-/);for(const file of [join(f.configDir,'secrets/proxy-management.key'),join(f.dataRoot,'proxy/config.yaml')])assert.equal(lstatSync(file).mode&0o777,0o600);for(const dir of ['proxy','proxy/auth','proxy/logs'])assert.equal(lstatSync(join(f.dataRoot,dir)).mode&0o777,0o700);assert.equal(readFileSync(join(f.configDir,'config.json'),'utf8'),'unchanged');await assert.rejects(initializeProxy({...f,pin,key}),code('proxy-already-initialized'));});
|
||||
packages/model-proxy/tests/settings.test.mjs:23:test('proxy-already-initialized: each existing target is preserved and never followed',async()=>{for(const target of ['proxy','key','settings']){const f=fixture();installed(f);let file;if(target==='proxy'){file=join(f.dataRoot,'proxy');mkdirSync(file);writeFileSync(join(file,'marker'),'old');}else if(target==='key'){mkdirSync(join(f.configDir,'secrets'),{mode:0o700});file=join(f.configDir,'secrets/proxy-management.key');writeFileSync(file,'old');}else{file=join(f.configDir,'proxy.json');writeFileSync(file,'old');}await assert.rejects(initializeProxy({...f,pin,key:'p1-management'}),code('proxy-already-initialized'));assert.equal(readFileSync(target==='proxy'?join(file,'marker'):file,'utf8'),'old');}});
|
||||
@@ -1,193 +0,0 @@
|
||||
# Row214 C2-11a work record
|
||||
|
||||
Assignment sage-2794 at2026-10-22T16:33:20Z, Q220/mos-1301, issue#1715.
|
||||
New isolated branch herb/row214 on aca16404c. The earlier197/215 worktrees
|
||||
and their dirty/untracked historical packets are untouched. node_modules is
|
||||
the required plain symlink to /mnt/storage/src/mosaic-stack/node_modules.
|
||||
|
||||
Read C2-11a in both pinned briefs. The section is unchanged at51cc0445c;
|
||||
Q222 changes C2-06's reply-limit settings, not wikilinks. The editor model,
|
||||
entry, view, existing model/browser/provenance tests, build/toolchain and
|
||||
vendored markdown parser/serializer were read. No third_party source changes.
|
||||
|
||||
## Static finding and authored work
|
||||
|
||||
model.mjs stores a canonical sig and the raw original block, and serialise
|
||||
returns raw when the sig matches. The vendored text writer escapes brackets
|
||||
(to_markdown.ts:433-437). It is therefore possible for no-edit round-trips
|
||||
to pass while dirty-block output escapes a wikilink. This is a source-based
|
||||
hypothesis, not a measured result. Both outcomes are in DESIGN.md.
|
||||
|
||||
Authored, unrun: the pinned-bundle measurement; ten fixture round-trips;
|
||||
three browser regressions; inert wikilink schema/tokenizer/serializer. The
|
||||
schema includes headings, and front matter remains raw. The serializer
|
||||
validates its spelling before bypassing escaping. HTML/entity-like targets
|
||||
stay text under the existing escaping rules. No clicking or resolution.
|
||||
|
||||
Local static git diff --check is clean. No Node, npm, compiler, browser,
|
||||
measurement, test, Docker, HTTPS Git or push has run. The queue claim waits
|
||||
for a gap because scripts/mosaic invokes Node. No candidate or pass claim.
|
||||
Only design/path documents may be committed before the granted red/green
|
||||
checks; product, tests and measurement remain uncommitted until validated.
|
||||
|
||||
## Next granted steps
|
||||
|
||||
1. Claim from canonical during a CLEAR/gap.
|
||||
2. Run measure.mjs against aca16404c's pinned Git blobs; save JSON unchanged.
|
||||
3. Run the structural/edit regression alone on the baseline bundle (red).
|
||||
4. Install the already-pinned esbuild0.28.2 in this worktree's packages/webui
|
||||
with npm ci --ignore-scripts --no-audit --no-fund; no root install or lock edit.
|
||||
5. Build with the existing editor/build.mjs, then the whole new test file and
|
||||
existing editor, editor-browser and editor-provenance files, each singly.
|
||||
6. Kill the serializer-removal mutant, restore, rebuild, focused green.
|
||||
7. Commit only after the applicable checks, push only when Sage clears HTTPS
|
||||
Git, send Filbert and Mos the candidate SHA/hash manifest directly, cc Sage.
|
||||
8. After253 lands, new branch on its tip preserving all landed changes.
|
||||
9. Filbert and Sage's whole webui and scripts gate finish the row.
|
||||
|
||||
All runs wait for explicit Sage CLEAR. Gander's row253 run5 owns the slot.
|
||||
The whole suite gate and any unexpected failure use mos-0823's stop rule.
|
||||
|
||||
Proposed SESSIONS text for Sage's post-253 doc sweep (do not append here):
|
||||
2026-10-22 | Herb (gpt-6.1-sol, f6cf4287) | row214 C2-11a editor wikilinks authoring | On herb/row214 at aca16404c, authored baseline round-trip measurement, designs for equal/unequal results, inert inline node and regression tests under sage-2794/Q220. Claim, runs and pushes held while253 owns the slot; measurement and test results unavailable.
|
||||
|
||||
## Filbert static design/path review accepted, R1 and R2 required
|
||||
|
||||
Review at2026-10-22T16:43:35Z read dee9f3d8d's packet only, no product or
|
||||
runs. R1 is now in the plan: set MOSAIC_REQUIRE_EDITOR_BUILD=1 on focused
|
||||
provenance and whole webui runs, grep ^# skip plus TAP/spec skip directives,
|
||||
and name every skip. Missing/wrong pinned esbuild must fail, not skip.
|
||||
R2: baseline no-edit roundTrips are expected to pass. They test retention
|
||||
of raw bytes and are not red evidence for the node. Only the baseline
|
||||
same-block structural/edit regression is expected red.
|
||||
|
||||
Two added fixtures cover a reference-definition collision and an atom
|
||||
inside ordinary link text, taking the planned file to10 no-edit tests and
|
||||
3 browser tests. The explicit & exclusion preserves the existing escaped
|
||||
HTML/entity writer for dirty blocks; Q&A stays text and is a known limit.
|
||||
Measurement VM setup matches loadEditor. Browser TMPDIR must use the short
|
||||
non-/tmp scratch root. Sweep Node/Chromium after mutant/timeout and at clear.
|
||||
All remain authored and unrun while253 owns the slot.
|
||||
|
||||
Filbert follow-up at2026-10-22T16:45:34Z: the authored N3 browser fixture
|
||||
now explicitly asserts the separate reference-definition block ends in its
|
||||
original exact bytes after the same-block edit. This test change is unrun
|
||||
and uncommitted with the other product/test authoring, pending CLEAR.
|
||||
|
||||
## R2 restart on current refactor, sage-4164
|
||||
|
||||
New worktree: /home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2.
|
||||
Branch herb/row214-r2, base487500a16f4ab5902c318509fdec6acc56a543ca.
|
||||
Carried dee9f3d8d and e2710e92a as67ac3c25a andde42a59d4. Copied only
|
||||
Herb's local model, new editor test/helper, measure.mjs and pending BUILD
|
||||
note. The old worktree remains untouched. No stash or force push.
|
||||
|
||||
The current editor model/build/toolchain/BUILD.json/shipped bundle and
|
||||
loader are identical to the old base. Entry/view and package dependencies
|
||||
are unchanged. The current test fixture adds configDirectory:root; its
|
||||
landed change is retained. The C2-11a brief section is unchanged. The
|
||||
visual-mode condition now lives at public/bus.js:1054. No product behavior
|
||||
beyond the accepted inert inline node is added by the rebase.
|
||||
|
||||
Row266 overlap: none. Our paths do not touch chat*.mjs, chat.js or chat.css,
|
||||
and the intersection with origin/fethry/row266's actual diff is empty.
|
||||
HASH-PINS.json records that ref's SHA and merge base.
|
||||
|
||||
Hash audit: grepped packages/*/tests for each actual/planned changed file
|
||||
and filename, and scanned495 test/fixture files for literal prior SHA256
|
||||
or Git-blob pins. No such pins found. Existing editor-provenance checks
|
||||
read BUILD.json dynamically; regenerating it and the bundle is required.
|
||||
The loader and browser/route tests use editor.js but pin no source hash.
|
||||
No tests or pin asserts were weakened. The complete references and planned
|
||||
generated paths are in HASH-PINS.json.
|
||||
|
||||
Sage-4164 explicitly permits the unrun node/tests to be committed now. This
|
||||
supersedes the earlier packet's instruction to keep them uncommitted until
|
||||
green. Static authoring is not a tested candidate. SOURCE.json records its
|
||||
source hashes and the unbuilt generated-output status. The measurement now
|
||||
pins this current execution base, not the historical accepted-doc base.
|
||||
|
||||
No Node, npm, measurement, compiler, test, browser, Docker or mutant has
|
||||
run. Claim already succeeded at rev3234 on10-22; no new queue move is
|
||||
needed. Push authorization is only herb/row214-r2. Row257's landing gate
|
||||
and then266 own the slot; all execution remains held for Sage's CLEAR.
|
||||
|
||||
Planned focused grant: baseline measurement; the same-block structural
|
||||
red; pinned npm ci/build; whole editor-wikilink.test.mjs (10 no-edit tests
|
||||
with/without a final newline and3 browser tests), editor.test.mjs,
|
||||
editor-browser.test.mjs and editor-provenance.test.mjs singly; one
|
||||
serializer-removal mutant and restored focused green. Set
|
||||
MOSAIC_REQUIRE_EDITOR_BUILD=1 for provenance and the later whole webui
|
||||
gate. Capture all skip names, raw logs, short scratch TMPDIR and final
|
||||
Node/Chromium process sweep. Two failures stop a gate; no rerun after an
|
||||
out-of-row failure without reporting to Sage.
|
||||
|
||||
## Filbert R2 static B1 fixed before execution
|
||||
|
||||
Review at2026-10-24T17:14:55Z confirmed a defect in the authored invalid
|
||||
atom path: state.text alone lacks the text-node override's HTML/entity
|
||||
escaping. Factored that existing policy into escapedText and reused it for
|
||||
invalid atoms. Extended the test payload/assertions to cover both <img and
|
||||
©. Valid atom behavior is unchanged. Excluded backticks from atom
|
||||
recognition and added a text/code precedence fixture for N1.
|
||||
|
||||
Requested focused-grant addition: a second mutant that swaps only the
|
||||
invalid-atom escapedText call for vendored state.text, dropping the <&
|
||||
escape for this path. The existing malformed-attrs browser test must kill
|
||||
it. The original serializer-removal mutant is still required. No runs,
|
||||
checks, installation or rebuild have occurred; all remain held for CLEAR.
|
||||
|
||||
## Granted execution and candidate, sage-4286, 2026-10-24
|
||||
|
||||
Granted lane B until22:40Z. Ran on2ec3f5b5d's source in this worktree.
|
||||
Every child inherited TMPDIR=/mnt/storage/scratch/tmp/g49X, obtained by
|
||||
mktemp -d /mnt/storage/scratch/tmp/gXXX, never /tmp. Each command used
|
||||
`nice -n "$((19 - $(nice)))" timeout -k 10 ...` with pipefail and tee;
|
||||
raw logs record actual absolute nice19 and MOSAIC_REQUIRE_EDITOR_BUILD=1.
|
||||
Node test concurrency was1 for each focused whole file and2 for webui.
|
||||
|
||||
Measurement22:07:22Z: all10 baseline forms round-trip byte for byte. The
|
||||
JSON is copied unchanged to measurement.json. Adopted outcome A: no
|
||||
measured file falls to Source just because of its wikilink. The atom is
|
||||
proved by structure and same-block edits, not no-edit raw retention.
|
||||
Baseline structural case:0/1 expected red, no atom in old shipped bundle.
|
||||
|
||||
Pinned npm ci --ignore-scripts --no-audit --no-fund succeeded locally in
|
||||
packages/webui, then editor/build.mjs ran with esbuild0.28.2. The existing
|
||||
upstream sideEffects warning for mark.ts appeared; no vendored file changed.
|
||||
No package/lockfile change. Rebuild provenance ran and passed, not skipped.
|
||||
|
||||
| Whole file | Pass/fail | Wall seconds |
|
||||
| --- | ---: | ---: |
|
||||
| editor-wikilink.test.mjs | 13/0 | 2.348 |
|
||||
| editor.test.mjs | 5/0 | 2.053 |
|
||||
| editor-browser.test.mjs | 16/0 | 14.984 |
|
||||
| editor-provenance.test.mjs | 6/0 | 0.343 |
|
||||
|
||||
Two mutants, each independently restored and rebuilt: serializer removal
|
||||
failed the structural case0/1, restore1/0; invalid-path escapedText swapped
|
||||
for vendored state.text failed malformed attrs0/1, restore1/0. The model
|
||||
and generated outputs match their original good hashes after both.
|
||||
Post-mutant cwd/temp-root sweep0. Both failures are expected evidence.
|
||||
|
||||
Full webui: exactly69 files,455/0,0 skipped/cancelled,174.189s, ended
|
||||
22:12:48.880975Z. The log contains the required-build env and nice19.
|
||||
Skip scan for ^# skip, TAP # SKIP and spec skipped-test lines found none,
|
||||
so skip names are []. A preliminary command mistakenly selected7 files;
|
||||
its28/0 in17.787s is archived as webui-whole.log and explicitly NOT used
|
||||
as full gate evidence. The corrected69-file run is webui-69.log.
|
||||
|
||||
Final cwd/TMPDIR/argv sweep22:13:17.560692Z:0 processes. No owned Node or
|
||||
Chromium remains. Removed the private TMPDIR only after that zero sweep.
|
||||
Clear was sent to Sage as herb-0102 at22:13:46Z; no further execution.
|
||||
|
||||
Bundle SHA256 bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72.
|
||||
CSS SHA2568654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f,
|
||||
byte-identical to2ec3f5b5d. BUILD.json outputs match those hashes. Source
|
||||
commit a530a60798bf48eb18bb9e225d099faf5c2975cf adds generated outputs and
|
||||
an append-only phase log; packet changes follow separately. No code or
|
||||
assertion changed after these results. The webui gate requirement is met
|
||||
on this tree; Filbert review and every scripts/test-*.sh remain pending.
|
||||
|
||||
Sage re-pinned the brief to case2-rows.md blob85e6fe2e under sage-4286;
|
||||
its C2-11a section is unchanged. No case1-accept file was in any run.
|
||||
@@ -1,168 +0,0 @@
|
||||
# C2-11a: an inert editor wikilink node
|
||||
|
||||
Base: aca16404c. Owner: Herb. Reviewer: Filbert. Issue: #1715.
|
||||
Authority: sage-2794, Q220/mos-1301. The assignment permits authoring the
|
||||
node and tests before the measurement slot. Runs, claim and pushes wait
|
||||
for Sage's CLEAR. After row253 lands, a new branch will carry the change
|
||||
onto its landing with every landed hunk retained.
|
||||
|
||||
## Measurement before choosing the explanation
|
||||
|
||||
Run agents/herb/work/queue-214/measure.mjs only on a granted slot. It loads
|
||||
aca16404c's editor.js and markdown-preview.js directly from local Git
|
||||
objects. It verifies the editor bundle hash against that base's BUILD.json.
|
||||
It cannot accidentally measure a candidate rebuild. Its JSON records the
|
||||
full baseline SHA, bundle hash, timestamp, input, output and equality for
|
||||
each fixture. The first five are the brief's plain, labelled, heading,
|
||||
list and front-matter cases; extra cases cover a heading block, combined
|
||||
heading/label, Unicode/spacing, adjacency and an inert embed. No result is
|
||||
available yet. Static reasoning is not a measurement.
|
||||
|
||||
Outcome A, every baseline round-trip is equal: record that wikilinks do
|
||||
not trigger Source fallback for the measured inputs. Do not claim that
|
||||
bug exists. The source's raw/sig cache explains why an unchanged block can
|
||||
keep its bytes even when its canonical serializer escapes brackets. Add
|
||||
the node for structured wikilinks and dirty-block preservation, as the
|
||||
brief requests. A baseline structural/edit regression must fail even if
|
||||
all unchanged-file checks pass.
|
||||
|
||||
Outcome B, one or more differ: record the exact differing bytes and affected
|
||||
contexts. Keep the existing Source fallback fail-closed. The node restores
|
||||
the required spellings where the block is structured. Retain the same
|
||||
no-edit and dirty-block regressions. If the mismatch comes from a separate
|
||||
block, line-ending or front-matter defect, report it before widening scope.
|
||||
|
||||
## Representation and conversion
|
||||
|
||||
The schema gains one inline atom, wikilink, with a single source attribute.
|
||||
Its source is the complete spelling, not reconstructed target/label parts.
|
||||
It has no href, navigation, fetch or click behavior. A span with data-source
|
||||
and a text child displays the spelling. Heading content includes the new
|
||||
atom; paragraphs, quotes and lists already accept inline content.
|
||||
|
||||
One markdown-it inline rule runs before ordinary links, after escapes and
|
||||
backticks. A sticky match reads a complete single-line [[...]] or ![[...]]
|
||||
without copying every suffix or crossing state.posMax. The node writer
|
||||
writes its validated spelling without bracket escaping, so editing adjacent
|
||||
text cannot rewrite a wikilink. Front matter remains a raw block. No new
|
||||
file-read, save, routing, documentPath or target-resolution behavior is added.
|
||||
|
||||
The accepted atom grammar excludes brackets within the body, line breaks,
|
||||
angle brackets and ampersands. This is an editor representation boundary,
|
||||
not a library resolver or a refusal to open such a file. Malformed,
|
||||
HTML/entity-like and code syntax stays under the existing text/raw rules.
|
||||
This preserves the existing escaping of HTML/entities when a block changes.
|
||||
DOM paste accepts only that same grammar. Invalid attributes constructed
|
||||
programmatically are flattened to one line and escaped by the text writer.
|
||||
No input string is parsed as HTML and embeds never load an image.
|
||||
|
||||
## Acceptance and review
|
||||
|
||||
The measurement JSON goes in BUILD.md and the final manifest packet.
|
||||
Ten fixture round-trips run with and without a final newline. A browser
|
||||
test inspects real ProseMirror atom types and attributes, edits the same
|
||||
block and reparses it, for each fixture. Two more browser tests cover
|
||||
code/escape/malformed/hostile syntax and DOM/programmatic-attribute safety.
|
||||
Tests use the existing fixture and Chromium harness and the shipped bundle.
|
||||
They do not export new production APIs just for testing.
|
||||
|
||||
Before rebuilding, run only the structural regression against the baseline
|
||||
bundle and observe it fail. Rebuild the candidate with the exact pinned
|
||||
esbuild0.28.2 binary, run the whole new test file, existing editor tests,
|
||||
editor browser tests and provenance test. Remove only the wikilink serializer
|
||||
handler for one mutant; the dirty-block assertion must fail. Restore, rebuild
|
||||
and rerun the focused regression. All execution needs Sage's CLEAR, including
|
||||
installation, checks, builds, browser tests and the measurement.
|
||||
|
||||
The checked-in bundle and editor/BUILD.json must be regenerated by the
|
||||
existing build script. No hand edits of generated JavaScript or provenance.
|
||||
The current shared esbuild is0.28.1 and the local webui install is absent.
|
||||
A granted npm ci --ignore-scripts --no-audit --no-fund in packages/webui is
|
||||
needed before building; the root node_modules remains its plain symlink.
|
||||
No dependency or lockfile change is planned.
|
||||
|
||||
Final gate: Filbert approves the manifest, then the whole webui suite and
|
||||
every scripts/test-*.sh on Sage's slot. Two failures stop a gate. A failure
|
||||
outside this row is reported to Sage before any rerun. Source, generated
|
||||
output, mode/hash manifest and raw granted logs identify the candidate.
|
||||
|
||||
## Static review follow-through (Filbert, 2026-10-22T16:43:35Z)
|
||||
|
||||
R1: the focused editor-provenance run and Sage's whole webui gate must set
|
||||
MOSAIC_REQUIRE_EDITOR_BUILD=1. A missing, wrong-version or unpinned binary
|
||||
then fails. Check every log for ^# skip, as well as TAP # SKIP directives
|
||||
and the spec reporter's skipped-test lines; record each skipped name and
|
||||
reason. A skipped rebuild is not proof of bundle reproducibility. The CSS
|
||||
output must stay byte-identical and match BUILD.json.
|
||||
|
||||
R2: no-edit roundTrip checks are expected to pass on the baseline because
|
||||
parse sets sig=canonical and an unchanged serialise returns lead+raw. Their
|
||||
green result is compatibility evidence, never evidence that the atom was
|
||||
needed or installed. The same-block edit/structural regression is the red
|
||||
that proves the new node. The required measurement still runs and is kept.
|
||||
|
||||
N1: bus.js checks visual mode at949 on this base and also requires
|
||||
MosaicMarkdown. The measurement uses the existing helper's bare-window VM
|
||||
shape, markdown-preview.js first, then editor.js, both from pinned Git blobs.
|
||||
|
||||
N2: the exclusion of & and angle brackets is deliberate: the existing
|
||||
text serializer escapes entities/HTML when it rewrites a block for another
|
||||
renderer. An atom's verbatim writer must not bypass that rule, including
|
||||
for pasted/programmatic values. This keeps those targets as ordinary text;
|
||||
[[Q&A]] will still be escaped if its own block changes. It is a known
|
||||
representation limit beyond the five brief cases, not a resolver change.
|
||||
It is included among the text-only cases. Unedited bytes remain intact.
|
||||
|
||||
N3: the reference-definition fixture [[a]] with [a]: u deliberately becomes
|
||||
one inert wikilink rather than a bracket around a reference link. Literal
|
||||
spelling and the separate definition block remain intact.
|
||||
|
||||
N4: [x [[a]]](u) is an explicit fixture. The atom inherits the enclosing
|
||||
ordinary link mark, whose existing target gate still applies. The atom
|
||||
itself supplies no href or new click behavior; the fixture checks its
|
||||
structure and spelling before/after a same-block edit.
|
||||
|
||||
N6: every granted browser/test process gets TMPDIR from
|
||||
mktemp -d /mnt/storage/scratch/tmp/gXXX. Never /tmp. Sweep owned Chromium
|
||||
and Node processes by cwd and the temp-root path after the mutant, after
|
||||
any timeout, and before clearing the slot. Retain/report uncertain owners.
|
||||
|
||||
## R2 current-base check, sage-4164 (2026-10-24)
|
||||
|
||||
The execution base is now487500a16, on herb/row214-r2, not the historical
|
||||
aca16404c above. The two accepted document commits were cherry-picked
|
||||
cleanly. The model, build script, toolchain, BUILD.json, editor.js, view,
|
||||
entry and editor test loader are byte-identical between those bases. The
|
||||
current fixture's new configDirectory isolation is retained; it is not
|
||||
copied from the old worktree. The visual-mode check is now bus.js:1054.
|
||||
The current C2-11a brief section is unchanged. Row266's chat modules,
|
||||
public/chat.js and public/chat.css are outside this row, with no overlap.
|
||||
|
||||
measure.mjs now pins487500a16's Git objects and BUILD.json. The baseline
|
||||
bundle still lacks the atom, and the first executed structural regression
|
||||
will use it before any rebuild. The required measurement, red/green, pinned
|
||||
rebuild, mutant kill and full gate remain unrun and required. Runtime
|
||||
validation is not inferred from the unchanged source or this static check.
|
||||
|
||||
Sage-4164 explicitly authorizes committing the preserved local node/tests
|
||||
on the new branch before execution. The authored source commit is static
|
||||
work, not a green candidate. No Node, npm, rebuild or browser starts until
|
||||
Sage sends CLEAR. HASH-PINS.json records the test-tree audit and row266
|
||||
intersection. The gate still requires MOSAIC_REQUIRE_EDITOR_BUILD=1, a
|
||||
named skip list, whole webui and every scripts/test-*.sh.
|
||||
|
||||
## R2 static follow-up, Filbert B1/N1 (2026-10-24T17:14:55Z)
|
||||
|
||||
B1: state.text(..., true) escapes Markdown punctuation, not HTML/entities.
|
||||
The invalid-atom writer now calls the same escapedText helper as ordinary
|
||||
text nodes, including the <& step. Valid atoms still preserve their source
|
||||
verbatim. The malformed-attribute regression now asserts both an escaped
|
||||
<img and an escaped ©, plus flattened line breaks. A second mutant
|
||||
will replace only the invalid atom's escapedText call with state.text,
|
||||
leaving normal text escaping intact; this browser regression must kill it.
|
||||
This additional mutant needs Sage's grant alongside the serializer-removal
|
||||
mutant. No runtime result is claimed for either.
|
||||
|
||||
N1: backticks are excluded from the atom body, preserving code-span
|
||||
precedence. The text-only fixture includes [[a`]]` and must produce no
|
||||
wikilink atom. All other malformed/HTML/entity boundaries remain as before.
|
||||
@@ -1,572 +0,0 @@
|
||||
{
|
||||
"grant": "sage-4286",
|
||||
"candidateBeforeBuild": "2ec3f5b5ddab0cb5f2716f8164c25861b741213e",
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"measurement": {
|
||||
"base": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"bundleSha256": "9c881b13740fae2408717ad75fa1d85bfcfe3fa8b3af0f1b3f2e706c90e80fee",
|
||||
"measuredAt": "2026-10-24T22:07:22.210Z",
|
||||
"allEqual": true,
|
||||
"results": [
|
||||
{
|
||||
"name": "plain",
|
||||
"input": "[[a]]\n",
|
||||
"output": "[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "labelled",
|
||||
"input": "[[a|b]]\n",
|
||||
"output": "[[a|b]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading target",
|
||||
"input": "[[a#h]]\n",
|
||||
"output": "[[a#h]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "list item",
|
||||
"input": "- [[a]]\n",
|
||||
"output": "- [[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "next to front matter",
|
||||
"input": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"output": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading block and combined label",
|
||||
"input": "# See [[a#h|Title]]\n",
|
||||
"output": "# See [[a#h|Title]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "spaces, Unicode and adjacent links",
|
||||
"input": "See [[ H\u00e9llo there # A heading | a label ]][[next]]\n",
|
||||
"output": "See [[ H\u00e9llo there # A heading | a label ]][[next]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "reference-definition collision",
|
||||
"input": "[[a]]\n\n[a]: u\n",
|
||||
"output": "[[a]]\n\n[a]: u\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inside an ordinary link",
|
||||
"input": "[x [[a]]](u)\n",
|
||||
"output": "[x [[a]]](u)\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inert embed",
|
||||
"input": "![[cover.png]]\n",
|
||||
"output": "![[cover.png]]\n",
|
||||
"equal": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"name": "measurement",
|
||||
"argv": [
|
||||
"node",
|
||||
"agents/herb/work/queue-214/measure.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.093,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 60,
|
||||
"ended": "2026-10-24T22:07:22.215700+00:00"
|
||||
},
|
||||
{
|
||||
"name": "baseline-red",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-name-pattern=wikilinks are inline atoms and survive",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 1,
|
||||
"wallSeconds": 1.151,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:07:27.998436+00:00"
|
||||
},
|
||||
{
|
||||
"name": "npm-ci",
|
||||
"argv": [
|
||||
"npm",
|
||||
"ci",
|
||||
"--ignore-scripts",
|
||||
"--no-audit",
|
||||
"--no-fund"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.514,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 240,
|
||||
"ended": "2026-10-24T22:07:41.534116+00:00"
|
||||
},
|
||||
{
|
||||
"name": "build",
|
||||
"argv": [
|
||||
"node",
|
||||
"editor/build.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.108,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 120,
|
||||
"ended": "2026-10-24T22:07:44.654385+00:00"
|
||||
},
|
||||
{
|
||||
"name": "wikilink-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 2.348,
|
||||
"counts": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:07:52.583345+00:00"
|
||||
},
|
||||
{
|
||||
"name": "editor-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"packages/webui/tests/editor.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 2.053,
|
||||
"counts": {
|
||||
"tests": 5,
|
||||
"pass": 5,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 240,
|
||||
"ended": "2026-10-24T22:07:59.286086+00:00"
|
||||
},
|
||||
{
|
||||
"name": "editor-browser-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"packages/webui/tests/editor-browser.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 14.984,
|
||||
"counts": {
|
||||
"tests": 16,
|
||||
"pass": 16,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 240,
|
||||
"ended": "2026-10-24T22:08:20.029050+00:00"
|
||||
},
|
||||
{
|
||||
"name": "provenance-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"packages/webui/tests/editor-provenance.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.343,
|
||||
"counts": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:08:39.003420+00:00"
|
||||
},
|
||||
{
|
||||
"name": "serializer-removal-build",
|
||||
"argv": [
|
||||
"node",
|
||||
"editor/build.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.093,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 90,
|
||||
"ended": "2026-10-24T22:08:51.422097+00:00"
|
||||
},
|
||||
{
|
||||
"name": "serializer-removal-red",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-name-pattern=wikilinks are inline atoms and survive",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 1,
|
||||
"wallSeconds": 0.887,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:08:52.340936+00:00"
|
||||
},
|
||||
{
|
||||
"name": "serializer-removal-restore-build",
|
||||
"argv": [
|
||||
"node",
|
||||
"editor/build.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.115,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 90,
|
||||
"ended": "2026-10-24T22:08:52.498613+00:00"
|
||||
},
|
||||
{
|
||||
"name": "serializer-removal-restore-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-name-pattern=wikilinks are inline atoms and survive",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.979,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:08:53.514962+00:00"
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping-build",
|
||||
"argv": [
|
||||
"node",
|
||||
"editor/build.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.102,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 90,
|
||||
"ended": "2026-10-24T22:08:53.655583+00:00"
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping-red",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-name-pattern=wikilink DOM paste accepts",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 1,
|
||||
"wallSeconds": 0.979,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:08:54.668225+00:00"
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping-restore-build",
|
||||
"argv": [
|
||||
"node",
|
||||
"editor/build.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.105,
|
||||
"counts": {},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 90,
|
||||
"ended": "2026-10-24T22:08:54.809629+00:00"
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping-restore-green",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-name-pattern=wikilink DOM paste accepts",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"rc": 0,
|
||||
"wallSeconds": 0.985,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 180,
|
||||
"ended": "2026-10-24T22:08:55.831793+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webui-whole",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=2",
|
||||
"tests/agents-browser.test.mjs",
|
||||
"tests/agents.test.mjs",
|
||||
"tests/board-held.test.mjs",
|
||||
"tests/browser-edge.test.mjs",
|
||||
"tests/browser.test.mjs",
|
||||
"tests/bus-browser.test.mjs",
|
||||
"tests/bus.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 17.787,
|
||||
"counts": {
|
||||
"tests": 28,
|
||||
"pass": 28,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 600,
|
||||
"ended": "2026-10-24T22:09:39.039897+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webui-69",
|
||||
"argv": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=2",
|
||||
"tests/agents-browser.test.mjs",
|
||||
"tests/agents.test.mjs",
|
||||
"tests/assistant.test.mjs",
|
||||
"tests/board-held.test.mjs",
|
||||
"tests/browser-edge.test.mjs",
|
||||
"tests/browser.test.mjs",
|
||||
"tests/bus-browser.test.mjs",
|
||||
"tests/bus.test.mjs",
|
||||
"tests/channel-chat.test.mjs",
|
||||
"tests/chat-browser.test.mjs",
|
||||
"tests/chat-instances.test.mjs",
|
||||
"tests/chat-replies-browser.test.mjs",
|
||||
"tests/chat-sessions-access.test.mjs",
|
||||
"tests/chat.test.mjs",
|
||||
"tests/conversation.test.mjs",
|
||||
"tests/decide-browser.test.mjs",
|
||||
"tests/decide-sso.test.mjs",
|
||||
"tests/decision-http.test.mjs",
|
||||
"tests/discord.test.mjs",
|
||||
"tests/docs-browser.test.mjs",
|
||||
"tests/editor-browser.test.mjs",
|
||||
"tests/editor-provenance.test.mjs",
|
||||
"tests/editor-wikilink.test.mjs",
|
||||
"tests/editor.test.mjs",
|
||||
"tests/granted-user.test.mjs",
|
||||
"tests/history-return-flow.test.mjs",
|
||||
"tests/instances-browser.test.mjs",
|
||||
"tests/instances.test.mjs",
|
||||
"tests/library-cli.test.mjs",
|
||||
"tests/library-routes.test.mjs",
|
||||
"tests/library-status.test.mjs",
|
||||
"tests/limits-browser.test.mjs",
|
||||
"tests/limits-route.test.mjs",
|
||||
"tests/markdown-preview.test.mjs",
|
||||
"tests/messages.test.mjs",
|
||||
"tests/pinned-copy.test.mjs",
|
||||
"tests/preview.test.mjs",
|
||||
"tests/processing-browser.test.mjs",
|
||||
"tests/processing-ui.test.mjs",
|
||||
"tests/processing.test.mjs",
|
||||
"tests/project-file.test.mjs",
|
||||
"tests/project-name-repo.test.mjs",
|
||||
"tests/proof-cli.test.mjs",
|
||||
"tests/proof.test.mjs",
|
||||
"tests/reads.test.mjs",
|
||||
"tests/relaunch.test.mjs",
|
||||
"tests/return-flow.test.mjs",
|
||||
"tests/routes-browser.test.mjs",
|
||||
"tests/routes.test.mjs",
|
||||
"tests/send-browser.test.mjs",
|
||||
"tests/send.test.mjs",
|
||||
"tests/serve.test.mjs",
|
||||
"tests/service.test.mjs",
|
||||
"tests/settings-form.test.mjs",
|
||||
"tests/settings-write.test.mjs",
|
||||
"tests/shell.test.mjs",
|
||||
"tests/sso-browser.test.mjs",
|
||||
"tests/sso.test.mjs",
|
||||
"tests/tester-browser.test.mjs",
|
||||
"tests/tester-cli.test.mjs",
|
||||
"tests/tester-listener.test.mjs",
|
||||
"tests/tester-socket.test.mjs",
|
||||
"tests/thread-claims-browser.test.mjs",
|
||||
"tests/thread-claims.test.mjs",
|
||||
"tests/thread-sharing.test.mjs",
|
||||
"tests/usage-browser.test.mjs",
|
||||
"tests/usage.test.mjs",
|
||||
"tests/user-option-swap.test.mjs",
|
||||
"tests/views.test.mjs"
|
||||
],
|
||||
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui",
|
||||
"rc": 0,
|
||||
"wallSeconds": 174.189,
|
||||
"counts": {
|
||||
"tests": 455,
|
||||
"pass": 455,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"nice": 19,
|
||||
"tmpRoot": "/mnt/storage/scratch/tmp/g49X",
|
||||
"requireEditorBuild": "1",
|
||||
"timeoutSeconds": 600,
|
||||
"ended": "2026-10-24T22:12:48.880975+00:00"
|
||||
}
|
||||
],
|
||||
"mutants": [
|
||||
{
|
||||
"name": "serializer-removal",
|
||||
"killed": true,
|
||||
"restored": true,
|
||||
"restoredHashesEqual": true
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping",
|
||||
"killed": true,
|
||||
"restored": true,
|
||||
"restoredHashesEqual": true
|
||||
}
|
||||
],
|
||||
"skipNames": [],
|
||||
"sweep": {
|
||||
"at": "2026-10-24T22:13:17.560692+00:00",
|
||||
"count": 0,
|
||||
"processes": []
|
||||
},
|
||||
"generated": {
|
||||
"src/public/editor.js": {
|
||||
"sha256": "bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72",
|
||||
"bytes": 759959
|
||||
},
|
||||
"src/public/editor.css": {
|
||||
"sha256": "8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f",
|
||||
"bytes": 4462
|
||||
}
|
||||
},
|
||||
"unchangedCss": true,
|
||||
"modelRestored": true,
|
||||
"notes": [
|
||||
"webui-whole was an accidental seven-file subset, 28/0, not gate evidence; superseded by webui-69 455/0",
|
||||
"no scripts/test-*.sh ran in this grant; later gate remains pending"
|
||||
],
|
||||
"tmpRemoved": true
|
||||
}
|
||||
@@ -1,323 +0,0 @@
|
||||
{
|
||||
"base": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"testFilesScanned": 495,
|
||||
"plannedPaths": [
|
||||
"packages/webui/editor/model.mjs",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs",
|
||||
"packages/webui/tests/helpers/wikilink-cases.mjs",
|
||||
"agents/herb/work/queue-214/measure.mjs",
|
||||
"agents/herb/work/queue-214/DESIGN.md",
|
||||
"agents/herb/work/queue-214/MANIFEST.md",
|
||||
"agents/herb/work/queue-214/BUILD.md",
|
||||
"packages/webui/src/public/editor.js",
|
||||
"packages/webui/editor/BUILD.json",
|
||||
"agents/herb/work/queue-214/HASH-PINS.json"
|
||||
],
|
||||
"literalPriorBlobPins": [],
|
||||
"pathReferences": [
|
||||
{
|
||||
"test": "packages/webui/tests/editor-wikilink.test.mjs",
|
||||
"line": 6,
|
||||
"text": "import { WIKILINK_CASES } from './helpers/wikilink-cases.mjs';"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/browser.test.mjs",
|
||||
"line": 21,
|
||||
"text": "// Rows 129, 154, 191, 194 and 294: chat.js, editor.js, processing.js, agents.js and federation.js are the scripts added, same origin; the list is the pin, so another script is a visible change."
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/browser.test.mjs",
|
||||
"line": 22,
|
||||
"text": "assert.deepEqual(await b.evaluate('[...document.querySelectorAll(\"script\")].map(s => s.getAttribute(\"src\"))'), ['/editor.js', '/processing.js', '/federation.js', '/brand.js', '/app.js', '/markdown-preview.js', '/chat.js', '/agents.js', '/bus.js']);"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/sso.test.mjs",
|
||||
"line": 1,
|
||||
"text": "// Q175 phase 1 (#1690, design agents/sage/work/q175-sso/DESIGN.md section 9): the Console as an"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/user-option-swap.test.mjs",
|
||||
"line": 133,
|
||||
"text": "['GET', '/app.js'], ['GET', '/bus.js'], ['GET', '/agents.js'], ['GET', '/editor.js'], ['GET', '/shared/app.css'], ['GET', '/index.html'],"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/serve.test.mjs",
|
||||
"line": 38,
|
||||
"text": "for (const path of ['/', '/app.js', '/brand.js', '/console.css', '/live.css', '/editor.js', '/editor.css', '/shared/app.css', '/assets/fonts/manrope-400.woff2']) {"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-provenance.test.mjs",
|
||||
"line": 18,
|
||||
"text": "const build = JSON.parse(readFileSync(join(webui, 'editor/BUILD.json'), 'utf8'));"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-provenance.test.mjs",
|
||||
"line": 92,
|
||||
"text": "const bundle = readFileSync(join(webui, 'src/public/editor.js'), 'utf8');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-provenance.test.mjs",
|
||||
"line": 167,
|
||||
"text": "const info = await run(out, join(out, 'BUILD.json'));"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-provenance.test.mjs",
|
||||
"line": 171,
|
||||
"text": "assert.equal(readFileSync(join(out, 'BUILD.json'), 'utf8'), readFileSync(join(webui, 'editor/BUILD.json'), 'utf8'));"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-browser.test.mjs",
|
||||
"line": 103,
|
||||
"text": "assert.equal(await h.q('typeof window.MosaicEditor.mount'), 'function', 'editor.js ran under script-src self');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor-browser.test.mjs",
|
||||
"line": 423,
|
||||
"text": "// (The editor's own reading of a file can give a single line break in a title or alt, never a blank line; see BUILD.md.)"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/granted-user.test.mjs",
|
||||
"line": 231,
|
||||
"text": "['GET', '/app.js'], ['GET', '/bus.js'], ['GET', '/agents.js'], ['GET', '/editor.js'], ['GET', '/shared/app.css'], ['GET', '/index.html'],"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 20,
|
||||
"text": "for (const [path, type] of [['/editor.js', 'text/javascript'], ['/editor.css', 'text/css']]) {"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 29,
|
||||
"text": "assert.ok(index.indexOf('src=\"/editor.js\"') < index.indexOf('src=\"/bus.js\"'), 'the editor loads before the page script, so bus.js can mount it');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 60,
|
||||
"text": "for (const file of ['entry.mjs', 'model.mjs', 'view.mjs']) {"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 64,
|
||||
"text": "const bundle = readFileSync(join(webui, 'src/public/editor.js'), 'utf8');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 65,
|
||||
"text": "assert.doesNotMatch(bundle, /\\beval\\s*\\(|\\bnew\\s+Function\\b/, 'src/public/editor.js');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/editor.test.mjs",
|
||||
"line": 69,
|
||||
"text": "const model = readFileSync(join(webui, 'editor/model.mjs'), 'utf8');"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/helpers/editor-bundle.mjs",
|
||||
"line": 1,
|
||||
"text": "// Loads src/public/editor.js (and markdown-preview.js, the link gate it needs) into a vm context with a"
|
||||
},
|
||||
{
|
||||
"test": "packages/webui/tests/helpers/editor-bundle.mjs",
|
||||
"line": 15,
|
||||
"text": "for (const f of ['markdown-preview.js', 'editor.js']) vm.runInContext(readFileSync(join(pub, f), 'utf8'), sandbox, { filename: f });"
|
||||
},
|
||||
{
|
||||
"test": "packages/plugins/tests/harness.test.mjs",
|
||||
"line": 44,
|
||||
"text": "// pi 0.85.1 --thinking and claude 2.1.302 --effort, as probed (BUILD.md); claude has no off or minimal."
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/revoke-window.test.mjs",
|
||||
"line": 4,
|
||||
"text": "// a limit stub and a usage stub for the limit stop. BUILD.md (agents/morgana/work/queue-306) names"
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/access-revoke.test.mjs",
|
||||
"line": 5,
|
||||
"text": "// lstat key; `edit` changes the document and the stamp together, as a hand edit does. BUILD.md"
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/land.test.mjs",
|
||||
"line": 410,
|
||||
"text": "// landHeld still counts it, so it stays listed (BUILD.md follow-up 5)."
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/session-clear.test.mjs",
|
||||
"line": 13,
|
||||
"text": "// docs/plans/2026-10-21_t1-sessions.md, the contract in agents/gizmoduck/work/queue-271/BUILD.md."
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/grant-executor.test.mjs",
|
||||
"line": 1027,
|
||||
"text": "// credential-unavailable; BUILD.md records the difference)."
|
||||
},
|
||||
{
|
||||
"test": "packages/bus/tests/host-run.test.mjs",
|
||||
"line": 343,
|
||||
"text": "// the options are checked here and the call runs with an alias no user file holds (BUILD.md)."
|
||||
},
|
||||
{
|
||||
"test": "packages/business/tests/workflow-roles.test.mjs",
|
||||
"line": 123,
|
||||
"text": "// of staff launches it. The broker and launcher states are row 137's tests (BUILD.md, round 3)."
|
||||
},
|
||||
{
|
||||
"test": "packages/business/tests/access.test.mjs",
|
||||
"line": 1,
|
||||
"text": "// FED R1 (#414, row 201): the access file loader and validator, DESIGN.md"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/revoke-window.test.mjs",
|
||||
"line": 9,
|
||||
"text": "// poll, with threadsState replaced by the caller. BUILD.md (agents/morgana/work/queue-306) names the"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-instances.test.mjs",
|
||||
"line": 3,
|
||||
"text": "// T table: agents/darkwing/work/queue-190/DESIGN.md D7. The unit, port and release cases are T56 in"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/session-launch.test.mjs",
|
||||
"line": 297,
|
||||
"text": "// Q2 (BUILD.md:177-179, t1-sessions.md:109): an earlier host's sessionless run of the instance is"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/case1-accept.test.mjs",
|
||||
"line": 2,
|
||||
"text": "// (agents/darkwing/work/queue-195/DESIGN.md); deviations in agents/darkwing/work/queue-195/BUILD.md."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release.test.mjs",
|
||||
"line": 4,
|
||||
"text": "// agents/darkwing/work/queue-162/BUILD.md. Every run uses a temp data root, temp units and stand-in"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release.test.mjs",
|
||||
"line": 915,
|
||||
"text": "// COUNTED or dropped from it shows here. Row 181's BUILD.md names each writer."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release.test.mjs",
|
||||
"line": 928,
|
||||
"text": "task_comment_cursors:'no time column; a restore drops its advances uncounted (BUILD.md)',"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release.test.mjs",
|
||||
"line": 1668,
|
||||
"text": "// refusal is the guard for a file that changes after that (BUILD.md, round 2)."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release.test.mjs",
|
||||
"line": 2331,
|
||||
"text": "// agents/darkwing/work/queue-190/DESIGN.md. T-I1, T-I2, T-I5, T-I10 and the loader half of T-I7 are in"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/publish-socket.test.mjs",
|
||||
"line": 236,
|
||||
"text": "// sage-1440 on BUILD.md 14: a push between checkPublish and the git push refuses, with one code"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-upgrade.test.mjs",
|
||||
"line": 3,
|
||||
"text": "// agents/darkwing/work/queue-195/DESIGN.md, as the I3 brief changes them; deviations:"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-upgrade.test.mjs",
|
||||
"line": 4,
|
||||
"text": "// agents/darkwing/work/queue-233/BUILD.md. The stand-ins and the module fixture are"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/stack-release-external.test.mjs",
|
||||
"line": 2,
|
||||
"text": "// test list, agents/darkwing/work/queue-195/DESIGN.md; deviations: agents/darkwing/work/queue-232/BUILD.md."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/case1-hostcheck.test.mjs",
|
||||
"line": 3,
|
||||
"text": "// (agents/darkwing/work/queue-195/DESIGN.md at b7239bb66). Every case copies the script into a scratch"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/thread-revoke.test.mjs",
|
||||
"line": 5,
|
||||
"text": "// The bus half is packages/bus/tests/access-revoke.test.mjs; BUILD.md"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/access.test.mjs",
|
||||
"line": 308,
|
||||
"text": "// outside R5 (BUILD.md). The test pins it, and nothing is written."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/access.test.mjs",
|
||||
"line": 316,
|
||||
"text": "// Row 193c (#1705): `user add` and `user remove`. BUILD.md (agents/megavolt/work/queue-207) names"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/access.test.mjs",
|
||||
"line": 455,
|
||||
"text": "// refuses access.reload alone, as a bus would refuse a call it can't take. BUILD.md"
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/launcher.test.mjs",
|
||||
"line": 799,
|
||||
"text": "// The run directory exists by then (BUILD.md residual); the persona is read before any bundle file."
|
||||
},
|
||||
{
|
||||
"test": "packages/cli/tests/lifecycle.test.mjs",
|
||||
"line": 778,
|
||||
"text": "// N6 (sage-2246, DESIGN.md:118-120): an end signals the runs the verb named and the instance's runs"
|
||||
}
|
||||
],
|
||||
"row266": {
|
||||
"ref": "origin/fethry/row266",
|
||||
"tip": "6418ec063389728e0d8883c94812b12d2074eb43",
|
||||
"diffBase": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"overlap": []
|
||||
},
|
||||
"interpretation": "No literal SHA256 or Git-blob hash pins found for planned changed files. Editor provenance compares generated output to BUILD.json and requires regeneration/rebuild, not an external fixed hash.",
|
||||
"postBuildAudit": {
|
||||
"paths": [
|
||||
"BUILD-LOG.md",
|
||||
"agents/herb/work/queue-214/BUILD.md",
|
||||
"agents/herb/work/queue-214/DESIGN.md",
|
||||
"agents/herb/work/queue-214/EVIDENCE.json",
|
||||
"agents/herb/work/queue-214/HASH-PINS.json",
|
||||
"agents/herb/work/queue-214/MANIFEST.md",
|
||||
"agents/herb/work/queue-214/SOURCE.json",
|
||||
"agents/herb/work/queue-214/granted-4286/baseline-red.log",
|
||||
"agents/herb/work/queue-214/granted-4286/build.log",
|
||||
"agents/herb/work/queue-214/granted-4286/editor-browser-green.log",
|
||||
"agents/herb/work/queue-214/granted-4286/editor-green.log",
|
||||
"agents/herb/work/queue-214/granted-4286/final-sweep.json",
|
||||
"agents/herb/work/queue-214/granted-4286/invalid-escaping-build.log",
|
||||
"agents/herb/work/queue-214/granted-4286/invalid-escaping-red.log",
|
||||
"agents/herb/work/queue-214/granted-4286/invalid-escaping-restore-build.log",
|
||||
"agents/herb/work/queue-214/granted-4286/invalid-escaping-restore-green.log",
|
||||
"agents/herb/work/queue-214/granted-4286/measurement.log",
|
||||
"agents/herb/work/queue-214/granted-4286/mutants.json",
|
||||
"agents/herb/work/queue-214/granted-4286/mutants.py",
|
||||
"agents/herb/work/queue-214/granted-4286/npm-ci.log",
|
||||
"agents/herb/work/queue-214/granted-4286/post-mutant-sweep.json",
|
||||
"agents/herb/work/queue-214/granted-4286/provenance-green.log",
|
||||
"agents/herb/work/queue-214/granted-4286/results.jsonl",
|
||||
"agents/herb/work/queue-214/granted-4286/serializer-removal-build.log",
|
||||
"agents/herb/work/queue-214/granted-4286/serializer-removal-red.log",
|
||||
"agents/herb/work/queue-214/granted-4286/serializer-removal-restore-build.log",
|
||||
"agents/herb/work/queue-214/granted-4286/serializer-removal-restore-green.log",
|
||||
"agents/herb/work/queue-214/granted-4286/settings.json",
|
||||
"agents/herb/work/queue-214/granted-4286/skips.json",
|
||||
"agents/herb/work/queue-214/granted-4286/step.py",
|
||||
"agents/herb/work/queue-214/granted-4286/webui-69.log",
|
||||
"agents/herb/work/queue-214/granted-4286/webui-files.txt",
|
||||
"agents/herb/work/queue-214/granted-4286/webui-whole.log",
|
||||
"agents/herb/work/queue-214/granted-4286/wikilink-green.log",
|
||||
"agents/herb/work/queue-214/measure.mjs",
|
||||
"agents/herb/work/queue-214/measurement.json",
|
||||
"packages/webui/editor/BUILD.json",
|
||||
"packages/webui/editor/model.mjs",
|
||||
"packages/webui/src/public/editor.js",
|
||||
"packages/webui/tests/editor-wikilink.test.mjs",
|
||||
"packages/webui/tests/helpers/wikilink-cases.mjs"
|
||||
],
|
||||
"literalCurrentOrPriorHashPins": [],
|
||||
"buildOutputsValidated": true
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
# Row214 candidate manifest
|
||||
|
||||
Owner: Herb. Reviewer: Filbert. Issue#1715, C2-11a. Execution base
|
||||
487500a16f4ab5902c318509fdec6acc56a543ca on herb/row214-r2. Current
|
||||
brief blob85e6fe2e has the same C2-11a section as the accepted old pin.
|
||||
Source commit a530a60798bf48eb18bb9e225d099faf5c2975cf.
|
||||
|
||||
| Path | Final change |
|
||||
| --- | --- |
|
||||
| packages/webui/editor/model.mjs | inert inline atom, heading content, tokenizer and validated serializer; invalid attrs share complete text escaping |
|
||||
| packages/webui/tests/editor-wikilink.test.mjs | ten byte round-trips and three browser regressions, including same-block edits and malformed attrs |
|
||||
| packages/webui/tests/helpers/wikilink-cases.mjs | exact fixtures shared with measurement |
|
||||
| packages/webui/src/public/editor.js | generated with pinned esbuild0.28.2 |
|
||||
| packages/webui/editor/BUILD.json | generated provenance and output hashes |
|
||||
| BUILD-LOG.md | one append-only phase receipt |
|
||||
| agents/herb/work/queue-214/measure.mjs | baseline measurement from pinned Git blobs |
|
||||
| agents/herb/work/queue-214/measurement.json | unchanged measurement JSON,10/10 equal |
|
||||
| agents/herb/work/queue-214/DESIGN.md | accepted design, both outcomes and static review follow-through |
|
||||
| agents/herb/work/queue-214/BUILD.md | rulings, actual granted commands, timings and limits |
|
||||
| agents/herb/work/queue-214/HASH-PINS.json | static hash-pin/row266 audit, repeated after build |
|
||||
| agents/herb/work/queue-214/SOURCE.json | actual source/output hashes and unchanged CSS dependency |
|
||||
| agents/herb/work/queue-214/EVIDENCE.json | grant, exact argv/counts, measurement, mutants, skips and sweeps |
|
||||
| agents/herb/work/queue-214/granted-4286/ | raw tee logs, commands, file list and sweep/skip/mutant records |
|
||||
|
||||
The CSS output is byte-identical and matches BUILD.json. No entry/view,
|
||||
third_party, dependency/lockfile, library, route, save, click or documentPath
|
||||
change. No row266 chat path changes. No test assertion changed after runs.
|
||||
|
||||
Outcome A: all ten measured no-edit cases were already preserved by the
|
||||
baseline's raw/sig behavior. Their green result is compatibility evidence,
|
||||
not proof of the node. The baseline structural case was0/1 expected red.
|
||||
|
||||
Grant sage-4286: four whole editor files40/0; whole webui69 files455/0
|
||||
in174.189s; zero skips/cancellations. Both named mutants killed0/1,
|
||||
each restored/rebuilt and focused1/0 green. Absolute nice19, required-build
|
||||
env and short scratch TMPDIR are in raw logs. Provenance rebuilt, not
|
||||
skipped. Final process sweep0, TMPDIR removed. The mistaken seven-file
|
||||
subset28/0 is archived but excluded from gate evidence.
|
||||
|
||||
The candidate hash manifest is rebuilt from the pushed tip outside its
|
||||
own path set. Filbert's candidate review and every scripts/test-*.sh gate
|
||||
remain pending. No Case1 acceptance test was run. The row is not done.
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"base": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"status": "focused and 69-file webui green under sage-4286; candidate review and shell gate pending",
|
||||
"sourcePaths": [
|
||||
{
|
||||
"path": "packages/webui/editor/model.mjs",
|
||||
"mode": "100644",
|
||||
"sha256": "81ac44d852cb54213a9644ebbde26630ec49614e468f376d71b471395e3dd9f7"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/tests/editor-wikilink.test.mjs",
|
||||
"mode": "100644",
|
||||
"sha256": "e144e7dbf23c68c136eef8f0fb2e8979c27e908c7cc14ee4ab4f722220e67d77"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/tests/helpers/wikilink-cases.mjs",
|
||||
"mode": "100644",
|
||||
"sha256": "afa4dc7188548457b2d1966b9437561ba411d7bc9aaaa38bff626c235a64e19c"
|
||||
},
|
||||
{
|
||||
"path": "agents/herb/work/queue-214/measure.mjs",
|
||||
"mode": "100644",
|
||||
"sha256": "f81987cdae5c4f7e5ce353162674b3c3510e44f22d6d3beb262a5d198db4e88d"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/src/public/editor.js",
|
||||
"mode": "100644",
|
||||
"sha256": "bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72"
|
||||
},
|
||||
{
|
||||
"path": "packages/webui/editor/BUILD.json",
|
||||
"mode": "100644",
|
||||
"sha256": "4d73af728cea60eaa6fadb4650b9d42b663c90ef7f59bb2b787e1f3d9acd8278"
|
||||
},
|
||||
{
|
||||
"path": "BUILD-LOG.md",
|
||||
"mode": "100644",
|
||||
"sha256": "30cc179e2b76c5aceeec35d5ab20339988241a4cb04d26d1cc9b2a5437796236"
|
||||
}
|
||||
],
|
||||
"pendingGeneratedPaths": [],
|
||||
"unchangedGeneratedCss": {
|
||||
"path": "packages/webui/src/public/editor.css",
|
||||
"sha256": "8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f",
|
||||
"mode": "100644"
|
||||
},
|
||||
"runtimeEvidence": "agents/herb/work/queue-214/EVIDENCE.json",
|
||||
"sourceCommit": "a530a60798bf48eb18bb9e225d099faf5c2975cf"
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✖ wikilinks are inline atoms and survive a neighbouring edit in every required context (932.607342ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1108.548729
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/editor-wikilink.test.mjs:35:1
|
||||
✖ wikilinks are inline atoms and survive a neighbouring edit in every required context (932.607342ms)
|
||||
AssertionError [ERR_ASSERTION]: plain
|
||||
+ actual - expected
|
||||
|
||||
+ []
|
||||
- [
|
||||
- {
|
||||
- atom: true,
|
||||
- inline: true,
|
||||
- source: '[[a]]'
|
||||
- }
|
||||
- ]
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui/tests/editor-wikilink.test.mjs:39:12)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [],
|
||||
expected: [ { source: '[[a]]', atom: true, inline: true } ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
editor.js bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72 (133 inputs)
|
||||
editor.css 8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f
|
||||
@@ -1,25 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ the Console's CSP stands and the editor runs under it; hostile markdown on the load path runs and loads nothing (928.130513ms)
|
||||
✔ hostile content pasted into the editor runs and loads nothing, and a bad link target is refused in the link bar (803.464018ms)
|
||||
✔ a pasted image span is kept only for a target the link gate accepts, and a save writes only those (635.018754ms)
|
||||
✔ a switch of view reads nothing; a reload, and a trip away and back, each read the file exactly once (2555.185634ms)
|
||||
✔ an edit rewrites only the block touched; a save sends the rest byte for byte; the Source view carries the draft (1077.608366ms)
|
||||
✔ a file the editor cannot write back byte for byte opens as Source, says so, cannot save, and the Visual button works once it can (2053.81983ms)
|
||||
✔ a link title pasted with line breaks in it is written on one line, so no HTML block comes of it (761.717564ms)
|
||||
✔ an image alt pasted with line breaks in it is written on one line, so no HTML block comes of it (677.209658ms)
|
||||
✔ an image title pasted with line breaks in it is written on one line, so no HTML block comes of it (681.501055ms)
|
||||
✔ a code block info string pasted with line breaks in it is written on one line, so no HTML block comes of it (664.552078ms)
|
||||
✔ a link title holding a quote after a backslash then a tag is written with the backslash escaped, so the title stays closed (653.763504ms)
|
||||
✔ an image title holding a quote after a backslash then a tag is written with the backslash escaped, so the title stays closed (680.145608ms)
|
||||
✔ a link title holding a trailing backslash is written with the backslash escaped, so the title stays closed (681.870693ms)
|
||||
✔ an image title holding a trailing backslash is written with the backslash escaped, so the title stays closed (686.810545ms)
|
||||
✔ a code block info string with a backtick, pasted, is dropped on Save, so the fence stays closed (631.067849ms)
|
||||
✔ a code block info string with a backtick, as a tilde fence can have, is kept as source, not rewritten without it (631.071266ms)
|
||||
ℹ tests 16
|
||||
ℹ suites 0
|
||||
ℹ pass 16
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14945.374491
|
||||
@@ -1,14 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ the editor routes serve the built files with their types and no cache (36.796766ms)
|
||||
✔ open and save with no edit writes the same bytes: the goals review and a doc with every element (16.912796ms)
|
||||
✔ open and save with no edit writes the same bytes: every repository doc under docs/ and spec/ (1791.779235ms)
|
||||
✔ the editor source builds markup only with DOM calls, and the bundle has no eval (2.568423ms)
|
||||
✔ the link gate and the image rule are the preview's (0.573105ms)
|
||||
ℹ tests 5
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2016.291596
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"at": "2026-10-24T22:13:17.560692+00:00",
|
||||
"count": 0,
|
||||
"processes": []
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
editor.js 52c00310b3c32b2f5ca99243f9bbe54f8a76ef0a87f597d8a2220cf1baaa8adc (133 inputs)
|
||||
editor.css 8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f
|
||||
@@ -1,30 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✖ wikilink DOM paste accepts only bounded single-line inert syntax; malformed attrs serialise as escaped text (780.97333ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 939.392901
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/editor-wikilink.test.mjs:65:1
|
||||
✖ wikilink DOM paste accepts only bounded single-line inert syntax; malformed attrs serialise as escaped text (780.97333ms)
|
||||
AssertionError [ERR_ASSERTION]: The input was expected to not match the regular expression /(?<!\\)<img/. Input:
|
||||
|
||||
'\\[\\[a\\]\\] <img src=x onerror=alert(1)>©\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui/tests/editor-wikilink.test.mjs:78:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104: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: '\\[\\[a\\]\\] <img src=x onerror=alert(1)>©\n',
|
||||
expected: /(?<!\\)<img/,
|
||||
operator: 'doesNotMatch',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
editor.js bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72 (133 inputs)
|
||||
editor.css 8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f
|
||||
@@ -1,10 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ wikilink DOM paste accepts only bounded single-line inert syntax; malformed attrs serialise as escaped text (752.4905ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 941.178679
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"base": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"bundleSha256": "9c881b13740fae2408717ad75fa1d85bfcfe3fa8b3af0f1b3f2e706c90e80fee",
|
||||
"measuredAt": "2026-10-24T22:07:22.210Z",
|
||||
"allEqual": true,
|
||||
"results": [
|
||||
{
|
||||
"name": "plain",
|
||||
"input": "[[a]]\n",
|
||||
"output": "[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "labelled",
|
||||
"input": "[[a|b]]\n",
|
||||
"output": "[[a|b]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading target",
|
||||
"input": "[[a#h]]\n",
|
||||
"output": "[[a#h]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "list item",
|
||||
"input": "- [[a]]\n",
|
||||
"output": "- [[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "next to front matter",
|
||||
"input": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"output": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading block and combined label",
|
||||
"input": "# See [[a#h|Title]]\n",
|
||||
"output": "# See [[a#h|Title]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "spaces, Unicode and adjacent links",
|
||||
"input": "See [[ Héllo there # A heading | a label ]][[next]]\n",
|
||||
"output": "See [[ Héllo there # A heading | a label ]][[next]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "reference-definition collision",
|
||||
"input": "[[a]]\n\n[a]: u\n",
|
||||
"output": "[[a]]\n\n[a]: u\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inside an ordinary link",
|
||||
"input": "[x [[a]]](u)\n",
|
||||
"output": "[x [[a]]](u)\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inert embed",
|
||||
"input": "![[cover.png]]\n",
|
||||
"output": "![[cover.png]]\n",
|
||||
"equal": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "serializer-removal",
|
||||
"killed": true,
|
||||
"restored": true,
|
||||
"restoredHashesEqual": true
|
||||
},
|
||||
{
|
||||
"name": "invalid-escaping",
|
||||
"killed": true,
|
||||
"restored": true,
|
||||
"restoredHashesEqual": true
|
||||
}
|
||||
]
|
||||
@@ -1,26 +0,0 @@
|
||||
from pathlib import Path
|
||||
import subprocess,sys,json,hashlib
|
||||
out=Path(__file__).parent;root=Path('/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2');model=root/'packages/webui/editor/model.mjs';good=model.read_bytes();(out/'model.good.mjs').write_bytes(good)
|
||||
initial={str(p.relative_to(root)):hashlib.sha256(p.read_bytes()).hexdigest() for p in [model,root/'packages/webui/src/public/editor.js',root/'packages/webui/editor/BUILD.json',root/'packages/webui/src/public/editor.css']}
|
||||
def step(name,cwd,cap,args):return subprocess.run([sys.executable,str(out/'step.py'),name,str(cwd),str(cap),*args]).returncode
|
||||
specs=[('serializer-removal','wikilinks are inline atoms and survive'),('invalid-escaping','wikilink DOM paste accepts')]
|
||||
results=[]
|
||||
for name,pattern in specs:
|
||||
changed=good.decode()
|
||||
if name=='serializer-removal':
|
||||
start=changed.index(' wikilink(state, node) {');end=changed.index(' raw_block(state, node)',start);changed=changed[:start]+changed[end:]
|
||||
else:
|
||||
old="else escapedText(state, oneLine(String(source ?? '')));";assert changed.count(old)==1;changed=changed.replace(old,"else state.text(oneLine(String(source ?? '')));")
|
||||
try:
|
||||
model.write_text(changed)
|
||||
assert step(name+'-build',root/'packages/webui',90,['node','editor/build.mjs'])==0
|
||||
rc=step(name+'-red',root,180,['node','--test','--test-concurrency=1','--test-name-pattern='+pattern,'packages/webui/tests/editor-wikilink.test.mjs'])
|
||||
if rc!=1:raise RuntimeError('mutant not killed or timed out: '+str(rc))
|
||||
finally:
|
||||
model.write_bytes(good)
|
||||
if step(name+'-restore-build',root/'packages/webui',90,['node','editor/build.mjs'])!=0:raise RuntimeError('restore build failed')
|
||||
assert step(name+'-restore-green',root,180,['node','--test','--test-concurrency=1','--test-name-pattern='+pattern,'packages/webui/tests/editor-wikilink.test.mjs'])==0
|
||||
for p,h in initial.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
||||
results.append({'name':name,'killed':True,'restored':True,'restoredHashesEqual':True})
|
||||
(out/'mutants.json').write_text(json.dumps(results,indent=2)+'\n')
|
||||
print('MUTANT_COMPLETE',name,flush=True)
|
||||
@@ -1,3 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
|
||||
added 2 packages in 425ms
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"count": 0,
|
||||
"processes": []
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ the imported source is the tagged upstream source plus the recorded local changes, and nothing else (27.800323ms)
|
||||
✔ every package names its origin and license, and NOTICE lists each (0.831005ms)
|
||||
✔ the build reads only imported source and the editor's own files; the bundle is the recorded build (7.478515ms)
|
||||
✔ MOSAIC_REQUIRE_EDITOR_BUILD: a missing or wrong esbuild skips without it and fails with it; a wrong binary always fails (6.189875ms)
|
||||
✔ the toolchain check, run as a program, exits non-zero without esbuild when the build is required (143.672155ms)
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
✔ rebuilding from the source gives the same bytes (needs the pinned esbuild; MOSAIC_REQUIRE_EDITOR_BUILD=1 makes its absence a failure) (67.600627ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 305.965249
|
||||
@@ -1,18 +0,0 @@
|
||||
{"name": "measurement", "argv": ["node", "agents/herb/work/queue-214/measure.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 0.093, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 60, "ended": "2026-10-24T22:07:22.215700+00:00"}
|
||||
{"name": "baseline-red", "argv": ["node", "--test", "--test-concurrency=1", "--test-name-pattern=wikilinks are inline atoms and survive", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 1, "wallSeconds": 1.151, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:07:27.998436+00:00"}
|
||||
{"name": "npm-ci", "argv": ["npm", "ci", "--ignore-scripts", "--no-audit", "--no-fund"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.514, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 240, "ended": "2026-10-24T22:07:41.534116+00:00"}
|
||||
{"name": "build", "argv": ["node", "editor/build.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.108, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 120, "ended": "2026-10-24T22:07:44.654385+00:00"}
|
||||
{"name": "wikilink-green", "argv": ["node", "--test", "--test-concurrency=1", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 2.348, "counts": {"tests": 13, "pass": 13, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:07:52.583345+00:00"}
|
||||
{"name": "editor-green", "argv": ["node", "--test", "--test-concurrency=1", "packages/webui/tests/editor.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 2.053, "counts": {"tests": 5, "pass": 5, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 240, "ended": "2026-10-24T22:07:59.286086+00:00"}
|
||||
{"name": "editor-browser-green", "argv": ["node", "--test", "--test-concurrency=1", "packages/webui/tests/editor-browser.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 14.984, "counts": {"tests": 16, "pass": 16, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 240, "ended": "2026-10-24T22:08:20.029050+00:00"}
|
||||
{"name": "provenance-green", "argv": ["node", "--test", "--test-concurrency=1", "packages/webui/tests/editor-provenance.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 0.343, "counts": {"tests": 6, "pass": 6, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:08:39.003420+00:00"}
|
||||
{"name": "serializer-removal-build", "argv": ["node", "editor/build.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.093, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 90, "ended": "2026-10-24T22:08:51.422097+00:00"}
|
||||
{"name": "serializer-removal-red", "argv": ["node", "--test", "--test-concurrency=1", "--test-name-pattern=wikilinks are inline atoms and survive", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 1, "wallSeconds": 0.887, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:08:52.340936+00:00"}
|
||||
{"name": "serializer-removal-restore-build", "argv": ["node", "editor/build.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.115, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 90, "ended": "2026-10-24T22:08:52.498613+00:00"}
|
||||
{"name": "serializer-removal-restore-green", "argv": ["node", "--test", "--test-concurrency=1", "--test-name-pattern=wikilinks are inline atoms and survive", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 0.979, "counts": {"tests": 1, "pass": 1, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:08:53.514962+00:00"}
|
||||
{"name": "invalid-escaping-build", "argv": ["node", "editor/build.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.102, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 90, "ended": "2026-10-24T22:08:53.655583+00:00"}
|
||||
{"name": "invalid-escaping-red", "argv": ["node", "--test", "--test-concurrency=1", "--test-name-pattern=wikilink DOM paste accepts", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 1, "wallSeconds": 0.979, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:08:54.668225+00:00"}
|
||||
{"name": "invalid-escaping-restore-build", "argv": ["node", "editor/build.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 0.105, "counts": {}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 90, "ended": "2026-10-24T22:08:54.809629+00:00"}
|
||||
{"name": "invalid-escaping-restore-green", "argv": ["node", "--test", "--test-concurrency=1", "--test-name-pattern=wikilink DOM paste accepts", "packages/webui/tests/editor-wikilink.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2", "rc": 0, "wallSeconds": 0.985, "counts": {"tests": 1, "pass": 1, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 180, "ended": "2026-10-24T22:08:55.831793+00:00"}
|
||||
{"name": "webui-whole", "argv": ["node", "--test", "--test-concurrency=2", "tests/agents-browser.test.mjs", "tests/agents.test.mjs", "tests/board-held.test.mjs", "tests/browser-edge.test.mjs", "tests/browser.test.mjs", "tests/bus-browser.test.mjs", "tests/bus.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 17.787, "counts": {"tests": 28, "pass": 28, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 600, "ended": "2026-10-24T22:09:39.039897+00:00"}
|
||||
{"name": "webui-69", "argv": ["node", "--test", "--test-concurrency=2", "tests/agents-browser.test.mjs", "tests/agents.test.mjs", "tests/assistant.test.mjs", "tests/board-held.test.mjs", "tests/browser-edge.test.mjs", "tests/browser.test.mjs", "tests/bus-browser.test.mjs", "tests/bus.test.mjs", "tests/channel-chat.test.mjs", "tests/chat-browser.test.mjs", "tests/chat-instances.test.mjs", "tests/chat-replies-browser.test.mjs", "tests/chat-sessions-access.test.mjs", "tests/chat.test.mjs", "tests/conversation.test.mjs", "tests/decide-browser.test.mjs", "tests/decide-sso.test.mjs", "tests/decision-http.test.mjs", "tests/discord.test.mjs", "tests/docs-browser.test.mjs", "tests/editor-browser.test.mjs", "tests/editor-provenance.test.mjs", "tests/editor-wikilink.test.mjs", "tests/editor.test.mjs", "tests/granted-user.test.mjs", "tests/history-return-flow.test.mjs", "tests/instances-browser.test.mjs", "tests/instances.test.mjs", "tests/library-cli.test.mjs", "tests/library-routes.test.mjs", "tests/library-status.test.mjs", "tests/limits-browser.test.mjs", "tests/limits-route.test.mjs", "tests/markdown-preview.test.mjs", "tests/messages.test.mjs", "tests/pinned-copy.test.mjs", "tests/preview.test.mjs", "tests/processing-browser.test.mjs", "tests/processing-ui.test.mjs", "tests/processing.test.mjs", "tests/project-file.test.mjs", "tests/project-name-repo.test.mjs", "tests/proof-cli.test.mjs", "tests/proof.test.mjs", "tests/reads.test.mjs", "tests/relaunch.test.mjs", "tests/return-flow.test.mjs", "tests/routes-browser.test.mjs", "tests/routes.test.mjs", "tests/send-browser.test.mjs", "tests/send.test.mjs", "tests/serve.test.mjs", "tests/service.test.mjs", "tests/settings-form.test.mjs", "tests/settings-write.test.mjs", "tests/shell.test.mjs", "tests/sso-browser.test.mjs", "tests/sso.test.mjs", "tests/tester-browser.test.mjs", "tests/tester-cli.test.mjs", "tests/tester-listener.test.mjs", "tests/tester-socket.test.mjs", "tests/thread-claims-browser.test.mjs", "tests/thread-claims.test.mjs", "tests/thread-sharing.test.mjs", "tests/usage-browser.test.mjs", "tests/usage.test.mjs", "tests/user-option-swap.test.mjs", "tests/views.test.mjs"], "cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui", "rc": 0, "wallSeconds": 174.189, "counts": {"tests": 455, "pass": 455, "fail": 0, "cancelled": 0, "skipped": 0}, "nice": 19, "tmpRoot": "/mnt/storage/scratch/tmp/g49X", "requireEditorBuild": "1", "timeoutSeconds": 600, "ended": "2026-10-24T22:12:48.880975+00:00"}
|
||||
@@ -1,15 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
editor.js bf55e22b945eda1e51ecbe9185eadd9ff21a7902713b24417ed7d697c7347bba (133 inputs)
|
||||
editor.css 8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f
|
||||
@@ -1,31 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✖ wikilinks are inline atoms and survive a neighbouring edit in every required context (698.378144ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 850.87157
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/editor-wikilink.test.mjs:35:1
|
||||
✖ wikilinks are inline atoms and survive a neighbouring edit in every required context (698.378144ms)
|
||||
Error: Uncaught: Error: Token type `wikilink` not supported by Markdown renderer
|
||||
at MarkdownSerializerState.render (http://127.0.0.1:43723/editor.js:18015:17)
|
||||
at progress (http://127.0.0.1:43723/editor.js:18096:18)
|
||||
at _Fragment.forEach (http://127.0.0.1:43723/editor.js:484:9)
|
||||
at _Node.forEach (http://127.0.0.1:43723/editor.js:1178:20)
|
||||
at MarkdownSerializerState.renderInline (http://127.0.0.1:43723/editor.js:18101:14)
|
||||
at Object.paragraph (http://127.0.0.1:43723/editor.js:17859:13)
|
||||
at MarkdownSerializerState.render (http://127.0.0.1:43723/editor.js:18012:35)
|
||||
at http://127.0.0.1:43723/editor.js:18025:44
|
||||
at _Fragment.forEach (http://127.0.0.1:43723/editor.js:484:9)
|
||||
at _Node.forEach (http://127.0.0.1:43723/editor.js:1178:20)
|
||||
at Object.evaluate (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui/tests/browser.mjs:49:35)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2/packages/webui/tests/editor-wikilink.test.mjs:38:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
@@ -1,15 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
editor.js bd167899a551c70dc07e500fcdd1853d7fb710b23c217ba5b42daf5785c38a72 (133 inputs)
|
||||
editor.css 8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f
|
||||
@@ -1,10 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ wikilinks are inline atoms and survive a neighbouring edit in every required context (782.721982ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 940.955124
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"root": "/home/jwoltje/.t3/worktrees/mosaic-stack/herb-row214-r2",
|
||||
"tmp": "/mnt/storage/scratch/tmp/g49X",
|
||||
"grant": "sage-4286",
|
||||
"candidate": "2ec3f5b5ddab0cb5f2716f8164c25861b741213e"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"grep": "^# skip plus # SKIP and spec skipped-test lines",
|
||||
"names": []
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import os,sys,subprocess,pathlib,json,time,datetime,shlex,re
|
||||
out=pathlib.Path(__file__).parent;s=json.loads((out/'settings.json').read_text());name=sys.argv[1];cwd=sys.argv[2];cap=int(sys.argv[3]);argv=sys.argv[4:]
|
||||
left=datetime.datetime(2026,10,24,22,40,tzinfo=datetime.timezone.utc).timestamp()-time.time()-20
|
||||
if left<15:raise SystemExit('hard-stop cleanup margin reached')
|
||||
limit=min(cap,int(left));env=os.environ.copy();env.pop('NODE_TEST_CONTEXT',None)
|
||||
env.update(TMPDIR=s['tmp'],TMP=s['tmp'],TEMP=s['tmp'],MOSAIC_REQUIRE_EDITOR_BUILD='1',MOSAIC_GATE_LANE='b',MOSAIC_GATE_STATE='/mnt/storage/scratch/mosaic-gate-lanes',NO_COLOR='1',MOSAIC_CONFIG=s['tmp']+'/missing-config.json',XDG_CACHE_HOME=s['tmp']+'/cache',JITI_FS_CACHE=s['tmp']+'/jiti')
|
||||
header='' if name=='measurement' else 'printf "# grant sage-4286; nice %s; TMPDIR %s; MOSAIC_REQUIRE_EDITOR_BUILD %s\\n" "$(nice)" "$TMPDIR" "$MOSAIC_REQUIRE_EDITOR_BUILD"; '
|
||||
inner=header+'exec "$@"'
|
||||
log=out/(name+'.log');command='nice -n "$((19 - $(nice)))" timeout -k 10 '+str(limit)+' bash -c '+shlex.quote(inner)+' gate-run '+shlex.join(argv)+' 2>&1 | tee '+shlex.quote(str(log))
|
||||
begin=time.time();print('START',name,datetime.datetime.now(datetime.timezone.utc).isoformat(),flush=True)
|
||||
r=subprocess.run(['bash','-o','pipefail','-c',command],cwd=cwd,env=env,stdout=subprocess.DEVNULL)
|
||||
text=log.read_text();counts={}
|
||||
for key in ['tests','pass','fail','cancelled','skipped']:
|
||||
hits=re.findall(r'^[ℹ#] '+key+r' (\d+)',text,re.M)
|
||||
if hits:counts[key]=int(hits[-1])
|
||||
record={'name':name,'argv':argv,'cwd':cwd,'rc':r.returncode,'wallSeconds':round(time.time()-begin,3),'counts':counts,'nice':19,'tmpRoot':s['tmp'],'requireEditorBuild':'1','timeoutSeconds':limit,'ended':datetime.datetime.now(datetime.timezone.utc).isoformat()}
|
||||
with (out/'results.jsonl').open('a') as f:f.write(json.dumps(record)+'\n')
|
||||
print(json.dumps(record),flush=True);print('\n'.join(text.splitlines()[-20:]),flush=True)
|
||||
raise SystemExit(r.returncode)
|
||||
@@ -1,489 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ row 194 T16 Settings Agents: unavailable read-only, launch follows its request, confirms, reason and refusal (17431.415001ms)
|
||||
✔ row 256 T7 T8 the human page offers Delete on a creative instance, the tester page never does (1196.894618ms)
|
||||
✔ row 194 T16: each agent action makes one call with only its keys, logs the user and answers the request (25.920868ms)
|
||||
✔ row 194 T16: the boundary refuses before any bus call (13.773722ms)
|
||||
✔ row 194 T16: read-only when send is off or no writer is wired; no route has a --send exception (6.006105ms)
|
||||
✔ row 194 T16: a bus refusal names its reason and nothing changed; an unknown outcome or a bad shape is never retried (4.80649ms)
|
||||
✔ row 194 T16: the request read takes one id, adds the refusal reason and refuses an unexpected shape (9.010999ms)
|
||||
✔ row 194 T16: delete joins add and change on /api/instances with only revision, instance and op (4.535523ms)
|
||||
✔ row 194 T16 D4.1: the tester listener launches, terminates and reads requests; regenerate, veto and delete are refused with no call (6.985924ms)
|
||||
✔ row 194 N5: agents.js is served as JavaScript and index.html loads it once (2.138169ms)
|
||||
✔ row 239 T6: a delete closed -revoked says the tokens may already be revoked, and outcome-unknown-revoked is an open outcome (3.807253ms)
|
||||
✔ Q169 the signed-in human names a seat and stops the assistant, one bus call each, logged with the user (20.467126ms)
|
||||
✔ Q169 the name and stop routes need send on, the public name, the user, the exact Origin and same-origin Fetch Metadata (10.75691ms)
|
||||
✔ Q169 the name and stop routes take JSON within 4 KiB and only their own keys, all text (7.456ms)
|
||||
✔ Row 167 a null body on the name and stop routes is 400 invalid-request with no write, and the next request is answered (4.218653ms)
|
||||
✔ Q169 a bus refusal says nothing changed; a lost or odd answer says the change may have been made (6.353476ms)
|
||||
✔ Q169 the names read is a bus read like the others (1.642206ms)
|
||||
✔ the Board: held roles with no machine sessions, a claim with no address, the toggle kept across a reload, and Message addressed to the role (6930.836448ms)
|
||||
✔ a Seen click while a Board read is in flight waits for that read, then posts (1178.550164ms)
|
||||
✔ a redirect answer on a Board read, a bus read, a conversation read, a board POST, a module read and a send signs the page out: one line, nothing stale, no further reads (5341.444261ms)
|
||||
✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (1618.401633ms)
|
||||
Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
|
||||
✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (1723.682265ms)
|
||||
✔ the README says a refused field table names the file or the key at fault, never a path (6.362709ms)
|
||||
✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (3554.138366ms)
|
||||
✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (124.549917ms)
|
||||
✔ decisions route serves the roles and recent lists from the reader view (46.444658ms)
|
||||
✔ credentials route serves the broker credential status from the reader view (19.448846ms)
|
||||
✔ replies route serves the replies to one message from the reader view (45.806351ms)
|
||||
✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (55.698955ms)
|
||||
✔ bus refusals map to statuses and never carry a path or a stack (27.537764ms)
|
||||
✔ humanCall speaks the human transport protocol without blocking the server (1707.350793ms)
|
||||
✔ busReader takes --business, else the live bus host, else refuses (257.530467ms)
|
||||
✔ humanCall kills a transport that runs past its timeout (529.025642ms)
|
||||
✔ serve refuses a --business value that is not a business id (463.414608ms)
|
||||
✔ WebUI channel off returns 503 and named recovery for every chat route without a chat operation (38.716248ms)
|
||||
✔ WebUI only selection keeps web chat enabled while retaining the old read envelope (2.635502ms)
|
||||
✔ WebUI channel-disabled recovery text is fixed and never echoes transport text (1.545115ms)
|
||||
✔ chat browser: list/create named projects and threads, hostile labels inert and no implicit writes (836.234777ms)
|
||||
✔ chat browser: thread drafts, receipts and cursor history stay isolated; refresh never writes (1150.355116ms)
|
||||
✔ chat browser: uncertain writes retain draft, ownership refusal clears it, read-only cannot send (1316.24955ms)
|
||||
✔ chat browser: a late read from A cannot paint B; sign-out clears private state and stops reads (1284.31592ms)
|
||||
✔ chat browser: page forward and deduplicate replies; pending and byte-limit submissions do not duplicate (953.60414ms)
|
||||
✔ chat browser: scrolled history stays put, New messages and an own send return to the tail (923.155974ms)
|
||||
✔ chat browser: automatic polling follows a reply without a POST or a lost draft (10953.35212ms)
|
||||
✔ chat browser: display stays bounded while every forward page remains reachable (1095.68322ms)
|
||||
✔ chat browser: a confirmed visible message replaces its pending receipt; malformed receipts stay unknown (963.350843ms)
|
||||
✔ chat browser: a refusal elsewhere forgets private chat drafts (882.872916ms)
|
||||
✔ chat browser: a late project creation receipt cannot navigate away from another thread (1050.661257ms)
|
||||
✔ C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST (1062.688519ms)
|
||||
✔ C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching (924.988913ms)
|
||||
✔ C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread (781.216726ms)
|
||||
✔ 264e chooser: two sessions keep drafts, cursors, deep links and counts independent (921.256121ms)
|
||||
✔ 264e clear confirmation and status never resend, force-stop or change selection (1103.840292ms)
|
||||
✔ 264e new session keeps its operation key after an unknown response and uses no implicit open (1124.509192ms)
|
||||
✔ 264e cancel shows before/after retirement and never starts or replays work (1599.216909ms)
|
||||
✔ 272 B1: a bad-session deep link preserves the draft and lost clear operation on A (1281.091753ms)
|
||||
✔ C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads (23.460794ms)
|
||||
✔ C2-09a metadata uses the private tester listener own bus and no human transport (5.122028ms)
|
||||
✔ C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields (5.504868ms)
|
||||
✔ C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity (4.184632ms)
|
||||
✔ chat replies: free text, cites with badges, the agent label, changed since and safe links (898.153564ms)
|
||||
✔ chat replies: a write notice reads as its line with a Revert; a refused revert shows its code (1170.744713ms)
|
||||
✔ chat replies: a read-only Console shows the notice with Revert disabled (850.32112ms)
|
||||
✔ chat status line: served commit and age, divergence, fetch error and the problems one click away (897.997997ms)
|
||||
✔ chat status line: limits when the status carries them, no problems, and refusals (1133.380317ms)
|
||||
✔ chat status line: a project with no repository link reads no library status (854.88335ms)
|
||||
✔ chat status line: unreadable reply limits show their problem and both fallback keys (882.924328ms)
|
||||
✔ chat replies: unchanged file at a different library commit and incomplete checks stay unmarked (768.120005ms)
|
||||
✔ chat status line: an invalid library mapping remains visible for diagnosis (737.619858ms)
|
||||
✔ chat replies: a checked notice-shaped agent message is plain text with no Revert (725.56059ms)
|
||||
✔ chat replies: owner-only without a sent field is a definite Revert refusal (811.129366ms)
|
||||
✔ 272 fallback: granted legacy route keeps default history, send and open without session controls (715.832685ms)
|
||||
✔ 272 fallback guard: granted explicit-session route refuses without default history or writes (631.667619ms)
|
||||
✔ 272 fallback guard: human-required catalog failure never enables default-thread access (663.54337ms)
|
||||
✔ 272 fallback guard: timeout catalog failure never enables default-thread access (537.528495ms)
|
||||
✔ 272 fallback guard: no-bus-host catalog failure never enables default-thread access (622.030953ms)
|
||||
✔ 272 fallback guard: malformed catalog failure never enables default-thread access (624.379398ms)
|
||||
✔ 272 fallback guard: owner route retains chooser and explicit default-session addressing (635.748276ms)
|
||||
✔ chat reads map only fixed verbs, strict forward paging and pure GET (40.110234ms)
|
||||
✔ chat refuses malformed and repeated query/id values before transport (7.000459ms)
|
||||
✔ chat project.create: one verified write, fixed identity/class and private log (2.986922ms)
|
||||
✔ chat project.create: each existing Console write fence makes zero bus calls (8.933369ms)
|
||||
✔ chat project.create: refusal or lost/malformed receipt never retries or invents success (5.056788ms)
|
||||
✔ chat thread.create: one verified write, fixed identity/class and private log (1.581993ms)
|
||||
✔ chat thread.create: each existing Console write fence makes zero bus calls (8.197701ms)
|
||||
✔ chat thread.create: refusal or lost/malformed receipt never retries or invents success (3.965463ms)
|
||||
✔ chat thread.send: one verified write, fixed identity/class and private log (1.353806ms)
|
||||
✔ chat thread.send: each existing Console write fence makes zero bus calls (6.740756ms)
|
||||
✔ chat thread.send: refusal or lost/malformed receipt never retries or invents success (4.970022ms)
|
||||
✔ chat thread.open: one verified write, fixed identity/class and private log (1.438093ms)
|
||||
✔ chat thread.open: each existing Console write fence makes zero bus calls (6.978012ms)
|
||||
✔ chat thread.open: refusal or lost/malformed receipt never retries or invents success (3.64445ms)
|
||||
✔ chat createThread receipt requires an instance even when its id is valid (2.535217ms)
|
||||
✔ chat write receipts expose only the fields belonging to their operation (3.886809ms)
|
||||
✔ chat validates names, body, project and strict empty open payload (5.948932ms)
|
||||
✔ chat read failures redact ownership and refuse invalid transport arrays (7.572799ms)
|
||||
✔ REQ-USER-2 real broker: owned catalog, create/name/filter, isolated history and 403/404 without mutations (108.639676ms)
|
||||
✔ chat repeats every POST boundary even when called behind an admitted request (1.210711ms)
|
||||
✔ configured Console process injects chat through its existing human transport (201.842342ms)
|
||||
✔ chat assets, GET purity, method and unknown-route refusals are explicit (15.908528ms)
|
||||
✔ the chat seam names the transport it is given: the human one and the tester one both pass, anything else is a TypeError (0.594861ms)
|
||||
✔ C2-09a createThread forwards an explicit instance through the existing channel (4.877049ms)
|
||||
✔ C2-09a malformed instance and extra thread fields refuse before the channel write (4.621594ms)
|
||||
✔ 264e session catalog/create and explicit selectors keep the human transport and strict keys (6.446ms)
|
||||
✔ 264e session writes retain Origin/identity fences and explicit selector errors (3.221617ms)
|
||||
✔ 264e clear envelope is projected, pending is preserved and GET never repeats the clear (5.920053ms)
|
||||
✔ 264e cancel is an authenticated, confirmed human write and retains retirement distinction (7.831208ms)
|
||||
✔ 272 N1: malformed clear/cancel write receipts get one redacted outcome-unknown audit line (5.831884ms)
|
||||
✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (1306.1032ms)
|
||||
✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (1836.119679ms)
|
||||
✔ conversation view: a newer session with no readable history keeps the marker (1285.484193ms)
|
||||
✔ conversation view: seats without history say so and offer no reply (1047.035848ms)
|
||||
✔ J16: no controls without sso and decide, read-only reasons, terminal lines kept, and only an eligible grant gets the panel (5771.215266ms)
|
||||
✔ J17: one POST per click, confirm then answer, cancel, refusals and an unknown outcome never retry (5272.178631ms)
|
||||
✔ a sign-in redirect at either step signs the page out and answers nothing (1989.670657ms)
|
||||
✔ a signed-in owner confirms and answers, with the session's provider, issuer and sub as the subject (213.942672ms)
|
||||
✔ the listener gates: no session, a cross-origin page, a loopback Host, a GET, and a sign-out between the steps (77.826712ms)
|
||||
✔ J16: without a decision transport the routes are read-only and /api/config says no; startServer refuses decide without sso or send (481.428976ms)
|
||||
✔ J19: a granted user's session gets decide false and the user page config, and a decision POST stops at owner-only (54.985489ms)
|
||||
✔ N4: decision.resolve has no Console route, the --send caller names no decision verb, and consoleCall takes only the two console verbs (80.240021ms)
|
||||
✔ a confirmation then a resolve answers once with the held choice and digest, and a second resolve refuses (3.814984ms)
|
||||
✔ deny resolves without a grant field (0.482281ms)
|
||||
✔ the gates before the body: method, read-only, sign-in and same origin (0.49765ms)
|
||||
✔ a bad body, id or content type refuses before the bus (0.762162ms)
|
||||
✔ a choice that is neither key is decision-stale, and a malformed preview is confirmation-unavailable (0.681931ms)
|
||||
✔ bus refusals map by code, and an unknown or missing code is unavailable at preview and outcome-unknown at resolve (2.862415ms)
|
||||
✔ a confirmation binds the session, decision and choice, and any mismatch spends it (0.81855ms)
|
||||
✔ a session that ends between the steps refuses before the bus (0.438239ms)
|
||||
✔ confirmations expire after the TTL, cap at the limit without dropping a live one, and are one use (0.323839ms)
|
||||
✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (1065.529279ms)
|
||||
✔ the editor: the list, hostile markdown that runs nothing, the draft, and each save receipt (2140.805191ms)
|
||||
✔ the Console's CSP stands and the editor runs under it; hostile markdown on the load path runs and loads nothing (1354.955091ms)
|
||||
✔ hostile content pasted into the editor runs and loads nothing, and a bad link target is refused in the link bar (1547.923208ms)
|
||||
✔ a pasted image span is kept only for a target the link gate accepts, and a save writes only those (1266.979424ms)
|
||||
✔ a switch of view reads nothing; a reload, and a trip away and back, each read the file exactly once (2940.297024ms)
|
||||
✔ an edit rewrites only the block touched; a save sends the rest byte for byte; the Source view carries the draft (1214.212642ms)
|
||||
✔ a file the editor cannot write back byte for byte opens as Source, says so, cannot save, and the Visual button works once it can (2204.177601ms)
|
||||
✔ a link title pasted with line breaks in it is written on one line, so no HTML block comes of it (954.989036ms)
|
||||
✔ an image alt pasted with line breaks in it is written on one line, so no HTML block comes of it (876.671026ms)
|
||||
✔ an image title pasted with line breaks in it is written on one line, so no HTML block comes of it (876.342459ms)
|
||||
✔ a code block info string pasted with line breaks in it is written on one line, so no HTML block comes of it (851.548483ms)
|
||||
✔ a link title holding a quote after a backslash then a tag is written with the backslash escaped, so the title stays closed (973.526659ms)
|
||||
✔ an image title holding a quote after a backslash then a tag is written with the backslash escaped, so the title stays closed (730.164235ms)
|
||||
✔ a link title holding a trailing backslash is written with the backslash escaped, so the title stays closed (705.431094ms)
|
||||
✔ an image title holding a trailing backslash is written with the backslash escaped, so the title stays closed (716.592245ms)
|
||||
✔ a code block info string with a backtick, pasted, is dropped on Save, so the fence stays closed (764.08523ms)
|
||||
✔ a code block info string with a backtick, as a tilde fence can have, is kept as source, not rewritten without it (846.538059ms)
|
||||
✔ the imported source is the tagged upstream source plus the recorded local changes, and nothing else (26.175796ms)
|
||||
✔ every package names its origin and license, and NOTICE lists each (1.097644ms)
|
||||
✔ the build reads only imported source and the editor's own files; the bundle is the recorded build (8.957963ms)
|
||||
✔ MOSAIC_REQUIRE_EDITOR_BUILD: a missing or wrong esbuild skips without it and fails with it; a wrong binary always fails (7.544758ms)
|
||||
✔ the toolchain check, run as a program, exits non-zero without esbuild when the build is required (302.664165ms)
|
||||
▲ [WARNING] Ignoring this import because "third_party/editor/prosemirror-transform/src/mark.ts" was marked as having no side effects [ignored-bare-import]
|
||||
|
||||
third_party/editor/prosemirror-transform/src/index.ts:10:7:
|
||||
10 │ import "./mark"
|
||||
╵ ~~~~~~~~
|
||||
|
||||
"sideEffects" is false in the enclosing "package.json" file:
|
||||
|
||||
third_party/editor/prosemirror-transform/package.json:13:2:
|
||||
13 │ "sideEffects": false,
|
||||
╵ ~~~~~~~~~~~~~
|
||||
|
||||
✔ rebuilding from the source gives the same bytes (needs the pinned esbuild; MOSAIC_REQUIRE_EDITOR_BUILD=1 makes its absence a failure) (172.641917ms)
|
||||
✔ wikilink round-trip: plain (9.175577ms)
|
||||
✔ wikilink round-trip: labelled (1.129295ms)
|
||||
✔ wikilink round-trip: heading target (1.25613ms)
|
||||
✔ wikilink round-trip: list item (1.645832ms)
|
||||
✔ wikilink round-trip: next to front matter (1.202128ms)
|
||||
✔ wikilink round-trip: heading block and combined label (1.18696ms)
|
||||
✔ wikilink round-trip: spaces, Unicode and adjacent links (2.377579ms)
|
||||
✔ wikilink round-trip: reference-definition collision (2.902031ms)
|
||||
✔ wikilink round-trip: inside an ordinary link (4.241793ms)
|
||||
✔ wikilink round-trip: inert embed (0.63341ms)
|
||||
✔ wikilinks are inline atoms and survive a neighbouring edit in every required context (1556.425084ms)
|
||||
✔ code, escaped openers, malformed syntax and HTML-like targets stay outside wikilink atoms (1452.825353ms)
|
||||
✔ wikilink DOM paste accepts only bounded single-line inert syntax; malformed attrs serialise as escaped text (1000.711061ms)
|
||||
✔ the editor routes serve the built files with their types and no cache (46.893995ms)
|
||||
✔ open and save with no edit writes the same bytes: the goals review and a doc with every element (21.572081ms)
|
||||
✔ open and save with no edit writes the same bytes: every repository doc under docs/ and spec/ (2160.196477ms)
|
||||
✔ the editor source builds markup only with DOM calls, and the bundle has no eval (4.311024ms)
|
||||
✔ the link gate and the image rule are the preview's (1.175245ms)
|
||||
✔ R6 G1 a granted user signs in, gets the user page and reaches the broker as itself (172.773172ms)
|
||||
▶ R6 G2 a subject with no live grant in this business is refused subject-unknown
|
||||
✔ a listed user with no grant (92.602053ms)
|
||||
✔ a grant in another business (104.491345ms)
|
||||
✔ an expired grant (114.256083ms)
|
||||
✔ another user's grant (55.98006ms)
|
||||
✔ a sub in no file (64.883816ms)
|
||||
✔ a file the loader refuses (90.210241ms)
|
||||
✔ R6 G2 a subject with no live grant in this business is refused subject-unknown (523.697455ms)
|
||||
▶ R6 G3 a revoke counts on the next request: 401 and the session is gone
|
||||
✔ grant removed (62.972504ms)
|
||||
✔ subject removed (93.888865ms)
|
||||
✔ grant expired (106.472694ms)
|
||||
✔ file now refused (112.582013ms)
|
||||
✔ R6 G3 a revoke counts on the next request: 401 and the session is gone (377.178827ms)
|
||||
✔ R6 G4 every owner route answers 403 owner-only before any bus call (127.865636ms)
|
||||
✔ R6 G5 the bus refuses every owner verb over the user transport on its own (123.119351ms)
|
||||
✔ R6 G9 a user chat sends only the plugins read over the owner transport (130.557956ms)
|
||||
✔ R6 G6 the user page holds the notice word for word (75.808533ms)
|
||||
✔ R6 G7 the hub label and plain peer links render from config on both pages (984.121102ms)
|
||||
✔ R6 G8 userCall spawns user-cli directly with the user nonce, no human nonce, and the user request (51.702992ms)
|
||||
✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (52842.755773ms)
|
||||
✔ row 165 Settings: role instances read, add with a restart named, change without one, a refusal keeps the draft (2069.883646ms)
|
||||
✔ row 165 Console: the signed-in human adds an instance through a real broker; validate exits 0, the log names the human and no restart is needed (row 194) (261.303304ms)
|
||||
✔ row 165 Console: the instance write needs send on, the public name, the user, the exact Origin and same-origin Fetch Metadata (10.054646ms)
|
||||
✔ row 165 Console: the instance write takes JSON within 16 KiB and only its own keys; holder, credentials and an actor are refused (9.747938ms)
|
||||
✔ row 165 Console: a bus refusal says nothing changed; a lost or odd answer says the change may have been made (15.879235ms)
|
||||
✔ row 165 Console: the instances read takes no arguments, needs a bus and refuses an answer without a revision (6.37516ms)
|
||||
✔ C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport (208.823243ms)
|
||||
✔ a signed-in same-origin revert reaches exactly one library.revert and returns the new commit (25.090439ms)
|
||||
✔ a revert needs send, the named Host, the user, the exact Origin and same-origin Fetch Metadata (8.67138ms)
|
||||
✔ a revert takes a project and a 40-hex commit, nothing else, before the bus is asked (7.475126ms)
|
||||
✔ a bus refusal is reported as not reverted with its code; before C2-02 that is the verb refusal (9.725112ms)
|
||||
✔ a revert whose answer is lost or unusable is reported unknown and is never retried (7.701918ms)
|
||||
✔ the status read takes one project query and answers the bus result for that project (4.432751ms)
|
||||
✔ a status answer for another project or of the wrong shape is refused; a refusal keeps its status (9.479692ms)
|
||||
✔ the status read needs no send; a read-only Console still has no revert (2.316938ms)
|
||||
✔ library routes are the owner's: a granted user is refused them, and the tester never reverts (0.874467ms)
|
||||
✔ the page gets the one library renderer, byte for byte, as a JavaScript module (1.946831ms)
|
||||
✔ a revert receipt for another project is unknown and is never retried (1.698516ms)
|
||||
✔ a granted-user HTTP session cannot reach owner library callbacks (2.11729ms)
|
||||
✔ a configured revert callback remains unreachable when send is off (1.619535ms)
|
||||
✔ row 254: each library sync code maps to its status (0.875525ms)
|
||||
✔ REQ-LIMIT-3 REQ-LIMIT-4 Settings shows token limits counted, not enforced and check failed; Reset posts one path; a save keeps the token limits (1283.613274ms)
|
||||
✔ Row 167 with an assistant draft open, a token limit reset gives the assistant submit its revision (951.959609ms)
|
||||
✔ REQ-LIMIT-3 limits read returns only the token rows; no query or write is accepted (36.003397ms)
|
||||
✔ REQ-LIMIT-3 a limits answer without a token list is refused, not shown as no limits (11.374745ms)
|
||||
2026-10-24T22:11:16.186Z settings user="jason" changed
|
||||
✔ REQ-LIMIT-3 a Settings reset reaches the human write with its paths; a reset alone is enough (7.465903ms)
|
||||
✔ REQ-LIMIT-3 the Console reader asks the bus limits verb with no arguments (0.460687ms)
|
||||
✔ the preview source names none of the four string-to-markup sinks (1.2239ms)
|
||||
✔ headings, paragraphs, emphasis and inline code render (1.52146ms)
|
||||
✔ lists, block quotes and code blocks render (0.569678ms)
|
||||
✔ a link is made for http, https and relative targets, with rel and the target shown (1.167267ms)
|
||||
✔ a link with any other scheme, or an evasion of the scheme, stays source text (1.071465ms)
|
||||
✔ an image shows alt text and URL, is never an img element and never loads (0.176798ms)
|
||||
✔ raw HTML, entities and unsupported blocks show as source text, never as elements (0.390592ms)
|
||||
✔ markup inside code and inside link text stays text (0.199256ms)
|
||||
✔ hostile and pathological input stays within its look-ahead budget and under the nesting cap (48.760884ms)
|
||||
✔ trailing blanks and closing hashes are cut by a walk from the end, not a regex that retries inside a blank run (35.531804ms)
|
||||
✔ a link opener with no closer searches at most SPAN characters ahead (188.875275ms)
|
||||
✔ the look-ahead work of one render is a fixed multiple of the text, whatever the opener (848.275978ms)
|
||||
✔ past the budget an opener is source text, through the path all other text takes (17.235886ms)
|
||||
✔ a normal 200 KiB document renders exactly as it did without a budget, and spends little of it (25.044171ms)
|
||||
✔ a line separator inside a heading, a list item or a fence line does not end the marker line (0.595681ms)
|
||||
✔ a thematic-break line is a paragraph, every other marker line opens a list (0.433323ms)
|
||||
✔ every short line over space, tab, - * _ and a letter is a break exactly when the old regex said so (48.393695ms)
|
||||
✔ one line of marks does not throw, at 4 MiB, whatever the mark or the spacing (7867.726504ms)
|
||||
✔ CRLF and tabs are read like LF and spaces; empty input renders nothing (0.182135ms)
|
||||
✔ messages HTTP read pages and preserves metadata; bad arguments refuse before a read; other reads unchanged (114.721485ms)
|
||||
✔ Console Messages lists late unsolicited messages on polling with sender class time read state and trail; nav count includes beyond the page; reads never deliver (1227.204744ms)
|
||||
✔ Messages nav count polls on Tasks and Board and clears on a Board refusal; messages 403 refuses local pages (2003.078514ms)
|
||||
✔ copy writes the Console paths at the full id, read-only, and leaves an existing copy alone (1488.436066ms)
|
||||
✔ copy refuses a commit off refactor, an unknown one, a worktree and a bad copies directory (1597.975802ms)
|
||||
✔ copy writes nothing when an archived path is missing at the commit (579.510216ms)
|
||||
✔ a copy that loses the rename race leaves no read-only temp directory behind (673.135629ms)
|
||||
✔ a copy whose rename fails with no target refuses, writes no copy and leaves no temp directory (710.289827ms)
|
||||
✔ a copy that meets a target holding files says exists: and moves nothing into it (732.806597ms)
|
||||
✔ a copy that meets an empty target directory replaces it by rename, not by moving into it (612.835517ms)
|
||||
✔ serve runs from a copy: /healthz 200, the config check, roles and RELEASE from the copy, the queue from --checkout (1149.224132ms)
|
||||
✔ serve refuses a --checkout that is not an absolute directory path (375.216061ms)
|
||||
✔ consoleReads runs the queue read under queueRoot and reads RELEASE under root (69.061909ms)
|
||||
✔ preview options are all three or none, and each is checked (11.596651ms)
|
||||
✔ the CLI refuses a partial or invalid preview flag set at start (945.562554ms)
|
||||
✔ the CLI with all three flags serves the preview mode (193.560054ms)
|
||||
✔ a request for the public name needs the header equal to the user id, else 401 and nothing read (21.565508ms)
|
||||
✔ the header name matches without regard to case, and the value compare is exact (3.95808ms)
|
||||
✔ the public name with the header reads the bus views, and the Host and Origin are checked first (33.216972ms)
|
||||
✔ in preview mode every write answers 403 read-only, from the public name and loopback, and reaches nothing (13.946391ms)
|
||||
✔ loopback requests are unchanged in preview mode, and the bus views work with the board down (21.317768ms)
|
||||
✔ a proxy that rewrites Host to the loopback port gets 403 on its first request, whatever the user (20.422653ms)
|
||||
✔ a repeated Host is 400 before any other check, in preview mode and without it (11.215391ms)
|
||||
✔ without the preview flags the public name is refused and writes still reach the board (5.587922ms)
|
||||
✔ processing browser: keyboard Stop, confirmed Resume, unknown outcome and persistent banner (718.01676ms)
|
||||
✔ processing browser: Q175 read-only interim keeps both writes disabled and names CLI recovery at 320px (695.148762ms)
|
||||
✔ processing browser: sign-out from config redirect blocks later refresh and writes (824.165228ms)
|
||||
✔ processing browser: sign-out from state redirect blocks later refresh and writes (860.253673ms)
|
||||
✔ processing browser: sign-out from write redirect blocks later refresh and writes (806.441355ms)
|
||||
✔ processing browser: sign-out from config sign-in required blocks later refresh and writes (864.004948ms)
|
||||
✔ processing browser: sign-out from state sign-in required blocks later refresh and writes (886.919472ms)
|
||||
✔ processing browser: sign-out from write sign-in required blocks later refresh and writes (960.067268ms)
|
||||
ROW191_LAYOUT {"width":400,"height":1000,"controls":97,"tree":324.0625,"main":1450.703125,"top":181.5,"bottom":217.5,"barBottom":129,"projectsTop":352.59375,"order":"0","visible":true}
|
||||
ROW191_LAYOUT {"width":1440,"height":1000,"controls":127,"tree":914,"main":914,"top":135.5,"bottom":171.5,"barBottom":53,"projectsTop":636.59375,"order":"0","visible":true}
|
||||
ROW191_LAYOUT {"width":1440,"height":420,"controls":127,"tree":334,"main":907.734375,"top":135.5,"bottom":171.5,"barBottom":53,"projectsTop":636.59375,"order":"0","visible":true}
|
||||
ROW191_LAYOUT {"width":800,"height":420,"controls":127,"tree":334,"main":1131.65625,"top":135.5,"bottom":171.5,"barBottom":53,"projectsTop":618.59375,"order":"0","visible":true}
|
||||
✔ processing browser: static nav controls keep Stop visible, ordered and keyboard reachable (764.42746ms)
|
||||
✔ interim read-only controls show CLI recovery, disable both writes and retain a halted banner across views (8.191348ms)
|
||||
✔ Stop sends one empty halt and Resume confirms before sending the displayed generation (2.947603ms)
|
||||
✔ a cancelled resume never calls the writer (1.219134ms)
|
||||
✔ unknown writes are not retried or displayed as success and partial stops remain explicit (2.112188ms)
|
||||
✔ the persistent shell loads the control outside route-specific content with accessible status and native buttons (0.471441ms)
|
||||
✔ read-only Console can read processing state but neither human control writes without --send (23.636966ms)
|
||||
✔ Console halt and generation-bound resume use only the management writer and keep partial stops honest (4.923203ms)
|
||||
✔ processing write fences refuse cross-site, wrong origin, unnamed host, duplicate identity and bad payload before writer (7.499038ms)
|
||||
✔ tester cannot invoke either control writer and failures never echo backend text (5.000005ms)
|
||||
✔ processing writes use the existing SSO signer and still require --send and same-origin (5.29471ms)
|
||||
✔ processing handler independently refuses wrong origin and cross-site before its writer (0.741847ms)
|
||||
✔ a signed-in same-origin save reaches exactly one human operation and returns the new commit (22.355345ms)
|
||||
✔ a save needs send, the named Host, the user, the exact Origin and same-origin Fetch Metadata (8.492884ms)
|
||||
✔ a save validates JSON, strict keys, text values and the 1 MiB body before the bus is asked (19.453599ms)
|
||||
✔ a body that is JSON but not an object is refused 400, not thrown on (5.777613ms)
|
||||
✔ the 1 MiB limit is this route only; Settings and messages keep 16 KiB (2.581226ms)
|
||||
✔ a bus refusal is reported as not saved with its own status; stale-base tells the user to reload (6.148622ms)
|
||||
✔ a save whose answer is lost or unusable is reported unknown and is never retried (3.873987ms)
|
||||
✔ the file list and one file read take strict queries and arrive in the expected shape (4.947705ms)
|
||||
✔ reads work without --send; an unusable bus answer is a bad response, a refusal keeps its status (3.061043ms)
|
||||
✔ /api/config says edit only where a save can pass (2.093648ms)
|
||||
✔ a repository-name project refusal is an HTTP conflict (0.589542ms)
|
||||
✔ proof startup refuses partial flags non-preview and invalid fixture file metadata or bytes (1372.358151ms)
|
||||
✔ serve argv carries only fixture proof path and header; startup explicitly reports proof on or off (296.532456ms)
|
||||
✔ CLI applies proof on the main listener and rejects that header on its tester listener (281.757503ms)
|
||||
✔ proxy proof admits named reads and sends, reads its fixture once, and never exposes the value (34.129527ms)
|
||||
✔ proxy proof refuses missing wrong short or repeated proof before auth and before any read (10.977149ms)
|
||||
✔ proxy proof header is refused on other Hosts and on the tester listener (5.374102ms)
|
||||
✔ proof options reject unsafe or colliding header names without disclosing file contents (0.797857ms)
|
||||
✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.703483ms)
|
||||
✔ credential state from the date alone, as the bus states it (0.208011ms)
|
||||
✔ queue: rows, one row, ids and methods, notes; no path or id from a row (414.58832ms)
|
||||
✔ queue: a refused read fails closed with the store's text, redacted (210.374206ms)
|
||||
✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (858.43953ms)
|
||||
✔ business: names, vars on the allowlist, authority, credential metadata only (17.500331ms)
|
||||
✔ business: missing or invalid file refuses with the module's text, redacted (8.383354ms)
|
||||
✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.244873ms)
|
||||
✔ settings: release, board, loopback address, notifier binding name only (129.222379ms)
|
||||
✔ task fields: the committed table with no reads configured, GET only; a bad table refuses with no path (18.325509ms)
|
||||
✔ bus-status: a refused boot shows reason, file and last good load; a live host or an ok boot clears it (8.620563ms)
|
||||
✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (912.269858ms)
|
||||
✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (20871.244615ms)
|
||||
organization: {"event":"reload-needs-restart","business":"acme"}
|
||||
organization: {"event":"reload-needs-restart","business":"acme"}
|
||||
✔ row 65 Settings: the routing table lists every instance, saves a harness, model, thinking and fallback to the file, and keeps the draft on each refusal (1456.057342ms)
|
||||
organization: {"event":"reload-needs-restart","business":"acme"}
|
||||
✔ row 65 Console: the signed-in human saves a route through a real broker; each refusal says nothing changed and leaves the file and the log (124.733405ms)
|
||||
✔ row 65 Console: the routes write needs send on, a writer, the public name, the user, the exact Origin and same-origin Fetch Metadata (7.984846ms)
|
||||
✔ row 65 Console: the routes write takes JSON within 16 KiB with a revision and routes only; an actor is refused and routes are never logged (9.931147ms)
|
||||
✔ row 65 Console: a bus refusal maps to its status and says nothing changed; a lost or odd answer says the change may have been made (24.176558ms)
|
||||
✔ row 65 Console: the routes read takes no arguments, needs a bus and refuses an odd answer (7.91025ms)
|
||||
✔ the send box: held roles, the draft and caret across a refresh, each receipt, one POST per Send, and the trail link; the board Reply on a 4xx and a 5xx (2577.785116ms)
|
||||
✔ a sent receipt lists its replies as the page refreshes, oldest first and capped, and marks none delivered or read (11216.600397ms)
|
||||
✔ startServer takes send only as a function and only with the preview mode (8.305533ms)
|
||||
✔ the CLI refuses --send without the preview flags, and without a configured bus (622.972543ms)
|
||||
✔ the CLI with --send and a configured bus sends through the human transport and logs one line (188.71069ms)
|
||||
✔ without --send the route is read-only like every other write, and config says no send (10.412469ms)
|
||||
✔ with --send every other write is still 403 read-only, and nothing reaches the board or bus (8.881331ms)
|
||||
✔ config says send only on the public name with --send on (4.624696ms)
|
||||
✔ a send without the signed-in user is 401 and is neither sent nor logged, loopback included (6.736458ms)
|
||||
✔ each request check refuses before anything is sent, and logs the refusal without the body (23.776724ms)
|
||||
✔ a send passes exactly to, body and in_reply_to, answers the id, and logs it (3.435425ms)
|
||||
✔ a crafted role name cannot forge a log line (2.520457ms)
|
||||
✔ a bus refusal is not sent, with its status; an outcome the bus could not confirm is unknown and never retried (8.782419ms)
|
||||
✔ through the human transport the request is exactly the business, message.send and the keys (100.281561ms)
|
||||
✔ against a real broker: the message is written once as a human send, and its refusals map (31.579317ms)
|
||||
✔ loopback host and board origin fail closed (6.349957ms)
|
||||
✔ real board fixture passes through WebUI; assets and isolated seen/reply work (85.238919ms)
|
||||
✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (49.199627ms)
|
||||
✔ unreachable board reports URL; CLI rejects unsupported options (479.978274ms)
|
||||
✔ tester service render carries the tester port alongside existing flags (134.959305ms)
|
||||
✔ tester service refuses forwarded 7332 even with another main port (111.314937ms)
|
||||
✔ tester service invalid ports refuse render and install with exit 4 and leave the unit alone (1140.951065ms)
|
||||
✔ tester service counts the digits as written before it strips leading zeros (106.037477ms)
|
||||
✔ tester service install and status show the tester port without changing send reporting (550.730447ms)
|
||||
✔ render prints the unit without the preview flags (50.043501ms)
|
||||
✔ render carries every serve flag, the preview set included (48.3057ms)
|
||||
✔ a partial preview set is refused (116.014202ms)
|
||||
✔ a value the unit cannot carry is refused, for every flag (2672.644014ms)
|
||||
✔ the rendered unit names none of the human proof agent markers and sets no agent variable (239.356908ms)
|
||||
✔ install into --dir with --no-reload writes the file whole, then reports unchanged (287.45407ms)
|
||||
✔ install without --no-reload runs daemon-reload and nothing that starts the unit (62.23267ms)
|
||||
✔ uninstall refuses while the unit is running, with or without --no-reload, and removes it once it is not (564.150662ms)
|
||||
✔ status prints the unit state and GET /healthz on the installed port (418.000891ms)
|
||||
✔ usage: an unknown verb or flag, and start or enable, exit 4 (748.152129ms)
|
||||
✔ without --send, render is the template with its placeholders filled, byte for byte (191.946387ms)
|
||||
✔ render --send with the preview set ends ExecStart with --send and changes nothing else (314.493899ms)
|
||||
✔ --send without the whole preview set is refused and writes nothing (731.918561ms)
|
||||
✔ install --send into --dir with --no-reload writes the sending unit, and status says whether it sends (513.043402ms)
|
||||
✔ uninstall and status take no --send (164.863424ms)
|
||||
✔ install refuses while the unit is running, in any state but inactive or failed, and changes nothing (697.765957ms)
|
||||
✔ when the state read fails, install and uninstall refuse with one line and change nothing (238.392922ms)
|
||||
✔ install needs --copy naming a copy that exists, and refuses outside the canonical checkout without --allow-worktree (355.132277ms)
|
||||
✔ install refuses unless the bus unit runs from the same copy, naming both paths, and changes nothing (735.389915ms)
|
||||
✔ render --copy runs the copy and reads the queue in the checkout; without --copy the unit is unchanged (114.218835ms)
|
||||
✔ the uid header takes only an Authentik uid; the username header still takes a username (2531.254234ms)
|
||||
✔ a preview value cannot start with - or . (295.955168ms)
|
||||
✔ status names the copy and whether refactor has moved past it, and says when the unit runs from no copy (877.622422ms)
|
||||
✔ proxy proof render carries both flags but never opens the fixture file (89.223556ms)
|
||||
✔ proxy proof render refuses incomplete non-preview missing unsafe-mode and repo/copy paths (565.728452ms)
|
||||
✔ proxy proof status retains send and tester reporting with both proof flags (170.319152ms)
|
||||
✔ row196 socket flag renders only for supporting targets and refuses mixed transports (114.439527ms)
|
||||
✔ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (1360.394114ms)
|
||||
✔ Q169 Assistant section: gated, changed fields only, name and stop posts, retained draft and no automatic retry (1339.787079ms)
|
||||
✔ Row 167 a refused names read gives the refused usage page; another names failure keeps the Assistant section (1001.13625ms)
|
||||
✔ Row 167 with a limits draft open, an assistant save gives the limits submit its revision and the typed limit stays (961.46178ms)
|
||||
✔ Row 167 with an assistant draft open, a launch save gives the assistant submit its revision, and reload reads the current one (919.499255ms)
|
||||
2026-10-24T22:12:18.574Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (20.814698ms)
|
||||
✔ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (7.338296ms)
|
||||
✔ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (5.704514ms)
|
||||
✔ Q169 a Console change of the assistant reaches the human operation unchanged, and the log names the signed-in user (3.12922ms)
|
||||
✔ tokens.css and icons.svg are byte copies of docs/design (2.466959ms)
|
||||
✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.202837ms)
|
||||
✔ shipped strings are unchanged, and the web keeps its write boundary (3.483166ms)
|
||||
ROW191_LAYOUT {"width":1440,"height":1000,"controls":212.5,"tree":914,"main":914}
|
||||
✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5724.337234ms)
|
||||
✔ five states on Board, Inbox, Tasks, Agents and Trail (2781.461551ms)
|
||||
✔ a 401 sign-in required on each fetch path signs the page out with a sign-in link and stops the refresh; another 401 stays an error (5951.403032ms)
|
||||
✔ the Sign out form shows only when /api/config says sso, and posts to /auth/logout (1240.276745ms)
|
||||
✔ positive: an RS256 provider signs in and sends one message, and the session reads (144.348303ms)
|
||||
✔ positive: an ES256 provider signs in and sends (20.592669ms)
|
||||
✔ positive: two providers each sign in their own subjects, and one provider's subject is unknown to the other (61.371982ms)
|
||||
✔ 1: a forged x-authentik header without a cookie is 401 on the API and a sign-in redirect on a page (43.593455ms)
|
||||
✔ 2: an HS256 ID token keyed with the client secret and a real RSA kid is refused (73.089469ms)
|
||||
✔ 3: a wrong aud, and an aud list holding another client with no azp, are refused (33.086381ms)
|
||||
✔ 4: a token that expired 10 minutes ago is refused (63.584637ms)
|
||||
✔ 5: another issuer, and the issuer without its trailing slash, are refused (48.311745ms)
|
||||
✔ 6: a nonce mismatch and a missing nonce are refused (27.913813ms)
|
||||
✔ 7: state mismatch, no login cookie, a replay, an expired record and two login cookies are refused (67.213632ms)
|
||||
✔ 8: the token request carries the PKCE verifier, and the OP refuses a wrong one (46.450232ms)
|
||||
✔ 9: alg none, a changed payload under a real kid, and an unknown kid even after the refetch are refused (208.50079ms)
|
||||
✔ 10: a valid token for a subject not configured is 403 with one subject-unknown line (114.43639ms)
|
||||
✔ 11: start refusals: HS or none algs, reserved names, HS-only discovery, an empty JWKS, no S256, an issuer mismatch, a short RSA key (276.730279ms)
|
||||
✔ 11: slot files: a symlink, mode 0644, mode 0640 and a file under the repository are refused, and no message holds the value (2.126877ms)
|
||||
✔ 11: the CLI refuses --sso with the old flags and without console.sso, and starts with a good one (1317.326217ms)
|
||||
✔ 12: under --sso the tester listener refuses each kind of sign-in, has no /auth, and startServer refuses tester with sso (61.815926ms)
|
||||
✔ 13: idle and absolute expiry, logout then reuse, a cross-origin logout, and background reads that don't keep a session (112.338051ms)
|
||||
✔ 13: the CSP lets the Sign out form reach the provider's end-session origin, and only under --sso (136.264868ms)
|
||||
✔ 14: open redirects land on /, and a path on the Console lands there (125.077087ms)
|
||||
✔ 15: a callback for A carrying B's code and iss, and a provider= query, is refused (114.160441ms)
|
||||
✔ 16: a provider with RS256 and ES256 takes either, and refuses PS256 with a usable PS256 key in the JWKS (111.659664ms)
|
||||
✔ 17: 33 started logins leave 32 records, and the first one's callback finds none (59.820684ms)
|
||||
✔ 18: after a key rotation a sign-in works through one refetch, and the removed kid is refused (119.662583ms)
|
||||
✔ 20 and 21: the store holds no raw session id, and the cookie strings are exact (36.447359ms)
|
||||
✔ 22: a loopback Host is 403 on a page, a read and a write; /healthz on loopback is 200; a redirect_uri never comes from the Host (64.398495ms)
|
||||
✔ 23: a provider down at start leaves the Console up and 503, and the retry makes sign-in work (225.671097ms)
|
||||
✔ 19: no captured log line holds a token, code, state, nonce, verifier, client secret or session id (4.654356ms)
|
||||
✔ tester Console banner exposes only instance route and name editors and saves a route as tester (1004.885424ms)
|
||||
✔ row 177: the tester Console chat composer is enabled and a send shows in its own thread (882.644221ms)
|
||||
✔ tester-port validates range tunnel main port and requires configured bus before listening (1166.339822ms)
|
||||
✔ CLI tester listener binds a private Unix socket and spawns TESTER_CLI for every Console bus read (4245.099179ms)
|
||||
✔ main listener refuses x-mosaic-tester before any board or bus read for every Host (28.708091ms)
|
||||
✔ tester listener rejects preview binding and requires its fixed logical Host and no proxy auth header (145.683675ms)
|
||||
✔ tester listener writes only instances routes and names with tester receipts and actor (158.995936ms)
|
||||
✔ tester listener refuses every human-only write with no bus call (108.260486ms)
|
||||
✔ tester-off and tester-required reads return HTTP 403 (109.020476ms)
|
||||
✔ tester credentials routes and committed project reads keep secrets and paths bounded (194.378994ms)
|
||||
✔ row 177 W1: the tester chat makes, sends to, opens and reads its own thread as tester (30.75864ms)
|
||||
✔ row 177 W2: tester chat writes refuse a missing or foreign Origin, cross-site, text/plain and the proxy header with no bus call (16.544702ms)
|
||||
✔ row 177 W3: the human thread through the tester chat is thread-not-owned, and bus.tester off answers tester-off (38.09277ms)
|
||||
✔ row 177 W4: the main listener refuses x-mosaic-tester on chat reads and writes before the chat (3.174145ms)
|
||||
✔ Row 252: the tester listener has no decision answer routes, and its config never offers them (115.156837ms)
|
||||
✔ private tester HTTP serves on 0600 socket in 0700 parent and fixed origin (92.027264ms)
|
||||
✔ private tester refuses symlink, unsafe parent and long path without repairs (1.361981ms)
|
||||
✔ tester cleanup must leave a replacement inode untouched (1.910765ms)
|
||||
✔ row278 browser lists held claims and release preserves role rows and totals (847.359938ms)
|
||||
✔ row278 browser claims 403 stays local and role section remains byte-equal (894.870976ms)
|
||||
✔ row278 browser renders only four escaped claim fields and never instance or other extras (843.980149ms)
|
||||
✔ row278 browser sign-out removes claims and prevents reuse of cached answers (893.668522ms)
|
||||
✔ row278 tester browser keeps role rows without requesting the owner claims section (787.543169ms)
|
||||
✔ row278 browser discards a late claims answer after sign-out (921.720447ms)
|
||||
✔ row278 HTTP read returns held claims without send and refuses arguments before the bus (53.230904ms)
|
||||
✔ row278 HTTP read preserves bus refusal and rejects a malformed result (16.041697ms)
|
||||
✔ row278 tester socket refuses thread claims explicitly with zero bus calls (7.920469ms)
|
||||
✔ row278 Console adapter calls argument-free thread.claims through the normal transport (234.138591ms)
|
||||
✔ 193d HTTP shares use the caller, plain/shared lists, exact args and write fences (101.289213ms)
|
||||
✔ 193d config supplies only the signed-in user live collaborator scopes and updates on downgrade (42.033352ms)
|
||||
✔ 193d viewer UI has no composer, resume, share, session mutations or create controls (924.760539ms)
|
||||
✔ 193d mixed grants keep viewer project read-only and collaborator own thread writable; downgrade hides controls (953.979736ms)
|
||||
✔ 193d owner has share controls on own threads and shared threads remain read-only (790.551799ms)
|
||||
✔ 193d bypassed UI checks still reach a refusing bus for every viewer write (788.861611ms)
|
||||
✔ 193d collaborator shares stay read-only and never expose reshare or wake controls (581.454324ms)
|
||||
✔ REQ-LIMIT-4 Settings shows all token kinds and unknown turns beside every total, as a read-only separate section (995.953487ms)
|
||||
✔ REQ-WEB-1 usage read keeps unknown counts and each token kind; no query or write is accepted (45.120159ms)
|
||||
✔ REQ-WEB-1 malformed usage is refused instead of shown as zero (8.503528ms)
|
||||
✔ R6-N1 with the userRoute gate open, a user session reaches no owner option over HTTP (253.639899ms)
|
||||
✔ Queue, Business and Settings in their five states, with no move button (3486.52394ms)
|
||||
✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1584.02624ms)
|
||||
✔ the server log names no config path when the system config refuses (369.222452ms)
|
||||
ℹ tests 455
|
||||
ℹ suites 0
|
||||
ℹ pass 455
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 174122.853398
|
||||
@@ -1,69 +0,0 @@
|
||||
tests/agents-browser.test.mjs
|
||||
tests/agents.test.mjs
|
||||
tests/assistant.test.mjs
|
||||
tests/board-held.test.mjs
|
||||
tests/browser-edge.test.mjs
|
||||
tests/browser.test.mjs
|
||||
tests/bus-browser.test.mjs
|
||||
tests/bus.test.mjs
|
||||
tests/channel-chat.test.mjs
|
||||
tests/chat-browser.test.mjs
|
||||
tests/chat-instances.test.mjs
|
||||
tests/chat-replies-browser.test.mjs
|
||||
tests/chat-sessions-access.test.mjs
|
||||
tests/chat.test.mjs
|
||||
tests/conversation.test.mjs
|
||||
tests/decide-browser.test.mjs
|
||||
tests/decide-sso.test.mjs
|
||||
tests/decision-http.test.mjs
|
||||
tests/discord.test.mjs
|
||||
tests/docs-browser.test.mjs
|
||||
tests/editor-browser.test.mjs
|
||||
tests/editor-provenance.test.mjs
|
||||
tests/editor-wikilink.test.mjs
|
||||
tests/editor.test.mjs
|
||||
tests/granted-user.test.mjs
|
||||
tests/history-return-flow.test.mjs
|
||||
tests/instances-browser.test.mjs
|
||||
tests/instances.test.mjs
|
||||
tests/library-cli.test.mjs
|
||||
tests/library-routes.test.mjs
|
||||
tests/library-status.test.mjs
|
||||
tests/limits-browser.test.mjs
|
||||
tests/limits-route.test.mjs
|
||||
tests/markdown-preview.test.mjs
|
||||
tests/messages.test.mjs
|
||||
tests/pinned-copy.test.mjs
|
||||
tests/preview.test.mjs
|
||||
tests/processing-browser.test.mjs
|
||||
tests/processing-ui.test.mjs
|
||||
tests/processing.test.mjs
|
||||
tests/project-file.test.mjs
|
||||
tests/project-name-repo.test.mjs
|
||||
tests/proof-cli.test.mjs
|
||||
tests/proof.test.mjs
|
||||
tests/reads.test.mjs
|
||||
tests/relaunch.test.mjs
|
||||
tests/return-flow.test.mjs
|
||||
tests/routes-browser.test.mjs
|
||||
tests/routes.test.mjs
|
||||
tests/send-browser.test.mjs
|
||||
tests/send.test.mjs
|
||||
tests/serve.test.mjs
|
||||
tests/service.test.mjs
|
||||
tests/settings-form.test.mjs
|
||||
tests/settings-write.test.mjs
|
||||
tests/shell.test.mjs
|
||||
tests/sso-browser.test.mjs
|
||||
tests/sso.test.mjs
|
||||
tests/tester-browser.test.mjs
|
||||
tests/tester-cli.test.mjs
|
||||
tests/tester-listener.test.mjs
|
||||
tests/tester-socket.test.mjs
|
||||
tests/thread-claims-browser.test.mjs
|
||||
tests/thread-claims.test.mjs
|
||||
tests/thread-sharing.test.mjs
|
||||
tests/usage-browser.test.mjs
|
||||
tests/usage.test.mjs
|
||||
tests/user-option-swap.test.mjs
|
||||
tests/views.test.mjs
|
||||
@@ -1,38 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ row 194 T16 Settings Agents: unavailable read-only, launch follows its request, confirms, reason and refusal (13526.912326ms)
|
||||
✔ row 256 T7 T8 the human page offers Delete on a creative instance, the tester page never does (917.27163ms)
|
||||
✔ row 194 T16: each agent action makes one call with only its keys, logs the user and answers the request (26.28546ms)
|
||||
✔ row 194 T16: the boundary refuses before any bus call (13.102463ms)
|
||||
✔ row 194 T16: read-only when send is off or no writer is wired; no route has a --send exception (6.394437ms)
|
||||
✔ row 194 T16: a bus refusal names its reason and nothing changed; an unknown outcome or a bad shape is never retried (4.282632ms)
|
||||
✔ row 194 T16: the request read takes one id, adds the refusal reason and refuses an unexpected shape (5.922485ms)
|
||||
✔ row 194 T16: delete joins add and change on /api/instances with only revision, instance and op (2.724511ms)
|
||||
✔ row 194 T16 D4.1: the tester listener launches, terminates and reads requests; regenerate, veto and delete are refused with no call (4.723645ms)
|
||||
✔ row 194 N5: agents.js is served as JavaScript and index.html loads it once (1.551741ms)
|
||||
✔ row 239 T6: a delete closed -revoked says the tokens may already be revoked, and outcome-unknown-revoked is an open outcome (2.702385ms)
|
||||
✔ the Board: held roles with no machine sessions, a claim with no address, the toggle kept across a reload, and Message addressed to the role (3264.641316ms)
|
||||
✔ a Seen click while a Board read is in flight waits for that read, then posts (1197.183961ms)
|
||||
✔ a redirect answer on a Board read, a bus read, a conversation read, a board POST, a module read and a send signs the page out: one line, nothing stale, no further reads (5156.528249ms)
|
||||
✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (1309.276425ms)
|
||||
Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
|
||||
✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (1518.992742ms)
|
||||
✔ the README says a refused field table names the file or the key at fault, never a path (104.682461ms)
|
||||
✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (3538.625499ms)
|
||||
✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (83.53196ms)
|
||||
✔ decisions route serves the roles and recent lists from the reader view (37.23684ms)
|
||||
✔ credentials route serves the broker credential status from the reader view (13.661469ms)
|
||||
✔ replies route serves the replies to one message from the reader view (37.146766ms)
|
||||
✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (57.970332ms)
|
||||
✔ bus refusals map to statuses and never carry a path or a stack (25.682155ms)
|
||||
✔ humanCall speaks the human transport protocol without blocking the server (1672.176975ms)
|
||||
✔ busReader takes --business, else the live bus host, else refuses (188.376745ms)
|
||||
✔ humanCall kills a transport that runs past its timeout (527.833381ms)
|
||||
✔ serve refuses a --business value that is not a business id (331.000231ms)
|
||||
ℹ tests 28
|
||||
ℹ suites 0
|
||||
ℹ pass 28
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 17747.118568
|
||||
@@ -1,22 +0,0 @@
|
||||
# grant sage-4286; nice 19; TMPDIR /mnt/storage/scratch/tmp/g49X; MOSAIC_REQUIRE_EDITOR_BUILD 1
|
||||
✔ wikilink round-trip: plain (5.135516ms)
|
||||
✔ wikilink round-trip: labelled (0.532763ms)
|
||||
✔ wikilink round-trip: heading target (0.47601ms)
|
||||
✔ wikilink round-trip: list item (0.674052ms)
|
||||
✔ wikilink round-trip: next to front matter (0.620153ms)
|
||||
✔ wikilink round-trip: heading block and combined label (0.718517ms)
|
||||
✔ wikilink round-trip: spaces, Unicode and adjacent links (0.543729ms)
|
||||
✔ wikilink round-trip: reference-definition collision (1.267657ms)
|
||||
✔ wikilink round-trip: inside an ordinary link (0.565479ms)
|
||||
✔ wikilink round-trip: inert embed (0.373131ms)
|
||||
✔ wikilinks are inline atoms and survive a neighbouring edit in every required context (773.2922ms)
|
||||
✔ code, escaped openers, malformed syntax and HTML-like targets stay outside wikilink atoms (686.084659ms)
|
||||
✔ wikilink DOM paste accepts only bounded single-line inert syntax; malformed attrs serialise as escaped text (675.536422ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2305.540306
|
||||
@@ -1,27 +0,0 @@
|
||||
// Run only under Sage's explicit CLEAR. Reads the pinned baseline Git objects,
|
||||
// not the edited model or rebuilt candidate bundle. Never writes product files.
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import vm from 'node:vm';
|
||||
import { WIKILINK_CASES } from '../../../../packages/webui/tests/helpers/wikilink-cases.mjs';
|
||||
|
||||
const repo = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
|
||||
const base = '487500a16f4ab5902c318509fdec6acc56a543ca';
|
||||
const git = (...args) => execFileSync('git', args, { cwd: repo, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
|
||||
const read = path => git('show', `${base}:${path}`);
|
||||
const source = read('packages/webui/src/public/editor.js');
|
||||
const build = JSON.parse(read('packages/webui/editor/BUILD.json'));
|
||||
const sha256 = createHash('sha256').update(source).digest('hex');
|
||||
if (sha256 !== build.outputs['src/public/editor.js'].sha256) throw Error('baseline bundle differs from its recorded build');
|
||||
const context = { console }; context.window = context; context.globalThis = context;
|
||||
vm.createContext(context);
|
||||
for (const [name, text] of [['markdown-preview.js', read('packages/webui/src/public/markdown-preview.js')], ['editor.js', source]])
|
||||
vm.runInContext(text, context, { filename: name });
|
||||
const results = WIKILINK_CASES.map(({ name, text }) => {
|
||||
const output = context.MosaicEditor.roundTrip(text);
|
||||
return { name, input: text, output, equal: output === text };
|
||||
});
|
||||
console.log(JSON.stringify({ base: git('rev-parse', base).trim(), bundleSha256: sha256,
|
||||
measuredAt: new Date().toISOString(), allEqual: results.every(r => r.equal), results }, null, 2));
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"base": "487500a16f4ab5902c318509fdec6acc56a543ca",
|
||||
"bundleSha256": "9c881b13740fae2408717ad75fa1d85bfcfe3fa8b3af0f1b3f2e706c90e80fee",
|
||||
"measuredAt": "2026-10-24T22:07:22.210Z",
|
||||
"allEqual": true,
|
||||
"results": [
|
||||
{
|
||||
"name": "plain",
|
||||
"input": "[[a]]\n",
|
||||
"output": "[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "labelled",
|
||||
"input": "[[a|b]]\n",
|
||||
"output": "[[a|b]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading target",
|
||||
"input": "[[a#h]]\n",
|
||||
"output": "[[a#h]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "list item",
|
||||
"input": "- [[a]]\n",
|
||||
"output": "- [[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "next to front matter",
|
||||
"input": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"output": "---\nrelated: \"[[metadata]]\"\n---\n\n[[a]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "heading block and combined label",
|
||||
"input": "# See [[a#h|Title]]\n",
|
||||
"output": "# See [[a#h|Title]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "spaces, Unicode and adjacent links",
|
||||
"input": "See [[ Héllo there # A heading | a label ]][[next]]\n",
|
||||
"output": "See [[ Héllo there # A heading | a label ]][[next]]\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "reference-definition collision",
|
||||
"input": "[[a]]\n\n[a]: u\n",
|
||||
"output": "[[a]]\n\n[a]: u\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inside an ordinary link",
|
||||
"input": "[x [[a]]](u)\n",
|
||||
"output": "[x [[a]]](u)\n",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"name": "inert embed",
|
||||
"input": "![[cover.png]]\n",
|
||||
"output": "![[cover.png]]\n",
|
||||
"equal": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
# Row 255 design: a bundled Pocket ID for users with no OIDC provider (Q203, Gitea #1760, Vikunja 458)
|
||||
|
||||
Launchpad, draft 1, 2026-10-25, on `launchpad/row255` off refactor 78b69e1e6. Brief
|
||||
`docs/plans/2026-10-21_bundled-pocket-id.md` (blob 26f34400). Reviewer Webby. Sage checks it against Q203, O6,
|
||||
REQ-WEB-2 and REQ-INST-1. REQ-INST-2 (PRD 1.10) is post-v1 (mos-1204), and so is everything here.
|
||||
|
||||
This is a design only. Nothing here installs, downloads or starts Pocket ID. It changes nothing on .53, .54 or
|
||||
dragon-lin, which keeps Authentik.
|
||||
|
||||
## Sources
|
||||
|
||||
- Q203 and O6 as the brief quotes them. PRD `docs/prd/mosaic-stack.md` REQ-WEB-2 (:902), REQ-INST-1 (:1509),
|
||||
REQ-INST-2 (:1513) and REQ-INST-3 (:1528). Lead decision 44 items 5 and 6
|
||||
(`docs/plans/2026-09-26_lead-decisions.md:655-663`).
|
||||
- The Q175 design `agents/sage/work/q175-sso/DESIGN.md` sections 4 and 10, and the code row 192 landed:
|
||||
`packages/webui/src/sso-config.mjs` (the `console.sso` shape), `packages/webui/src/sso.mjs` (the slot read,
|
||||
the discovery checks at :105-118, the client at :147-148, the callback at :133, the post-logout URI at :332).
|
||||
- Researcher's note `agents/researcher/work/2026-10-04_vikunja-pocketid.md` part 2 (v2.17.0).
|
||||
- A fresh read of upstream on 2026-10-25, from release metadata and source text only: no binary was fetched or
|
||||
run. The latest stable release is **v2.19.1** (2026-10-22). Source paths below are under
|
||||
`backend/internal/` at tag v2.19.1 in `github.com/pocket-id/pocket-id`, marked "P". Releases v2.18.0,
|
||||
v2.19.0 and v2.19.1 are not marked breaking.
|
||||
|
||||
## What the Console already needs from any provider
|
||||
|
||||
This design keeps the Console's sign-in and start checks exactly as row 192 built them. Pocket ID becomes one
|
||||
`console.sso.providers` entry, the same shape any compliant OP uses (Q175 section 4, "Several providers"). The
|
||||
Console gets no new sign-in path, no password and no proxy-header identity (O6, REQ-WEB-2, REQ-INST-2). The
|
||||
facts that drive the rest of the design:
|
||||
|
||||
- `publicOrigin` and every `issuer` must be https (`sso-config.mjs` `httpsURL`). A plain-http Pocket ID can't
|
||||
be a provider at all.
|
||||
- Each provider needs 1 to 64 `subjects`. A `console.sso` with no subject refuses to load. So the first
|
||||
person's subject has to exist before the Console starts with `--sso` (section 5).
|
||||
- The client authenticates with `client_secret_basic` (`sso.mjs:148`), so the client is confidential.
|
||||
- The slot is `<configDir>/secrets/mosaic-stack/<slot>`: a regular file, owned by the Console's uid, mode
|
||||
with no group or other bits, and outside the repo and every stack copy (`readSlot`).
|
||||
- `config.json` is user-authored. bootstrap.sh creates it and nothing overwrites it (canon invariant 2, Q175
|
||||
section 4). This matters for sections 1 and 5.
|
||||
|
||||
## 1. The choice
|
||||
|
||||
The installer is REQ-INST-3's install command (Vikunja #432; today `stack-upgrade.sh` and the per-case
|
||||
install scripts). It takes one sign-in option per instance:
|
||||
|
||||
- `--oidc existing`. The user points the Console at one or more OIDC providers they already have. Nothing
|
||||
is installed. The user writes `console.sso` themselves, as Q175 step 4 does today. The installer writes
|
||||
nothing into `console.sso`; it prints the entry shape and the two URIs to register
|
||||
(`<publicOrigin>/auth/callback`, `<publicOrigin>/auth/signed-out`).
|
||||
- `--oidc bundled`. The stack installs Pocket ID as an install component (section 2), and
|
||||
`console.sso.providers` holds exactly one entry, `id: "pocket-id"`, whose `issuer` is the component's
|
||||
origin.
|
||||
- No option keeps today's behaviour: no `console.sso`, and the Console runs without `--sso`.
|
||||
|
||||
How the bundled choice is recorded. REQ-INST-1 lets a component be switched on "in the organization file
|
||||
or system config". It has to be the system config. The organization file can be written by agents through
|
||||
`organizationWriter`, which is the reason Q175 B1 put `console.sso` in config.json, and the same reason
|
||||
holds for a component that issues the Console's identities. So config.json gets one new optional key:
|
||||
|
||||
```json
|
||||
"components": {
|
||||
"pocket-id": {
|
||||
"release": "v2.19.1",
|
||||
"origin": "https://id.example.internal",
|
||||
"port": 1411
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The loader (`scripts/mosaic-config.mjs`) checks the shape: `release` is a `vX.Y.Z` tag, and the component script refuses one that
|
||||
differs from the pin file (section 2), `origin` is an https origin, `port` is 1024 to 65535. It also cross-checks: when
|
||||
`components["pocket-id"]` is present, `console.sso` must have exactly one provider, `id` `pocket-id`,
|
||||
`issuer` equal to `origin`. A config with `console.sso` providers and no `components` is the existing
|
||||
choice and loads as today.
|
||||
|
||||
**M1, approved by Mos with three conditions (mos-1666 item 3).** `components` is a new top-level config key.
|
||||
The loader refuses unknown keys today, so this is a config schema change. The conditions:
|
||||
|
||||
1. **Rollback trap.** A copy older than P1 refuses a config that has the key, the same trap Q175 section 4
|
||||
names for `console.sso`. P1 documents the order. On a rollback past P1, first take `components` out of
|
||||
config.json (restore the backup made before the key went in), then roll back the pointer. The STATE check
|
||||
after the rollback reads config.json and confirms the key is absent.
|
||||
2. **Strict inside the key.** The loader refuses any name under `components` other than `pocket-id`, and any
|
||||
field under `pocket-id` other than `release`, `origin` and `port`. Each refusal names the key path and
|
||||
quotes no value, as `checkConsole` does.
|
||||
3. **test-config.sh cases:**
|
||||
- a valid `components` loads;
|
||||
- a malformed one fails, naming the bad key path;
|
||||
- a config without `components` loads;
|
||||
- the cross-check refuses a `console.sso` whose provider doesn't match `origin`.
|
||||
|
||||
What each choice writes into `console.sso` is in section 5. For the bundled choice, Pocket ID is the only
|
||||
providers entry. The design keeps it that way because REQ-INST-2 says "the Console's one providers entry".
|
||||
A user who later adds an existing provider moves to `--oidc existing` and removes the component (section 2).
|
||||
|
||||
## 2. The component, against REQ-INST-1
|
||||
|
||||
**Pinned.** A Pocket ID release is a set of raw binaries plus `checksums.txt` (sha256). From v2.16.0 there is
|
||||
an SPDX SBOM per binary, and the release workflow attests `checksums.txt` through Sigstore (`actions/attest`
|
||||
in `.github/workflows/release.yml`). The repo holds one pin file,
|
||||
`scripts/pocket-id-pins.sh`, sourced the way `scripts/case1-pins.sh` is: the tag, and for each supported platform (linux amd64 and arm64 to
|
||||
start) the asset name and its sha256. The build row copies the sha256 from `checksums.txt` at the tag and
|
||||
records the `gh attestation verify` output for each asset as its evidence. The pin is checked by hand at
|
||||
build time, not trusted at install time. No Pocket ID source and no binary goes in the repo. The binary is
|
||||
not in any image either, since the container install comes after v1 (REQ-INST-3).
|
||||
|
||||
Recommended pin: v2.19.1, the current release. The build row checks it again, because Pocket ID ships a
|
||||
minor every one to four weeks. Upgrading is a pin file change in a reviewed commit.
|
||||
|
||||
**Fetched and checked.** `scripts/component-pocket-id.sh fetch` downloads the pinned asset for the host's
|
||||
platform over https into a new 0700 staging directory, computes its sha256, and compares it with the pin.
|
||||
On a mismatch it deletes the file and refuses with `pocket-id-digest-mismatch`, naming the expected value
|
||||
and the computed one. On a match it installs the binary read-only (0555) at
|
||||
`<dataRoot>/components/pocket-id/bin/pocket-id-<tag>`. The fetch is the only network step, and the user
|
||||
runs it at install. Tests never run it against the network (section 9).
|
||||
|
||||
**Runs.** A systemd user unit, `mosaic-pocket-id.service` (`mosaic-pocket-id-NAME.service` for a named
|
||||
instance, as row 190 names the bus and webui units), as the instance's user:
|
||||
|
||||
- `ExecStart=<dataRoot>/components/pocket-id/bin/pocket-id-<tag>`.
|
||||
- `WorkingDirectory=<dataRoot>/components/pocket-id/run`, a directory the unit owns, so Pocket ID's habit of
|
||||
reading `.env` from the working directory reads nothing we didn't write. The build row checks there is no
|
||||
`.env` there at start.
|
||||
- Environment, all from the rendered unit:
|
||||
- `APP_URL=<origin>` and `HOST=127.0.0.1` (P `common/env_config.go`: HOST defaults to `0.0.0.0`).
|
||||
- `PORT=<port>`.
|
||||
- `DB_CONNECTION_STRING` and `UPLOAD_PATH` as absolute paths under `<dataRoot>/components/pocket-id/data/`
|
||||
(P defaults are `data/pocket-id.db` and `data/uploads`, relative to the working directory).
|
||||
- `ALLOW_USER_SIGNUPS=disabled` and `ALLOW_INSECURE_CALLBACK_URLS=false`.
|
||||
- `EMAIL_ONE_TIME_ACCESS_AS_UNAUTHENTICATED_ENABLED=false` and `..._AS_ADMIN_ENABLED=false`.
|
||||
- The `OUTBOUND_ALLOWED_HOSTS_*` allowlists set empty (added in 2.19.0).
|
||||
- No `TRUST_PROXY` unless section 6's proxy step sets it to the proxy's address.
|
||||
- `ENCRYPTION_KEY` (mandatory since v2.0, at least 16 bytes) never goes in the unit text. It lives in slot
|
||||
`<configDir>/secrets/mosaic-stack/pocket-id-encryption-key`, 0600. The component script generates it from
|
||||
`/dev/urandom` straight into the file and never prints it. The unit passes it with
|
||||
`LoadCredential=` and `ENCRYPTION_KEY_FILE=%d/...`. The build row confirms `ENCRYPTION_KEY_FILE` at the pinned
|
||||
tag; if it isn't there, it refuses rather than putting the key in `Environment=`.
|
||||
- The unit never carries `STATIC_API_KEY`. That key exists only during the enroll run (section 4).
|
||||
|
||||
The data directory holds the SQLite database, Pocket ID's signing key (stored encrypted with
|
||||
`ENCRYPTION_KEY`), and the passkey registrations. It is 0700. Agent sandboxes bind only an allowlist
|
||||
(`packages/seat/src/sandbox.mjs`), and `<dataRoot>/components/` is not on it. The build row adds a sandbox
|
||||
test that pins that.
|
||||
|
||||
**Health-checked.** `GET http://127.0.0.1:<port>/healthz` returns 204 (P `controller/healthz_controller.go`).
|
||||
`component-pocket-id.sh status` reports the unit state, the binary tag against the pin, the binary's sha256
|
||||
against the pin, and the health result. The Console's own `/healthz` already shows `sso: { "pocket-id": ready
|
||||
| unreachable | refused }` from its discovery retries, so an operator sees the provider from either side.
|
||||
|
||||
**Removable.** `component-pocket-id.sh remove` refuses while `console.sso` still names `pocket-id`, so the
|
||||
Console can't be left pointing at a provider that's gone. Once the user has taken the entry out (or moved to
|
||||
`--oidc existing`), the script stops and removes the unit, then moves the data directory to
|
||||
`<dataRoot>/components/pocket-id.removed-<utc>` with a receipt line in `<dataRoot>/state/components.log`
|
||||
(append-only). It never deletes the passkey database outright. Deleting the moved directory and the
|
||||
encryption key slot is a separate `purge` verb that names both paths and needs `--yes`. Removing the
|
||||
`components` key from config.json is the user's edit.
|
||||
|
||||
## 3. The Q175 start checks against the bundled instance
|
||||
|
||||
The Console checks are unchanged. Here is each one against Pocket ID, and the setting it needs:
|
||||
|
||||
| Check (row 192) | Pocket ID v2.19.1 | Default that fails | Fix |
|
||||
|---|---|---|---|
|
||||
| `issuer` is https (loader) | issuer = `APP_URL` exactly (P `controller/well_known_controller.go`) | `APP_URL` defaults to `http://localhost:1411` | `APP_URL=<https origin>`, section 6 |
|
||||
| discovery `issuer` equals config `issuer` | equal when `APP_URL` has no trailing slash; Pocket ID refuses a path | none | config `issuer` = `origin`, no trailing slash; the loader cross-check compares them |
|
||||
| `id_token_signing_alg_values_supported` overlaps `algs` | advertises only the current key's alg. RS256 (RSA-2048) by default (P `service/jwt_service.go`) | none | `algs: ["RS256"]` |
|
||||
| `code_challenge_methods_supported` has `S256` | advertises `plain` and `S256` | none | none. The Console always sends S256 (`sso.mjs:221`) |
|
||||
| JWKS has a usable key for `algs` | one key at `/.well-known/jwks.json` | none | none. The build row's fake OP pins `use`/`alg`/`kid` as Pocket ID emits them |
|
||||
| `end_session_endpoint` is https | `<APP_URL>/api/oidc/end-session` | http, if `APP_URL` is http | same fix as row 1 |
|
||||
| `redirect_uri` is registered | exact match first, then wildcard patterns; loopback callbacks match any port (P `utils/callback_url_util.go`) | `ALLOW_INSECURE_CALLBACK_URLS` defaults to true | register exactly `<publicOrigin>/auth/callback`, with no `*`; set `ALLOW_INSECURE_CALLBACK_URLS=false` |
|
||||
| post-logout URI | per-client `logoutCallbackURLs`, same matching | none | register exactly `<publicOrigin>/auth/signed-out` |
|
||||
| ID token alg in `algs`, `iss` match | as above | none | none |
|
||||
|
||||
Two points the Console doesn't check, set on the client anyway:
|
||||
|
||||
- `pkceEnabled: true`. Then Pocket ID refuses an authorize request that has no `code_challenge`. Pocket ID has
|
||||
no per-client S256-only setting (P `oidc/provider.go` turns on `plain` for the server). That doesn't relax
|
||||
anything: the Console sends S256 every time, and `plain` stays available only to other clients.
|
||||
- `isPublic: false`, which matches `client_secret_basic`.
|
||||
|
||||
Key rotation. `pocket-id key-rotate --alg ...` replaces the one signing key (P `cmds/key_rotate.go`). After a
|
||||
rotation to another alg, the Console's discovery check refuses on the next restart (no overlap with
|
||||
`algs`), and that is the intended fail-closed result. A rotation is a user step that updates `algs` in the
|
||||
same edit. The component script never rotates.
|
||||
|
||||
## 4. The client, and where its secret goes
|
||||
|
||||
The person running the install creates the client through `component-pocket-id.sh enroll`. No agent runs
|
||||
this verb. It refuses when any agent marker is in its environment: the `MARKERS` list in
|
||||
`packages/bus/src/human.mjs` (`MOSAIC_RUN_ID`, `MOSAIC_BUS_CAP`, `CLAUDECODE` and the rest) that the human
|
||||
boundary uses. A test pins the refusal.
|
||||
|
||||
Enroll needs admin rights before any person has a passkey. Pocket ID offers two ways to get them, and one of
|
||||
them is a hazard:
|
||||
|
||||
- `/setup` and its backing `POST /api/signup/setup` are unauthenticated: whoever calls first becomes admin
|
||||
(P `usersignup/service.go`). Sandboxed agents share the host's network namespace (`sandbox.mjs` unshares
|
||||
user, pid and ipc, not net), so any agent could reach a loopback Pocket ID and take that first admin.
|
||||
- `STATIC_API_KEY` is a fixed admin key with no expiry (P `apikey/service.go`). It doesn't count as
|
||||
completing setup, so `/setup` stays open while it's set.
|
||||
|
||||
So enroll never lets the real unit serve before an admin person exists. It runs the pinned binary once in a
|
||||
**private network namespace** (`unshare --user --net`, or `bwrap --unshare-net` with the binary and data
|
||||
directory bound), where only enroll's own loopback can reach it:
|
||||
|
||||
1. Generate a one-run static key into a 0600 temp file in a new 0700 directory, and start Pocket ID inside
|
||||
the namespace with `STATIC_API_KEY_FILE` pointing at it, plus the unit's environment.
|
||||
2. Wait for `/healthz` 204.
|
||||
3. Create the admin user, `POST /api/users` with `isAdmin: true` and the username and email given with
|
||||
`--admin-user` and `--admin-email`. Keep the returned `id`. That is the OIDC `sub` (P
|
||||
`oidc/claims_service.go` uses `user.ID`, a UUIDv4 set at creation, so it's stable).
|
||||
4. Create the Console client: client id `mosaic-console-<instance>`, callback and logout URLs exactly as in
|
||||
section 3, `pkceEnabled: true`, `isPublic: false`. Supply the secret instead of letting Pocket ID
|
||||
generate it. Enroll generates 48 random bytes, base64url, and writes them straight to slot
|
||||
`<configDir>/secrets/mosaic-stack/console-sso-pocket-id` (0600, `O_CREAT|O_EXCL`, not a symlink). It sends
|
||||
the same bytes in the create body over the namespace's loopback (`dto/oidc_dto.go` accepts a supplied
|
||||
secret of 16 or more characters). The value is never printed, logged or put in an argv, and a test pins
|
||||
that it appears in no output.
|
||||
5. Mint a one-time access token for the admin, `POST /api/users/<id>/one-time-access-token`.
|
||||
6. Stop the namespaced process, then shred and remove the static key file. The real unit has never had a
|
||||
static key, so no admin key survives enroll.
|
||||
7. Start the real unit and wait for `/healthz` 204.
|
||||
8. Print the sign-in link `<origin>/lc/<token>` to the user's terminal (section 5), and the `console.sso`
|
||||
entry (section 5).
|
||||
|
||||
The build row confirms each route and body against the pinned tag's source before it writes the client (the
|
||||
upstream read for this design didn't trace the create-client route). If any of steps 1 to 7 fails, enroll
|
||||
stops the process, removes the static key, leaves no slot file it created, and refuses with the step name.
|
||||
|
||||
The secret never enters the repo or an image. It sits in two places only: the slot file and Pocket ID's
|
||||
database (stored as a hash). The Console's `readSlot` reads it as it does any provider's.
|
||||
|
||||
## 5. The first person, and their subject in `console.sso`
|
||||
|
||||
Pocket ID is passkey-only for people (REQ-INST-2). The installing user enrolls like this:
|
||||
|
||||
1. Enroll prints `<origin>/lc/<token>`. The token is valid for one hour and is a credential, so it goes only
|
||||
to the terminal of the person who ran enroll. It goes in no log and no file.
|
||||
2. The user opens it in a browser that can reach `origin` (section 6). Pocket ID signs them in and asks them
|
||||
to add a passkey. Without one they can't sign in again. If the hour passes, `pocket-id
|
||||
one-time-access-token <username>` (P `cmds/one_time_access_token.go`), run by the user against the data
|
||||
directory, prints a new link. `component-pocket-id.sh relink` wraps that call.
|
||||
3. Enroll already has the subject, the `id` from step 3 of section 4. It doesn't wait for a sign-in or read a
|
||||
`subject-unknown` log line.
|
||||
|
||||
How the subject gets into `console.sso`. config.json is user-authored and never auto-written. Two ways
|
||||
to respect that; I recommend the first:
|
||||
|
||||
- **R1 (recommended).** Enroll prints the full entry and writes nothing:
|
||||
|
||||
```json
|
||||
"console": { "sso": { "publicOrigin": "<publicOrigin>", "providers": [ {
|
||||
"id": "pocket-id", "issuer": "<origin>", "clientId": "mosaic-console-<instance>",
|
||||
"clientSecret": { "slot": "console-sso-pocket-id" }, "algs": ["RS256"],
|
||||
"subjects": [ { "sub": "<id>", "name": "<admin-user>" } ] } ] } },
|
||||
"components": { "pocket-id": { "release": "<tag>", "origin": "<origin>", "port": <port> } }
|
||||
```
|
||||
|
||||
The user pastes it into config.json, as with Q175 step 4. Rerunning `scripts/bootstrap.sh` (or
|
||||
`--instance NAME`) then validates it through the loader, including the section 1 cross-check, and writes
|
||||
nothing. Nothing changes in invariant 2.
|
||||
- **R2 (rejected, Sage sage-4401: R1 chosen).** `enroll --write-config` would write those two keys itself, with a backup of config.json first, and
|
||||
refuse if `console` or `components` were already present. That would be the first tool to modify an
|
||||
existing config.json, against canon invariant 2's "never overwritten" practice. Not built.
|
||||
|
||||
Whose subject. Enroll creates one person, the one running it, and only that subject goes in the entry. On
|
||||
Jason's instances, only his subject goes into `console.sso` (mos-1197). Further people are added with
|
||||
Pocket ID's admin UI (a user plus a one-time link), and their subjects go into `console.sso` by the user's
|
||||
edit, never by an agent. Pocket ID users who aren't in `subjects` can sign in to Pocket ID, but the Console
|
||||
refuses them `subject-unknown`, so REQ-WEB-2's "must map to an authorized human" holds.
|
||||
|
||||
## 6. Reach: origin, TLS and proxy
|
||||
|
||||
WebAuthn takes its RP id from `APP_URL`'s host name, and its allowed origin is `APP_URL`
|
||||
(P `webauthn/module.go`). Browsers allow passkeys only on a secure origin. The Console also needs https for
|
||||
both `publicOrigin` and `issuer`. Pocket ID serves plain http, and I found no TLS listener setting in its
|
||||
environment config. So:
|
||||
|
||||
- Pocket ID always binds `127.0.0.1:<port>`. That is the default, and the component never binds anything
|
||||
else (`HOST=127.0.0.1`; the status verb refuses a unit whose `HOST` differs).
|
||||
- `origin` is an https origin served by a TLS front that the user already has for the Console. The Console
|
||||
needs one anyway, since `publicOrigin` is https. Pocket ID goes behind the same front under **its own host
|
||||
name**, for example `id.<console host>`. Pocket ID doesn't support a path prefix (`APP_URL` must have no
|
||||
path). A separate host name also keeps Pocket ID's cookies apart from the Console's
|
||||
`__Host-mosaic_*` cookies; the two share cookies if they sit on one host name on different ports.
|
||||
- The front reaches Pocket ID on loopback, so the front has to run on the same host. If it doesn't, Pocket
|
||||
ID would need a non-loopback bind, and that is a `network.expose` hard wait (REQ-WAIT-1), not a component
|
||||
option.
|
||||
- `TRUST_PROXY` is set to the front's address only, never `true`.
|
||||
- The Console fetches discovery and JWKS from `issuer` over https from the server side, so the Console's
|
||||
node has to trust the front's certificate. A public CA does that. A private CA needs
|
||||
`NODE_EXTRA_CA_CERTS` in the Console unit, which the build row adds as a render flag.
|
||||
|
||||
These steps are the user's, and on Jason's hosts they are Jason's, because each one changes who can reach
|
||||
the Console or Pocket ID, or who the host trusts:
|
||||
- J1: the DNS name for `origin`;
|
||||
- J2: the certificate for it, or a private CA and its trust in the browser and in `NODE_EXTRA_CA_CERTS`;
|
||||
- J3: the TLS front's route from `origin` to `127.0.0.1:<port>` (a Traefik change on Jason's hosts);
|
||||
- J4: any listener off loopback.
|
||||
|
||||
The component checks and refuses; it never does them itself. With none of them done, Pocket ID runs on
|
||||
loopback with an https `APP_URL` that nothing serves yet. Enroll's step 2 health probe goes straight to
|
||||
`127.0.0.1`, so enroll still works. The person can't add a passkey until J1 to J3 are done.
|
||||
|
||||
## 7. Agents
|
||||
|
||||
Unchanged. Agents keep their per-role service tokens (lead decision 44 item 6, REQ-INST-2). Pocket ID issues
|
||||
nothing an agent uses. The Console client is the only client enroll creates. No API, no client-credentials
|
||||
grant and no admin API key exist after enroll. Residuals, stated plainly:
|
||||
|
||||
- Agents can reach `127.0.0.1:<port>`, because the sandbox shares the host network. What they can reach there
|
||||
is the public sign-in pages, discovery and JWKS. Signup is disabled, email codes are off, `/setup` is
|
||||
closed because an admin exists, and there is no static key. A test of the rendered unit pins all four
|
||||
settings.
|
||||
- The data directory and the two slots are outside every sandbox bind (section 2).
|
||||
- A seat that ran as the same OS user outside a sandbox could read the data directory. The Console's
|
||||
existing slot has the same exposure; this design adds no new class of it.
|
||||
|
||||
## 8. Instances
|
||||
|
||||
One Pocket ID per named instance, never shared:
|
||||
|
||||
- Each instance has one system config (row 190), and `components` and `console.sso` live in it. A shared
|
||||
Pocket ID would make one instance's config depend on a unit, a data directory and an encryption key that
|
||||
belong to another instance's config and data root.
|
||||
- Unit names, ports, data directory, slots and removal are all per instance (`mosaic-pocket-id-NAME`,
|
||||
`<dataRoot of NAME>/components/pocket-id`), so removing one instance's component can't break another's
|
||||
sign-in.
|
||||
- Each instance needs its own `origin` (section 6), so passkeys are per instance too. A person enrolls once
|
||||
per instance.
|
||||
- An instance that wants to use another instance's Pocket ID can still do it with `--oidc existing`. Then it
|
||||
is just an OIDC provider, with its own client registered by that instance's owner. Nothing special-cases it.
|
||||
|
||||
Two instances on one host each need their own `port`. The loader can't see other instances' configs, so
|
||||
`component-pocket-id.sh` refuses at fetch and enroll when the port is already bound on loopback.
|
||||
|
||||
## 9. Tests, stand-ins only
|
||||
|
||||
No test downloads or starts a real Pocket ID, and no test touches auth.diversecanvas.com,
|
||||
mosaic.woltje.com or 127.0.0.1:7332. The stand-ins:
|
||||
|
||||
- **Fake Pocket ID OP**, a node server like row 192's fake OP, shaped from v2.19.1:
|
||||
- the discovery fields `well_known_controller.go` emits (issuer = origin, `plain` and `S256`,
|
||||
`end_session_endpoint` at `/api/oidc/end-session`, the three auth methods);
|
||||
- one RS256 JWK at `/.well-known/jwks.json`;
|
||||
- a token endpoint that takes only `client_secret_basic`;
|
||||
- `/healthz` 204.
|
||||
|
||||
The Console starts against it under `--sso` with the section 5 entry, with no check changed. Negative
|
||||
cases:
|
||||
- an http issuer refuses at load;
|
||||
- an ES256-only JWKS against `algs: ["RS256"]` refuses at discovery;
|
||||
- an issuer with a trailing slash refuses on the cross-check.
|
||||
- **Fake admin API** on the same stand-in: `POST /api/users`, the client create, the one-time token, and a
|
||||
static-key check. Enroll runs against it with the binary replaced by a stub script that serves the stand-in.
|
||||
The tests pin:
|
||||
- the namespace argv;
|
||||
- the slot file's mode and `O_EXCL`;
|
||||
- that the secret appears in no stdout, stderr or argv;
|
||||
- the static key file gone after success and after a failure at each step;
|
||||
- the refusal under an agent marker in the environment.
|
||||
- **Fetch**: a local file served by a test https server (self-signed, trusted only by the test) with a
|
||||
matching pin, a mismatched pin and a truncated file.
|
||||
- **Unit render**: the environment table in section 2. `HOST=127.0.0.1`, no `STATIC_API_KEY`, no
|
||||
`ENCRYPTION_KEY` value in the text, and `ALLOW_USER_SIGNUPS=disabled`.
|
||||
- **Loader**: test-config.sh cases for the `components` key and the cross-check, and the copy-rollback note.
|
||||
- **Sandbox**: `<dataRoot>/components/` is in no bind list.
|
||||
|
||||
## 10. Build rows, in landing order
|
||||
|
||||
All are post-v1 (REQ-INST-2). Each row has Webby or Sage's named reviewer and its own gate. None of them
|
||||
runs on .53, .54 or dragon-lin, and none installs Pocket ID on any host.
|
||||
|
||||
1. **P1, loader key.** `components["pocket-id"]` in `mosaic-config.mjs`, strict inside the key, and the
|
||||
cross-check against `console.sso` (section 1, M1 conditions from mos-1666 item 3). P1 also writes the
|
||||
rollback order into `docs/TOOLS.md` beside Q175's: remove `components` (restore the backup) before the
|
||||
pointer goes back, and the post-rollback STATE check confirms the key is absent from config.json. Gate:
|
||||
test-config.sh green with the four M1 cases.
|
||||
2. **P2, pin and fetch.** `scripts/pocket-id-pins.sh` with the build-time sha256 and the
|
||||
attestation evidence, and `component-pocket-id.sh fetch|verify`. Gate: the fetch tests against the local
|
||||
stand-in; the evidence file shows `gh attestation verify` output for each pinned asset.
|
||||
3. **P3, unit.** The unit template, `render|install|status|remove|purge`, and the encryption key slot. Gate:
|
||||
the render and remove tests, and the sandbox bind test.
|
||||
4. **P4, enroll.** The namespaced bootstrap, the client, the subject, `relink`, and printing the entry (R1),
|
||||
(R2 rejected). Gate: the enroll tests in section 9, and a secret-leak grep over every test log.
|
||||
5. **P5, Console against the fake Pocket ID.** The section 9 fake-OP start tests, and the
|
||||
`NODE_EXTRA_CA_CERTS` render flag for the Console unit. Gate: the webui suite, with no change to
|
||||
`sso.mjs` checks (a diff of `sso.mjs` and `sso-config.mjs` against the base shows none).
|
||||
6. **P6, installer option.** `--oidc existing|bundled` on REQ-INST-3's install command, calling P2 to P4 in
|
||||
order, and the docs: `docs/TOOLS.md`, the host run sheet's J1 to J4 steps. Gate: the installer's own
|
||||
suite against the stubs; the docs list J1 to J4 as the user's steps.
|
||||
|
||||
## Open items for review
|
||||
|
||||
- M1 approved by Mos with three conditions (mos-1666 item 3), written into section 1 and P1.
|
||||
- M2 dropped: Sage chose R1 and rejected R2 (sage-4401).
|
||||
- **Q1 (Webby):** the private network namespace for enroll (section 4). The other option is to start the
|
||||
real unit and race `/setup`, which I think is unsafe while agents share the host network.
|
||||
- **Q2 (Webby):** one-providers-entry for the bundled choice (section 1). REQ-INST-2's wording reads that
|
||||
way. Mixing a bundled Pocket ID with existing providers would need Sage's ruling.
|
||||
- Not covered: Pocket ID for Vikunja or Gitea people sign-in (the Researcher note's part 3), and
|
||||
client-credentials between Mosaic services. Neither is in Q203.
|
||||
@@ -1,482 +0,0 @@
|
||||
# Row 193 design: many humans per business, human roles, private and shared threads
|
||||
|
||||
Morgana (Opus 5.5), 2026-10-20. Revision 5: sage-1373 item 1 (mos-1023 item 2), the user sentence names every record the owner sees. Revision 4: duckworth-0011 B3 and N5. Revision 3: duckworth-0008 B1, B2 and N1-N4, sage-1368. Revision 2: sage-1354 (5.7 private from the owner, 193b split) and gizmoduck-0018 (coverage and the R4 predicate in FED r4.1). Gitea #1691, queue row 193, brief `docs/plans/2026-10-20_human-users.md`
|
||||
(blob f7472d1e47b1). Reviewer Duckworth, gate owner Sage. Base: `refactor` at 53bb59462.
|
||||
|
||||
Read for this design: COMMON.md (53bb59462), the brief, Gizmoduck's federation design r4.4 (b67bc6de9 on
|
||||
gizmoduck/federation-design, cited as FED; r3.1 a2840a6be was read first), Duckworth's federation reviews (b402197ff, 03a663cd7,
|
||||
45cbe5896 on duckworth/reviews), Sage's Q175 SSO design (`agents/sage/work/q175-sso/DESIGN.md`), the row 192
|
||||
and row 196 briefs, Darkwing's row 190 packet (uncommitted, sha256 5493c9df3ec0...), and the bus, business,
|
||||
cli and webui code at the lines cited. Messages: morgana-0001 to 0003, sage-1338, gizmoduck-0009,
|
||||
gander-0002 and gander-0005.
|
||||
|
||||
## 1. Summary
|
||||
|
||||
- Three human roles: **owner**, **collaborator**, **viewer**. The owner is the business file's one `human`,
|
||||
as today. Collaborators and viewers are access.json users, the same store federation uses (FED 3.5).
|
||||
Their role is the `level` of a grant, so a role is per project and instance, not per person.
|
||||
- Every human principal is minted by one bus verifier, owned by row 196 (Gander). Row 193 states what it
|
||||
needs from that verifier (section 6) and adds no second mechanism.
|
||||
- Threads stay private to their owner by default. A thread owner may share a thread, read-only, with a
|
||||
named user, with the owner, or with everyone granted on it. Shares live in a new append-only bus table,
|
||||
`thread_shares`. This is a deviation from brief point 4, agreed by Sage (sage-1338), for Duckworth to rule
|
||||
on (section 5.1).
|
||||
- A share never widens a grant. It counts only while the reader's live grant covers the thread's project
|
||||
and instance, and while the thread's owner still has coverage. Revocation, expiry and unsharing take
|
||||
effect on the next request.
|
||||
- Existing businesses keep working unchanged: every existing thread is already owned by the business
|
||||
human, and an instance without access.json has exactly one human, the owner.
|
||||
- The build splits so the part without a schema change can land first. `thread_shares` needs schema 3j and
|
||||
a `--migrate` window with Jason.
|
||||
|
||||
## 2. What exists today (measured at 53bb59462)
|
||||
|
||||
- One `human` per business (`packages/business/src/business.mjs:160`). `bindHuman` refuses any other name
|
||||
(`packages/bus/src/broker.mjs:532-538`).
|
||||
- The owner's CLI proof is path-bound (#225): `verifyHuman` checks uid, start time, nonce
|
||||
(`MOSAIC_BUS_CLI_NONCE`), `argv[1]` equal to the tree's `human-cli.mjs`, then walks parents and refuses
|
||||
agent markers, launch records and agent binaries (`packages/bus/src/human.mjs:64-96`).
|
||||
`authenticateHuman` binds the proof to `businesses[business].human` (`packages/bus/src/runtime.mjs:175-182`).
|
||||
- Threads: `threads(seq,id,at,business,project,instance,owner,name)`, append-only
|
||||
(`packages/bus/schema.sql:247`, triggers at :310-312). `#owner(s)` returns `tester` or `s.human`
|
||||
(broker.mjs:364-366). `#thread` refuses a non-owner with `thread-not-owned` (:357-362).
|
||||
- Thread verbs are gated `if (!s.tester) this.#human(s)`: `project.list` (:2318), `thread.create` (:2325),
|
||||
`thread.list` (:2351, owner filter), `thread.open` (:2365), `thread.send` (:2374, writes `human.input`
|
||||
for the human only), `thread.messages` (:2401).
|
||||
- Board reads are business-wide and human or reader only: `inbox`, `agents`, `tasks`, `trail` (:2143-2167),
|
||||
`decisions` (:2174), `credentials` (:2195), `messages` (:2217, `to_role='human'`), `replies` (:2422).
|
||||
`trail` and `replies` return any message in the business by id (:2679-2700, :2422-2432).
|
||||
- The Console reads threads by polling the same verbs (`packages/webui/src/chat.mjs:22-26`). It has no
|
||||
stream, so a refusal on the next poll ends access.
|
||||
- The launcher restarts a thread with pending messages as the business human
|
||||
(`packages/cli/src/launcher.mjs:533-542`).
|
||||
|
||||
## 3. The human model (brief point 1)
|
||||
|
||||
### 3.1 Who the humans are
|
||||
|
||||
| Human | Where it is declared | How many | Identity |
|
||||
|---|---|---|---|
|
||||
| owner | business file `human` (unchanged) | exactly one per business | the business human's name |
|
||||
| user (collaborator or viewer) | access.json `users[]` with `home: "local"` (or a peer id under federation) | any number | `user:<id>` |
|
||||
| tester | not a human; row 177 test principal | one | `tester` |
|
||||
|
||||
The owner stays outside access.json (FED 9 Q2). A business has no second owner and no admin level. Adding
|
||||
one is out of scope; section 9 lists it as a follow-up for Jason.
|
||||
|
||||
### 3.2 How a sign-in or a call becomes exactly one human
|
||||
|
||||
| Entry | Becomes | Checked by |
|
||||
|---|---|---|
|
||||
| Console SSO session whose `(provider, sub)` is in `console.sso.providers[].subjects` (row 192) | the owner | the Console after OIDC checks, then the bus verifier (row 196) |
|
||||
| Console SSO session whose `(provider, sub)` is a `users[].subjects` entry in access.json with a live grant | that one user | same |
|
||||
| Console SSO session matching neither | nobody: refused | the Console, and the bus refuses any later claim |
|
||||
| CLI call through `human-cli.mjs` that passes the human proof | the owner | the bus (`verifyHuman`) |
|
||||
| Any other process, including an agent | nobody | the bus |
|
||||
|
||||
Why each is exactly one:
|
||||
|
||||
- The R1 loader refuses a `(provider, sub)` pair that appears twice in access.json or also in
|
||||
`console.sso.subjects` (FED 3.5). So one subject maps to at most one human.
|
||||
- A user id can't be `human`, `tester` or any business's human (FED 3.5). So a user can't be named as the
|
||||
owner.
|
||||
- A terminal maps only to the owner. The only identity the bus can verify for a local process is the
|
||||
instance's OS user, and that is the owner's. A user has no CLI path in row 193. This follows Mos's B1 rule
|
||||
(mos-0985): the principal comes from what the bus verifies, never the process's own claim.
|
||||
- The bus never reads a user name from a request body as identity. The verifier returns the principal
|
||||
(section 6).
|
||||
|
||||
## 4. Human roles (brief point 2)
|
||||
|
||||
### 4.1 The three roles
|
||||
|
||||
- **owner**: everything the business human does today. Only the owner restructures the organization
|
||||
(business file writer, project and role changes) and only the owner manages users and grants.
|
||||
- **collaborator**: FED 3.5's level, unchanged. Creates threads in granted projects on granted instances,
|
||||
sends into and opens its own threads, and in row 193 also shares its own threads.
|
||||
- **viewer**: new. Reads threads shared with it, within its grant. It creates, opens and sends nothing, so
|
||||
it never drives an instance. FED 3.5 notes that a collaborator's message drives the instance with the
|
||||
owner's role authority (F10). A viewer has none of that.
|
||||
|
||||
The word "collaborator" stays, so FED's tests and help text need no rename. The brief's example "member" is
|
||||
this level.
|
||||
|
||||
A role is the `level` on a grant, and a grant is per business, project set and instance set. A user may
|
||||
hold a collaborator grant on one project and a viewer grant on another. Every check asks "does a live
|
||||
grant of a level that allows this verb cover this project and instance". A user has no single role.
|
||||
|
||||
### 4.2 R1 widening
|
||||
|
||||
FED R1 refuses any level but `collaborator`, because the 10-27 slice ships only that (FED 9 Q2).
|
||||
Row 193 widens R1's level check to `collaborator` or `viewer`, with its own test that each is accepted and
|
||||
anything else refuses. Nothing else in the access file changes. If R1 has not landed when row 193 builds,
|
||||
this one-line widening goes into the row 193a candidate chained on R1's candidate (Q177).
|
||||
|
||||
### 4.3 Bus verbs per role
|
||||
|
||||
Every verb not in a user's column fails `access-refused` before its own checks, as FED 3.5 requires for
|
||||
collaborators. That covers every owner verb, every board read, `message.*`, `decision.*`, project files,
|
||||
`spec.read`, `assistant.stop`, `launch.*`, `name.set`, `usage.*` and `access.reload`.
|
||||
|
||||
| Verb | owner | collaborator | viewer |
|
||||
|---|---|---|---|
|
||||
| `project.list` | all | projects covered by any live grant | projects covered by any live grant |
|
||||
| `thread.create` | yes | collaborator grant covers project and instance | refused |
|
||||
| `thread.list` | own threads | own threads still covered | own threads still covered (from an earlier collaborator grant) |
|
||||
| `thread.list {shared: true}` (new) | threads shared with the owner | threads shared with me and readable (5.4) | same |
|
||||
| `thread.open` | own | own, collaborator grant still covers | refused |
|
||||
| `thread.send` | own | own, collaborator grant still covers, no `human.input` | refused |
|
||||
| `thread.messages` | own, or shared with the owner | own (any level still covering), or shared and readable | same as collaborator |
|
||||
| `thread.share`, `thread.unshare` (new) | own threads | own threads, collaborator grant still covers | refused |
|
||||
| `thread.shares` (new) | own threads | own threads | refused |
|
||||
| `names` | all | instances covered by any live grant | instances covered by any live grant |
|
||||
| every other verb | as today | refused | refused |
|
||||
|
||||
Notes:
|
||||
|
||||
- `thread.list` keeps its response shape exactly. Shared threads come only from `thread.list {shared: true}`,
|
||||
whose rows add `owner`. The Console and existing tests read the plain list unchanged.
|
||||
- A viewer can still read its own threads when a collaborator grant is lowered to viewer, but can't send
|
||||
or open them. This is the downgrade path.
|
||||
- The tester keeps its row 177 verbs. It can't share or be shared with: `thread.share`, `thread.unshare`
|
||||
and `thread.shares` fail `tester-refused`, and a share target is never `tester`. Agent testers (Q173) test
|
||||
sharing through the bus suites, not the live 7333 listener.
|
||||
- `reader` sessions (Console read caps, broker.mjs:1303) are the owner's board view and stay owner-only.
|
||||
A user never gets a reader session.
|
||||
|
||||
### 4.4 Console per role
|
||||
|
||||
- owner: as today, plus a share control on each own thread and a "Shared with me" list.
|
||||
- collaborator: the chat view only, for granted projects (FED R6's granted-user sign-in), plus share
|
||||
controls on its own threads and "Shared with me". No board.
|
||||
- viewer: "Shared with me" and its own old threads, read-only. No composer, no open, no share control.
|
||||
- The Console hides controls a role can't use, but the bus check is authoritative. A Console bug can't
|
||||
widen a grant (FED 3.6). Each role gets a webui test with the UI check removed (mutant) that the bus still
|
||||
refuses.
|
||||
|
||||
### 4.5 Who manages humans and roles
|
||||
|
||||
Only the owner, through `mosaic access` (FED R5), which checks the human proof and refuses tester and agent
|
||||
callers. Row 193 needs from R5:
|
||||
|
||||
- `mosaic access user add <id> --home local --subject <provider>:<sub>` and `user remove <id>`;
|
||||
- `--level viewer` on `grant`;
|
||||
- the receipt line in `<dataRoot>/state/access-log.jsonl` and the `access.reload` call, as FED R5 has.
|
||||
|
||||
If R5 has no `user` verbs when row 193 builds, row 193c adds them on R5's candidate. The Console gets no
|
||||
user or grant writes in row 193: a write from the Console would need a new owner verb that writes
|
||||
access.json from the bus, and access.json is a config file only the owner's CLI writes. A read-only users
|
||||
page for the owner is a follow-up (section 9).
|
||||
|
||||
The owner keeps every restructuring power (TARGET Case 1). Users can't touch the business file, projects,
|
||||
roles or access.json.
|
||||
|
||||
## 5. Private and shared threads (brief point 3)
|
||||
|
||||
### 5.1 Deviation from brief point 4, agreed by Sage (sage-1338)
|
||||
|
||||
Brief point 4 says access.json is the one store. Users, roles and grants live there. Per-thread shares do
|
||||
not, for three reasons (morgana-0002):
|
||||
|
||||
- F1. Thread ids are bus-generated UUIDs. A hand-typed share with a typo would fail the loader, and the
|
||||
loader refuses the whole file on any failure, which revokes every user.
|
||||
- F2. Only the owner writes access.json. A collaborator could never share its own thread.
|
||||
- F3. Threads are append-only bus rows, and a share is a runtime act by a principal that wants a trail.
|
||||
|
||||
So shares go in an append-only bus table, gated by the grant. Sage agreed (sage-1338). Gizmoduck had no
|
||||
objection (gizmoduck-0009) and recorded it as FED 9 Q2. Duckworth rules on it in this review.
|
||||
|
||||
### 5.2 Schema 3j
|
||||
|
||||
```sql
|
||||
CREATE TABLE thread_shares (
|
||||
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
at TEXT NOT NULL,
|
||||
business TEXT NOT NULL,
|
||||
thread TEXT NOT NULL REFERENCES threads(id),
|
||||
op TEXT NOT NULL CHECK (op IN ('share','unshare')),
|
||||
target TEXT NOT NULL,
|
||||
by TEXT NOT NULL
|
||||
) STRICT;
|
||||
CREATE INDEX thread_shares_thread ON thread_shares (thread, target, seq);
|
||||
-- no_update, no_delete and no_replace triggers, as thread_opens has (schema.sql:319-321).
|
||||
```
|
||||
|
||||
- `target` is an owner string: `user:<id>`, the business human's name, or `*`. A share whose target is a
|
||||
name that is no longer the business's `human` (after a rename) is void: rule 1 in 5.4 compares against
|
||||
the current owner string, so it matches nobody (Duckworth N4).
|
||||
- `by` is the sharer's owner string, which is always the thread's owner.
|
||||
- A share's state is its latest row per `(thread, target)` (Duckworth N12, REVIEW-r3.md:74-76). Shares
|
||||
are not assumed to only grow.
|
||||
- No existing row changes. Existing threads are already owned by the business human (`#owner` at
|
||||
broker.mjs:364-366), so they are the owner's and private. The brief's "all become the current human's"
|
||||
is already true.
|
||||
|
||||
The migration `3i-3j.sql` creates the table, index and triggers. `thread_shares` joins every table list that
|
||||
holds timed append-only tables: `timedTables` in store.mjs (:60-74), the broker's clock list
|
||||
(broker.mjs:223-235), the restore guard's counted tables (row 181) and `COUNTED` in
|
||||
`scripts/stack-release.sh:315`. The schema digest for 3j is pinned as the other versions are.
|
||||
|
||||
### 5.3 Verbs
|
||||
|
||||
- `thread.share {thread, to}`: the caller must own the thread (`thread-not-owned`). For a user, a
|
||||
collaborator grant must still cover the thread. `to` is `user:<id>`, the business human's name or `*`.
|
||||
A `user:<id>` target must have a live grant, of any level, covering the thread's project and instance,
|
||||
else `share-not-covered`. Sharing with yourself fails `invalid-request`. A share that is already in force
|
||||
fails `share-exists`. Writes one `share` row.
|
||||
- `thread.unshare {thread, to}`: the caller must own the thread. The share must be in force, else
|
||||
`share-not-found`. Writes one `unshare` row. Unsharing the owner's or `*` shares works the same way.
|
||||
- `thread.shares {thread}`: the caller must own the thread. Returns the shares in force, latest row each.
|
||||
- Both writes go through `refuse()` on failure, so each refusal records `action.refused` with `by` set
|
||||
(FED 3.6 item 6).
|
||||
|
||||
### 5.4 The read check, one function
|
||||
|
||||
`#readable(s, t)` decides whether a session may read thread `t` it doesn't own. True only when all hold:
|
||||
|
||||
1. a share for `t` is in force whose target is the caller's owner string, or `*`;
|
||||
2. the caller is the owner, or the caller has a live grant of any level covering `t.project` and
|
||||
`t.instance`;
|
||||
3. if `t.owner` is a user, that user still has a live grant covering `t` (a revoked owner hides the
|
||||
thread, sage-1338);
|
||||
4. `t.owner` is not `tester`.
|
||||
|
||||
`#thread(s, id)` keeps its owner check for `thread.open`, `thread.send`, `thread.share`, `thread.unshare`
|
||||
and `thread.shares`. A new `#threadRead(s, id)` admits the owner or `#readable`, and serves only
|
||||
`thread.messages`. A sharee fails `thread-not-owned` on every write verb.
|
||||
|
||||
### 5.5 Every read path and its filter
|
||||
|
||||
| Read path | Today | After row 193 |
|
||||
|---|---|---|
|
||||
| `thread.list` | `owner=?` | unchanged for the owner; for users also each row's thread still covered |
|
||||
| `thread.list {shared: true}` | none | rows where `#readable` holds |
|
||||
| `thread.messages` | `#thread` | `#threadRead` |
|
||||
| `thread.open`, `thread.send` | `#thread` | `#thread`, plus a collaborator grant for users |
|
||||
| `project.list`, `names` | business-wide | per FED 3.5 for users, unchanged for the owner |
|
||||
| `trail`, `replies` | human, reader or tester; any message by id | users refused (`access-refused`); for the others, messages in other users' unshared threads hidden (5.7) |
|
||||
| `messages`, `inbox`, `agents`, `tasks`, `decisions`, `credentials` | human or reader | users refused (`access-refused`); owner unchanged. A user-thread run can't send to the human (`user-thread-human`, FED 3.6), so `messages` holds none of a user's thread |
|
||||
| `message.receive` by a run | its own thread (:1933) | unchanged: runs read their own thread, never a share |
|
||||
| `threadsState` (launcher) | all threads | adds `revoked` per 5.6 |
|
||||
|
||||
### 5.6 Revocation, expiry and unsharing
|
||||
|
||||
Gizmoduck asked that a grant loss end access to threads shared with that user (gizmoduck-0009 point 2).
|
||||
|
||||
- A sharee holds no claim and no run. Its access is only reads, and every read runs `#readable` against the
|
||||
access state the broker already refreshes on each request (mtime, size, inode), on its 30 s timer, and on
|
||||
`access.reload` (FED 3.7). So a removed, expired or invalid grant ends share reads on the next request,
|
||||
with nothing to tear down. The Console polls, so a revoked sharee's next poll fails.
|
||||
- An unshare row ends access on the next request in the same way.
|
||||
- A user who loses coverage of their own thread also loses its shares: rule 3 in 5.4.
|
||||
|
||||
The downgrade case. With viewer, "no live grant covers" would be wrong for runs: a viewer grant covers the
|
||||
thread but must not let a run continue. FED puts this in R4: `revoked`, claim end and the launch check call
|
||||
`covers` with level `collaborator`, so a downgrade to viewer ends the run within one launcher tick. FED r4.4
|
||||
(b67bc6de9, mos-1020) chains R4 after row 193's viewer level (193a) and keeps the level-loss test and its
|
||||
mutant in R4. Row 193 carries neither (Duckworth N3), so the mutant has one owner.
|
||||
|
||||
### 5.7 What "private" means, stated plainly
|
||||
|
||||
Sage ruled (sage-1354): a user's thread is private from the owner on the bus too. Jason's words are "private
|
||||
agent sessions per user", and in Case 2 the owner of Melanie's hub is not the user whose thread it is.
|
||||
Duckworth's B1 asked where the line sits, since a user-thread run acts with the owner's role authority (F10).
|
||||
I took Duckworth's option (a): **the user's messages are private, and the run's governance is not.** The
|
||||
run spends the owner's authority, so its decisions, task writes and claims are the owner's to see and
|
||||
answer. Filtering them too (option b) would need a thread link on `decisions`, more schema, and would hide
|
||||
from the owner what is done in the owner's name.
|
||||
|
||||
Every read an owner or reader session has, and its side of the line:
|
||||
|
||||
| Read | Shows | Side |
|
||||
|---|---|---|
|
||||
| `thread.list`, `thread.messages`, `thread.open` | own threads only, plus shares to the owner from 193b2 | private: other users' threads never appear |
|
||||
| `trail` | events, messages, decisions and deliveries by subject | messages filtered (below); decision rows and their events stay visible |
|
||||
| `replies` | messages replying to an id | filtered (below) |
|
||||
| `messages`, `message.receive`, `message.read` | messages `to_role='human'` (broker.mjs:1931-1936, :1953) | private by construction: a user-thread run can't send to the human (`user-thread-human`, FED 3.6 item 7) |
|
||||
| `inbox` | open decisions routed to the human | governance, visible |
|
||||
| `decisions {list: roles \| recent}` | decision rows with question, options and recommendation | governance, visible |
|
||||
| `agents` | role claims and each held role's state | governance, visible |
|
||||
| `tasks`, `state` | tracker tasks and launch state | governance, visible |
|
||||
| `credentials`, `usage` | credential state, usage records | governance, visible; neither holds message text |
|
||||
| `project.files`, `project.file` | project files, including records a run writes with `record.write` (broker.mjs:1395-1407, :1441-1450) | governance, visible |
|
||||
| `project.list`, `names` | projects and instance names | business-wide for the owner, visible |
|
||||
|
||||
So a decision a user-thread run raises shows in the owner's `inbox` or `decisions`, with the free text the
|
||||
run wrote. Its role claims show in `agents`, its task writes in `tasks`, and a record it writes in
|
||||
`project.file`. Any of these can quote the user, and 5.7 doesn't call them private. The users' help text
|
||||
(R5) and the Console's share and thread pages say so in one sentence, which FED R6 reuses (mos-1023 item 2,
|
||||
duckworth-0012 N21):
|
||||
|
||||
> The business owner sees your thread's agent's decisions, inbox entries, claims, tasks and project files,
|
||||
> but not your messages.
|
||||
|
||||
The gated-raise route. A user-thread run's uncited gated raise or hard wait routes to the human (broker.mjs:1677-1680).
|
||||
FED r4.5 (acd5f1f42, B9) settled this with no guard: the tester guard at :1683 (`tester-thread-human`) is not
|
||||
copied, and the decision reaches the owner's inbox and no other (sage-1368, mos-1021, mos-1022). FED R3 tests it.
|
||||
Row 193 adds nothing here.
|
||||
|
||||
The message filter. A message is hidden from a session when it is in a thread (`message_threads`) whose owner
|
||||
is a `user:<id>` other than the caller, and `#readable(s, t)` is false. Threads owned by the business human or
|
||||
by `tester` are not affected, so row 177's behaviour is unchanged.
|
||||
|
||||
- `trail`: drops hidden messages, their `deliveries` rows, and `events` rows whose `subject` is a hidden
|
||||
message id. A `subject` that is itself a hidden message returns `message-not-found`, as an unknown id does,
|
||||
so the reply doesn't confirm the id exists.
|
||||
- `replies {id}`: a hidden `id` fails `message-not-found`, and hidden messages are dropped from the result.
|
||||
- It applies to every session that can call these verbs: the owner, reader sessions and the tester.
|
||||
- It lands in 193b1, with no schema (Duckworth B2). Before 193b2 there are no shares, so `#readable` is false
|
||||
for anyone but the thread's owner and b1 hides every message in another user's thread. 193b2 adds only the
|
||||
share exception. So no build order can put a user thread live without the filter.
|
||||
|
||||
What it does not do. The owner holds the store as the instance's OS user and can read it with sqlite. That is
|
||||
the same-uid limit in section 6, not a bus path. An owner audit verb, explicit and logged, is a follow-up row
|
||||
only if Jason asks for one (sage-1354).
|
||||
|
||||
## 6. The bus human boundary (brief point 5)
|
||||
|
||||
Row 196 (Gander, #1694, brief `docs/plans/2026-10-20_human-boundary.md` at 96f243faf) owns P19 333 and the
|
||||
verifier. Row 193 cites it and designs no boundary of its own (sage-1338: one mechanism).
|
||||
|
||||
Agreed with Gander (gander-0002, morgana-0003, gander-0005):
|
||||
|
||||
- One bus verifier, `verifyPrincipal(request, connection) -> {kind, business, id}`, kind `owner`, `user` or
|
||||
`tester`. It mints one transient principal per request. It returns no role. The broker reads the level
|
||||
from the live grant on every request, so a grant change acts without a new principal.
|
||||
- Gander recommends FED 3.6's shape for users (path-bound `user-cli.mjs`, direct parent the bus tree's
|
||||
`packages/webui/src/cli.mjs serve`) plus kernel peer PID binding, and weighs bus-side ID-token
|
||||
verification as the larger alternative.
|
||||
- Correction from Gander, accepted: the tester proof doesn't run the full agent walk, because agents bind
|
||||
tester by design (Q173). Managed runs still fail it. The tester listener moves from TCP 7333 to a private
|
||||
Unix socket, with `bus.tester` unchanged (agreed by Sage with Gander).
|
||||
|
||||
What row 193 needs from row 196:
|
||||
|
||||
- H1. Owner on the CLI keeps today's proof. Owner in the Console is a `console.sso.subjects` entry.
|
||||
- H2. A user principal comes only from an OIDC sign-in, through a path the bus verifies. No CLI path for
|
||||
users.
|
||||
- H3. The user binding fails closed on no live grant, an unknown subject, a subject also in
|
||||
`console.sso.subjects`, or a missing or invalid access.json. A broken access.json never stops the owner.
|
||||
- H4. Agent processes never get an owner or user principal.
|
||||
- H5. Revocation ends a bound user within 30 s and at once on `access.reload`, from the same access state
|
||||
row 193's share check reads.
|
||||
|
||||
The same-uid limit. Within one instance, a non-agent process on the instance's uid can claim the owner, and
|
||||
can start its own Console copy and claim any granted user (FED 3.6). An unsandboxed same-uid agent that
|
||||
detaches from its ancestry can do the same. The walk doesn't stop that, and Gander's design won't claim it
|
||||
does (gander-0005). Several humans don't make this worse: a user principal is no stronger than the owner
|
||||
principal that the same process could already take. Users themselves are not on the uid. They reach the
|
||||
bus only through the Console, so the limit is about local processes, not other humans.
|
||||
|
||||
Does row 190 narrow it? Row 190 runs several instances under one uid, so no. Row 190b puts an instance (the
|
||||
hub) under its own Linux user (mos-0986). That narrows reach across instances: another instance's uid fails
|
||||
the uid check (human.mjs:67) and can't read the hub's store or access.json. It does not narrow reach within
|
||||
one instance. Private threads are private from other humans using the bus, not from processes running as
|
||||
the instance's uid.
|
||||
|
||||
## 7. Migration and rollback (brief point 6)
|
||||
|
||||
- No access.json: the business has exactly its owner, every verb behaves as today, and the share verbs
|
||||
work for the owner only (target `*` or none). A broken access.json revokes users and leaves the owner.
|
||||
- Existing threads: already owned by the business human. Nothing is rewritten.
|
||||
- Schema: 3i to 3j adds `thread_shares` only. A re-pin past a schema bump needs a `--migrate` window with
|
||||
Jason, and row 185's backup before activate covers it.
|
||||
- Rollback before any share is written: activate the previous copy with the store restored from the
|
||||
pre-activate backup. A 3i copy refuses a 3j store, as it does for every bump.
|
||||
- Rollback after shares are written: the same restore loses shares made since the window. Grants are in
|
||||
access.json and survive. Users re-share. Row 181's restore guard counts `thread_shares`, so the loss is
|
||||
shown, not silent.
|
||||
- To keep that window small, the build splits (section 9): 193a, 193b1, 193c and 193d have no schema
|
||||
change and can go live in any window. 193b2 carries 3j.
|
||||
|
||||
## 8. Tests and mutants
|
||||
|
||||
Bus, each in `packages/bus/tests/` (193b1: viewer, mixed grants, board reads, the 5.7 message filter and governance pin; 193b2: shares, the share exception to the filter, migration):
|
||||
|
||||
- Viewer: each allowed verb works, every other verb refuses `access-refused`, including `thread.create`,
|
||||
`thread.open`, `thread.send` and `thread.share`.
|
||||
- Mixed grants: collaborator on project A and viewer on B. Create in A works, create in B refuses.
|
||||
- Downgrade: not here. FED R4 owns the level-loss test and its mutant (r4.4, mos-1020, N3).
|
||||
- Shares: owner shares with `user:<id>`, the user reads `thread.messages` and gets `thread-not-owned` on
|
||||
`thread.send` and `thread.open`. Share with `*` reaches every covered user and the owner. Share with a user
|
||||
whose grant doesn't cover the project or instance refuses `share-not-covered`.
|
||||
- A share never widens: the target's grant drops the project, the next read refuses.
|
||||
- Revoke, expiry and an invalid file each end share reads on the next request. The 30 s timer and
|
||||
`access.reload` paths each have a case.
|
||||
- A revoked thread owner hides the thread from sharees.
|
||||
- Unshare ends access. Share, unshare, share again leaves it shared (latest row wins).
|
||||
- Non-owner `thread.share`, `thread.unshare`, `thread.shares` refuse. Tester refuses on all three.
|
||||
- `thread.list` plain shape unchanged. `thread.list {shared: true}` returns only readable threads.
|
||||
- Board reads refuse users and viewers.
|
||||
- Governance pin (B1, sage-1368): a user-thread run raises a decision; it shows in the owner's
|
||||
`decisions recent` with its question text, and `inbox` lists it when routed to the human; the run's
|
||||
role claim shows in the owner's `agents`, its task write in `tasks`, and its `record.write` in
|
||||
`project.file` (B3, sage-1373); the user's message bodies stay hidden from the owner's `trail` and
|
||||
`replies`. The test names each item of the 5.7 user sentence, so the sentence and the pin match.
|
||||
- `trail`, for the owner, a reader session and the tester (193b1): a user's thread message as `subject`
|
||||
fails `message-not-found`; a decision trail that reaches such a message omits it, its deliveries and its
|
||||
events. Once the thread is shared with the owner, the owner's trail shows it.
|
||||
- `replies`, same three sessions (193b1): a hidden `id` fails `message-not-found`; hidden replies are dropped. The
|
||||
owner's own and the tester's threads are unchanged.
|
||||
- Migration: a 3i store with threads migrates to 3j, row counts unchanged, `thread_shares` empty and
|
||||
append-only (update, delete, replace each abort). Restore-guard and `COUNTED` include it.
|
||||
|
||||
Business (193a): R1 accepts `viewer`, refuses any other new level.
|
||||
|
||||
CLI (193c): `mosaic access user add/remove` and `grant --level viewer` refuse tester and agent callers,
|
||||
write a receipt line and call `access.reload`.
|
||||
|
||||
Webui (193d): a viewer has no composer or share control. With each UI check removed, the bus still refuses.
|
||||
|
||||
Mutants, each must be killed:
|
||||
|
||||
1. `#readable` rule 1 dropped (any covered user reads any thread).
|
||||
2. Rule 2 dropped (a share widens the grant).
|
||||
3. Rule 3 dropped (a revoked owner's thread stays visible).
|
||||
4. Latest-row lookup replaced by "any share row" (unshare ignored).
|
||||
5. (Moved to FED R4, N3: the level-loss mutant is R4's.)
|
||||
6. Viewer allowed `thread.send`.
|
||||
7. `#threadRead` used for `thread.send` (sharee writes).
|
||||
8. `share-not-covered` check removed.
|
||||
9. `thread.share` owner check removed (sharee re-shares).
|
||||
10. A user allowed `trail`.
|
||||
11. The `trail` filter removed (the owner reads a user's unshared message by id).
|
||||
12. The `replies` filter removed (the owner reads replies in a user's unshared thread).
|
||||
|
||||
## 9. Build rows and order
|
||||
|
||||
| Row | Work | Chains on | Schema |
|
||||
|---|---|---|---|
|
||||
| 193a | R1 level check widened to viewer | FED R1 candidate | none |
|
||||
| 193b1 | Bus: viewer verb list, per-grant level checks, users refused on board reads, the 5.7 `trail` and `replies` filter with `#readable` as owner-only | FED R3, R4 candidates, row 196 verifier | none |
|
||||
| 193b2 | Bus: `thread_shares`, share verbs, the share rules of `#readable`, `#threadRead`, the 5.5 share filters | 193b1 candidate | 3j |
|
||||
| 193c | `mosaic access` user verbs and `--level viewer`, if R5 lacks them | FED R5 candidate | none |
|
||||
| 193d | Console: shared list, share controls, viewer read-only | FED R6, row 192 candidates, 193b2 for share controls | none |
|
||||
|
||||
Sage ruled the split (sage-1354): 193b1 has no schema change and can go live first. 193b2 carries 3j, and
|
||||
Sage takes its migrate window to Mos when 193b2 is near. The 5.7 message filter is in 193b1 (Duckworth B2,
|
||||
sage-1368), so it is live before any user thread can be, whatever order FED R8 and 193b2 land in. 193b2 adds
|
||||
only the share exception. FED R4 chains on 193a (viewer level), and 193b1 chains on R4.
|
||||
|
||||
Coverage, settled in FED r4.1 (73677b87d, gizmoduck-0018, still under Duckworth's review). A grant's
|
||||
`projects` is `["*"]` or bus project UUIDs (`projects.id`, broker.mjs:2306; `threads.project` references it).
|
||||
R1 exports one pure `covers(grant, {business, project, instance}, now, {level})`. Row 193 uses only that
|
||||
function and adds no second one (Sage confirmed, sage-1354):
|
||||
|
||||
- share reads (5.4 rules 2 and 3) and `share-not-covered`: `covers(g, thread, now, {})`, any level;
|
||||
- `thread.create`, `thread.open`, `thread.send`, `thread.share`: `covers(g, thread, now, {level: 'collaborator'})`;
|
||||
- `project.list` and `names` for users: any level, as FED 3.5.
|
||||
|
||||
`covers` needs no further argument for row 193. If r4.1 changes in review, 193b1 follows it.
|
||||
|
||||
Follow-ups, not in this row:
|
||||
|
||||
- A read-only users and grants page for the owner in the Console.
|
||||
- A second owner or admin level, if Jason wants one.
|
||||
- An explicit, logged owner audit verb for user threads, only if Jason asks for one (sage-1354).
|
||||
|
||||
## 10. Gate
|
||||
|
||||
Per the brief: Duckworth approves this design, then the manifest. The bus, business, cli and webui suites and
|
||||
every `scripts/test-*.sh` pass on Sage's gate, and the section 8 mutants are killed. No test touches the live
|
||||
directories. No product code before Duckworth approves.
|
||||
@@ -1,71 +0,0 @@
|
||||
// Sage, 2026-10-25: files two follow-ups as P19 tasks (mos-1647 item 3, Q109): the CLIProxyAPI startup version refreshes
|
||||
// seen in row 332's isolated runs (a P7 cutover item) and Webby's row 284 N1 (library read path). No relation, labels,
|
||||
// assignees, due dates or bucket moves. Sage's own key (bot user 13); the sync key reads back. Refuses if a title exists.
|
||||
// Prints no secret.
|
||||
// Usage: node file-1025-followups.mjs https://tasks.woltje.com SAGE_TOKEN_FILE SYNC_TOKEN_FILE OUT_JSON
|
||||
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
||||
const [ORIGIN, KEY, SYNC, OUT] = process.argv.slice(2);
|
||||
if (!/^https:\/\/tasks\.woltje\.com$/.test(ORIGIN)) throw new Error("tasks.woltje.com only");
|
||||
if (!OUT || existsSync(OUT)) throw new Error("OUT_JSON missing or exists; refusing");
|
||||
const PROJECT = 19;
|
||||
const SIG = "Created by Sage (T3 1ef1e4f8) with Sage's own key (bot user 13).";
|
||||
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
const ps = (sig, xs) => xs.map((x) => `<p>${esc(x)}</p>`).join("") + `<p>${esc(sig)}</p>`;
|
||||
const TASKS = [
|
||||
{
|
||||
title: "Stack P7 cutover: CLIProxyAPI 8.0.42 makes outbound version-refresh calls at startup (Grok CLI via npm, antigravity)",
|
||||
description: ps(SIG, [
|
||||
"Filed by Mos's ruling mos-1647 item 3. Seen by Fethry in row 332 (P3) isolated runs on 2026-10-24, pinned CLIProxyAPI 8.0.42 (commit bc064340, PIN binary sha256 74661f8c), run under unshare -rn with only lo, empty HOME and auth, panel auto-update disabled.",
|
||||
"At startup the binary logged xai_version.go:96 'failed to fetch latest Grok CLI version from npm' for https://registry.npmjs.org/@xai-official/grok/latest (network unreachable inside the namespace), then xai_version.go:79 'periodic Grok CLI version refresh started (interval=3h0m0s)'. It also logged antigravity_version.go:71 'periodic antigravity version refresh started (interval=3h0m0s)'. Evidence: origin/fethry/row332-p1 agents/fethry/work/queue-332/BUILD.md:251-252 and evidence/offline.txt.",
|
||||
"On the live host these calls would leave the machine every 3 hours, which P1's loopback-only design doesn't account for. The proxy kept working with the fallback version, so the failure is harmless to requests.",
|
||||
"Needed before or at P7 cutover, with Jason present: find whether 8.0.42 has a config switch for these refreshes; if so set it in P1's initial config with a test, otherwise decide deliberately to allow or block the egress (unit-level network policy) and record the choice in P7's receipt. Also recorded in docs/plans/DEFERRED.md. Umbrella: 237.",
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: "Stack: library get lists the whole served tree per read (row 284 N1, Webby)",
|
||||
description: ps(SIG, [
|
||||
"Filed by Mos's ruling mos-1647 item 3. Webby's round 1 note N1 on row 284 (#1789, landed ce0b6ed41 on 2026-10-25), carried in c31654. Not a correctness issue.",
|
||||
"Each read that resolves one file walks the whole served tree with listTree (git ls-tree -r -l) and then finds the one entry: packages/library/src/mirror.mjs:257 and packages/library/src/query.mjs:142, both via packages/library/src/reader.mjs:28. On a large library that is one full tree listing per read.",
|
||||
"Fix options: git rev-parse <commit>:<path> for the one oid, or a per-commit listing cache. listTree also bounds and checks the tree and its object IDs, so a replacement must keep those checks.",
|
||||
"Bound to the next row that edits the library read path: that row measures a get on a library of realistic size and records the choice in its BUILD.md. Also recorded in docs/plans/DEFERRED.md.",
|
||||
]),
|
||||
},
|
||||
];
|
||||
const key = readFileSync(KEY, "utf8").trim(), sync = readFileSync(SYNC, "utf8").trim();
|
||||
async function api(method, path, body, auth) {
|
||||
const r = await fetch(ORIGIN + path, { method, headers: { Authorization: `Bearer ${auth}`, "Content-Type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body), redirect: "error" });
|
||||
const t = await r.text(); let json = null; try { json = JSON.parse(t); } catch {}
|
||||
return { status: r.status, json };
|
||||
}
|
||||
const list = (j) => j?.items ?? (Array.isArray(j) ? j : []);
|
||||
async function existing() {
|
||||
const out = [];
|
||||
for (let page = 1; page < 20; page++) {
|
||||
const r = await api("GET", `/api/v2/projects/${PROJECT}/tasks?per_page=50&page=${page}`, undefined, sync);
|
||||
if (r.status !== 200) throw new Error(`list tasks: ${r.status}`);
|
||||
out.push(...list(r.json));
|
||||
if (list(r.json).length < 50) return out;
|
||||
}
|
||||
throw new Error("more than 19 pages");
|
||||
}
|
||||
const rec = { at: new Date().toISOString(), project: PROJECT, created: null, problems: [] };
|
||||
const save = () => {
|
||||
const out = JSON.stringify(rec, null, 1) + "\n";
|
||||
if (out.includes(key) || out.includes(sync)) throw new Error("secret in the record; not written");
|
||||
writeFileSync(OUT, out);
|
||||
};
|
||||
const have = await existing();
|
||||
for (const T of TASKS) if (have.some((t) => t.title === T.title)) throw new Error("title exists; refusing");
|
||||
writeFileSync(OUT, "", { flag: "wx" });
|
||||
rec.created = [];
|
||||
for (const T of TASKS) {
|
||||
const r = await api("PUT", `/api/v1/projects/${PROJECT}/tasks`, { title: T.title, description: T.description }, key);
|
||||
const c = { status: r.status, id: r.json?.id ?? null };
|
||||
rec.created.push(c);
|
||||
if (r.status >= 300 || !Number.isSafeInteger(r.json?.id)) { rec.problems.push(`create: ${r.status} ${r.json?.message ?? ""}`); continue; }
|
||||
const back = await api("GET", `/api/v2/tasks/${r.json.id}`, undefined, sync);
|
||||
Object.assign(c, { readBack: back.status, done: back.json?.done });
|
||||
if (back.status !== 200 || back.json?.title !== T.title || back.json?.done) rec.problems.push(`read-back differs for ${r.json.id}`);
|
||||
}
|
||||
save();
|
||||
console.log(JSON.stringify(rec));
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"at": "2026-10-25T00:18:17.480Z",
|
||||
"project": 19,
|
||||
"created": [
|
||||
{
|
||||
"status": 201,
|
||||
"id": 633,
|
||||
"readBack": 200,
|
||||
"done": false
|
||||
},
|
||||
{
|
||||
"status": 201,
|
||||
"id": 634,
|
||||
"readBack": 200,
|
||||
"done": false
|
||||
}
|
||||
],
|
||||
"problems": []
|
||||
}
|
||||
+24
-3
@@ -1693,6 +1693,27 @@ are never rewritten or removed; corrections are new entries.
|
||||
2026-10-24 | magica | row329 round2 #1827 | In-progress rev4031; B1 ASCII-only key fix/new inventory tests and N1/N3/N4 docs, cleared reader verification running, old tests byte-identical.
|
||||
2026-10-24 | magica | row329 R2 #1827 | ASCII management-key fix and docs verified: package66/66,bus readers261/261,CLI readers726/726,config55/55; no required failures/skips, slot returned. Preparing authorized ff review candidate; old tests unchanged.
|
||||
2026-10-24 | Sage 1ef1e4f8 | row329 landing #1827 (mos-1634) | Gate GREEN 23:29:14Z unchanged, landed 61ebf2c34 pushed 23:31:27Z; #1827 closed c31650; queue note 4063, done 4064 (b24d917ec); DEFERRED N2/R2-N1 to 331, N1 to P7; Vikunja 631 filed, 237 c1109; 284 and 157 must rebase.
|
||||
2026-10-25 | Sage 1ef1e4f8 | row284 landing #1789 | Gate GREEN 00:09:04Z unchanged, landed ce0b6ed41 pushed 00:09:52Z; #1789 closed c31655; queue note 4071, done 4072 (7c8dc2033); DEFERRED Webby N1 to the next library read-path row; row 332 PROXY_CODEX_API ruled openai-responses (sage-4331), P3 holds for row 331.
|
||||
2026-10-25 | Sage 1ef1e4f8 | rows 214 and 193 landing (#1715, #1691) | 214 gate GREEN 04:10:34Z, landed 3a8e4abad, #1715 closed c31680, queue 4094/4095 (ce8bb4d8b); 193 doc-only landed 35f34ad27 after Duckworth approve 4088; 198 group A and 267 assertion diffs to Mos (sage-4397, sage-4403); CLEAR to Bubba for 288.
|
||||
2026-10-25 | Sage 1ef1e4f8 | row255 landing #1760 | Doc-only design landed de3e23dde after Webby approve 4103 (c31689); 288 r6 gate green from Bubba (2604/0, 12 scripts, 6 mutants), in-review move handed back to the claimant.
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 P3 proxy harness configuration at c8a9bcf94 | Started recovery and design; npm ci in isolated worktree; tests held for Sage CLEAR; no live proxy or credentials accessed.
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 crash stop (mos-1630) | Documentation-only handoff on fethry/row332; four unrun test files and import audit script left uncommitted; no tests/probes/production edits; no jobs restarted or other threads messaged.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 resume sage-4298 | Added unrun launcher persistence test and third mutant; regenerated import audit and delivered full inline report to Sage; no tests, probes, fetches or production edits; CLEAR and after-none notice pending.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 start sage-4301 | Canonical fethry-332-start succeeded rev4059 briefed→in-progress; no tests/probes/fetches pending CLEAR.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 P1 rebase/reader pre-step | Rebased to 9e2689dff, HEAD efe3e4697; uncommitted tests restored; P3 imports P1 broker through cli test helpers, stopped/reported under sage-4313 step1 before execution.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 first RED lane B | Ran four new files+whole launcher, all34 old launcher tests pass; two new fixture errors; fixes b285e581e then one rerun each: plugin valid RED1/4, bundle further fixture error0/5; reported/stopped, no mutants/probes/fetches, no test process leftovers.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 corrected bundle RED sage-4320 | Fixture-only56701f715 atop b285e581e; whole bundle0pass/5fail/0skip at23:44:40Z, all missing models.json generation; lane B returned, no production edits/mutants/probes/fetches.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 P3 implementation sage-4323/4325 | Production edits and authorized old fixtures written; optional route default Anthropic; GPT wire PENDING; no runs/probes/fetches, preparing pushed unverified checkpoint and import list.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 six-file run sage-4326 | business6/0,seat2/0,proxy-harness5/0,harness9/0,bundle1/5(PENDING),launcher34/1(old fallback lacks own pi key),zero skips; no reruns/behavior fixes, reported old RED before edit; title-only correction authorized, lane B free23:57:42Z,no test leftovers.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 fixture verification sage-4327 | f1e8cda07 bundle6/1(PENDING)/0skip,launcher35/0/0skip; no other failures, old fallback fixed in test only; lane B free23:59:45Z,no test leftovers.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 route required sage-4328 |9563fbc8b proxy-launch6/0,launch-settings18/0,bundle6/1(expected GPT PENDING),launcher35/0,zero skips; grep positive controls/old assertion preservation recorded; lane B free00:02:27Z UTC10-25,no test leftovers,no probes/fetches/mutants.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 pinned offline evidence sage-4329/4330 | One verified fetch; first setup0turns wrong provider shape; statically diagnosed bundled panel schema then one corrected isolated attempt: both GPT shapes+GLM exit0/marker,thinking retained,tool_stream untested(no tools); GPT choice inconclusive/PENDING,no real auth; process cleanup0,lane B free.
|
||||
|
||||
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 sage-4331 API choice and GLM tool field | ef0939e35 responses constant per lead reasoning tie-break;rehash/no-fetch isolated GLM one turn0/tool_stream retained;bundle7/0/0skip,proxy-harness5/0/0skip;lane B free00:14:20Z UTC10-25,no test leftovers;wait row331 before further work.
|
||||
@@ -1,70 +0,0 @@
|
||||
# PRD 1.18 brief: REQ-INST-2 prints the providers entry
|
||||
|
||||
Sage, 2026-10-25, for Mos's ruling mos-1671 on sage-4418. This follows
|
||||
`docs/plans/BRIEF-TEMPLATE.md`. Vikunja 458 (bundled Pocket ID).
|
||||
|
||||
## PRD 1.18 REQ-INST-2 prints the providers entry (mos-1671)
|
||||
|
||||
### Problem
|
||||
|
||||
REQ-INST-2's second bullet says the stack installs the bundled Pocket ID "and
|
||||
writes it as the Console's one providers entry". That sentence is Mos's reading
|
||||
(mos-1202), not Jason's words. The row 255 design, landed at de3e23dde, chose R1:
|
||||
enroll prints the entry and writes nothing, because config.json is user-authored
|
||||
and never overwritten (canon invariant 2, Q175). Mos approved R1 in mos-1666 and
|
||||
ruled the amendment in mos-1671. What the requirement allows or forbids is
|
||||
unchanged.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
- Owner: Gosalyn.
|
||||
- Reviewer: Webby.
|
||||
- After: row 255 (landed).
|
||||
|
||||
### Files owned
|
||||
|
||||
- `docs/prd/mosaic-stack.md`.
|
||||
- `packages/tasks/requirements.json`: version 1.18 only. No id or title changes,
|
||||
so the count stays 87.
|
||||
- `packages/tasks/tests/requirements.test.mjs`: the version pin 1.18 (:24).
|
||||
|
||||
### What ships
|
||||
|
||||
- In REQ-INST-2's second bullet (PRD :1519-1520), replace
|
||||
"and writes it as the Console's one providers entry."
|
||||
with
|
||||
"and prints the Console's one providers entry for the user to add to
|
||||
config.json. The stack never writes config.json (canon invariant 2)."
|
||||
The rest of the bullet stays, and so does Jason's Q203 quote.
|
||||
- Status line: version 1.18.
|
||||
- The header gets a 1.18 sentence: Version 1.18 corrects Mos's reading in
|
||||
REQ-INST-2 to match the approved row 255 design. The stack prints the
|
||||
providers entry and never writes config.json. What the requirement allows or
|
||||
forbids is unchanged (mos-1671, sage-4418). Doc-only, so it takes the 1.11
|
||||
path: one seat drafts, a second reviews, Sage lands.
|
||||
- A "Version 1.18 source" line, placed before the 1.17 one: Mos's ruling
|
||||
mos-1671 on 2026-10-25, answering sage-4418, with the old and new text.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- The P1 to P6 build rows from the row 255 design. Sage files them after this
|
||||
lands (mos-1671).
|
||||
- Any other REQ-INST-2 wording, and REQ-INST-1 and REQ-INST-3.
|
||||
|
||||
### Gate
|
||||
|
||||
- Webby checks that the PRD diff is the replacement, the Status line, the 1.18
|
||||
sentence and the source line, and nothing else.
|
||||
- On Sage's gate:
|
||||
- tasks, run whole;
|
||||
- bus, run whole, because the broker loads requirements.json;
|
||||
- cli `stack-copy.test.mjs`;
|
||||
- every `scripts/test-*.sh`, under `timeout -k 10`.
|
||||
- Mos gets the landing commit.
|
||||
|
||||
### Handoffs
|
||||
|
||||
Every seat hands off directly (DECISIONS Q210, mos-1221). When the owner pushes a
|
||||
round or the reviewer posts a verdict, that seat messages the next seat's T3
|
||||
thread and Sage's with `mcp__t3__t3_send_message`. Mos has one step here, which
|
||||
is receiving the landing commit.
|
||||
@@ -796,27 +796,3 @@ Sage, for Dewey's round 1 N1 on row 329 (c31639). The acceptance netns had only
|
||||
but never saw the real binary refuse a non-loopback client.
|
||||
Bound to P7: at cutover, with Jason present, confirm the listener is on 127.0.0.1 only (`ss -ltnp`), and
|
||||
record it in P7's receipt.
|
||||
|
||||
## Row 284 N1: library.get lists the whole served tree per read
|
||||
|
||||
Sage, for Webby's round 1 N1 on row 284 (c31654 carries it forward). Each library get runs `listTree`
|
||||
(`git ls-tree -r -l`) over the whole served tree to find one blob oid. On a large library that is one full
|
||||
tree listing per read. `git rev-parse <commit>:<path>`, or a per-commit cache, would avoid it. Not a
|
||||
correctness issue. Bound to the next row that edits the library read path; that row measures a get on a
|
||||
library of realistic size and records the choice in its BUILD.md.
|
||||
|
||||
## Row 284 N1: Vikunja task
|
||||
|
||||
Sage, for mos-1647 item 3 (Q109). The row 284 N1 entry above is tracked as Vikunja 634. No open task
|
||||
covered the library read path.
|
||||
|
||||
## Row 332 finding: CLIProxyAPI startup version refreshes reach outside the host
|
||||
|
||||
Sage, for Fethry's row 332 isolated runs (2026-10-24, pinned 8.0.42, `unshare -rn` with only `lo`). At
|
||||
startup the binary tried `https://registry.npmjs.org/@xai-official/grok/latest` (xai_version.go:96, blocked
|
||||
by the namespace) and then started a 3-hour Grok CLI version refresh and a 3-hour antigravity version
|
||||
refresh. The proxy kept serving with its fallback version. Evidence: origin/fethry/row332-p1
|
||||
`agents/fethry/work/queue-332/BUILD.md`:251-252 and `evidence/offline.txt`. Bound to P7: before or at
|
||||
cutover, find a config switch that turns these off and set it in P1's initial config with a test, or
|
||||
decide on purpose to allow or block that egress and record it in P7's receipt. Tracked as Vikunja 633
|
||||
(umbrella 237).
|
||||
+10
-10
@@ -33,7 +33,7 @@ Gaps found while working go to `docs/plans/DEFERRED.md`, not here.
|
||||
|
||||
<!-- mosaic-queue:begin -->
|
||||
|
||||
Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not edit between the markers; change the queue with `scripts/mosaic queue`.
|
||||
Generated from `docs/plans/queue.json` revision 4064 by `queue render`. Do not edit between the markers; change the queue with `scripts/mosaic queue`.
|
||||
|
||||
| # | Piece | Owner | Issues | State | After | Gate | Brief | Note |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
@@ -229,7 +229,7 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 190 | several Mosaic Stack instances on one host: per-instance config, data root, units and ports (MVP T1.1, mos-0974, Vikunja #414) | darkwing; reviewers filbert | #1688 | done | — | Filbert approves DESIGN.md then the manifest; cli suite and every scripts/test-*.sh green on Sage's gate; the design mutants killed (sage) | `docs/plans/2026-10-20_multi-instance.md` § Brief: several Mosaic Stack instances on one host | Landed 00d4cc1f6 on refactor (base 99a406ed3). Patch-id 5ec610a7 matches git diff 176a6bf4b..df65a3d4c on the 25 manifest paths. Manifest cc0ea9e8, Filbert approve r3 29713. Gate on d0bbc5c1c: packages 2664/0, scripts 429/0. Mutants 20/20. Unpushed. |
|
||||
| 191 | one kill switch for the bus, every run, Discord and new launches, from the CLI and the Console (MVP T1.4, mos-0974, Vikunja #414) | rocko; reviewers dewey | #1689 | done | — | Dewey approves DESIGN.md then the manifest; cli, bus, discord and webui suites and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_kill-switch.md` § Brief: one kill switch for the bus, every run, Discord and new launches | Landed 0fa7bf421 fast-forward on 86f95bb27 (10 commits, 89 paths; manifest 0bcbf337 = 88 paths without BUILD.md). Dewey manifest APPROVE c30359 rev 3118. Gate: 77 mutants killed (75 assert + SR08, KS54 timeout with controls), suites green on Sage's window; N7 closed by runs suite 43/0/0 on 0fa7bf421. N6, clock fix, :52 assertion, generic cause go to Vikunja 502 (mos-1267/1268). Rebase next: 205, 236, 194, 253, 274, 268. |
|
||||
| 192 | Q175 phase 1: the Console verifies SSO itself (--sso), OIDC RP with oauth4webapi 3.8.8, no live change (MVP T1.2, #412) | launchpad; reviewers webby | #1690 | done | — | Webby approves the manifest; webui and cli suites, scripts/test-config.sh and every scripts/test-*.sh green on Sage's gate; design section 9 mutants killed (sage) | `docs/plans/2026-10-20_sso-phase1.md` § Brief: Q175 phase 1, the Console verifies SSO itself (--sso) | Landed 4429a104f on refactor (squash of launchpad/row192 53bb59462..37582e820, round 2 manifest 6f8cee14...7787). patch-id 4a4869026 matches the reviewed diff on all 18 paths. Gate on 088087ac9: package suites 2758/0, scripts 429/0, mutants 22 of 23 killed (#23 equivalent, sage-1407). npm ci in canonical, oauth4webapi 3.8.8. Live re-pin is a window with Mos (mos-1099 item 3). |
|
||||
| 193 | many humans per business, human roles, private and shared threads, one access.json store (MVP T1.3, Vikunja #414/#415) | morgana; reviewers duckworth | #1691 | in-review, round 1, request posted | — | Duckworth approves DESIGN.md then the manifest; bus, business, cli and webui suites and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_human-users.md` § Brief: many humans per business, human roles, private and shared threads | — |
|
||||
| 193 | many humans per business, human roles, private and shared threads, one access.json store (MVP T1.3, Vikunja #414/#415) | morgana; reviewers duckworth | #1691 | in-progress | — | Duckworth approves DESIGN.md then the manifest; bus, business, cli and webui suites and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_human-users.md` § Brief: many humans per business, human roles, private and shared threads | — |
|
||||
| 194 | agent lifecycle from the Console and the CLI (create, launch, terminate, regenerate, delete) with a per-agent hire/fire veto (MVP T1.5, Vikunja #414/#415) | honker; reviewers webby | #1692 | done | — | Webby approves DESIGN.md then the manifest; bus, cli, business and webui suites and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_agent-lifecycle.md` § Brief: agent lifecycle from the Console and the CLI, with a per-agent hire/fire veto | Landed fd6dd327c on refactor, a fast-forward on e122aad8e. b18 is b17 3f451772d rebased: 16 commits =, series patch-id 64303253f8e6, packages equal b17. Webby approve webby-0120 on manifest 29f131ab. Honker gate on fd6dd327c: runb8 39 files 503/0/0, mutants 17/17; gate.sh 18 packages 3668/0, ten scripts rc=0, Docker up, skips environment-only and named. Overlap with 13 and 257 clean. #1692 closed. |
|
||||
| 195 | row 195: the Case 1 install on 10.1.1.53 as mosaic under /srv/mosaic, reusing C2-13's scripts by input under row 190's canon (Q181, Q182/Q183, Q185; ops-01 root steps under #423 step 1) | darkwing; reviewers duckworth | #1693 | done | 190 done, 226 done, 233 done | Duckworth approves DESIGN.md then the manifest; cli suite and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_hub-own-uid.md` § Brief: the Case 1 install on 10.1.1.53 (row 195) | LANDED b65014647 (pushed 361ba2387 tip). Patch-id 656e43ff25de = 4ced5e63d..37171f65b; verify-commit ok, 5 paths. Combined gate with 213 on 38b83ea5c+paths 09:45:52-09:57:52Z: business 200/0 bus 542/0 harness 140/0 cli 663/0, all 10 scripts green, L1 killed. N1-N3 to DEFERRED next; follow-up darkwing/row195-n1 1e3c4767c. |
|
||||
| 196 | the human boundary across uids and humans: Console, tester listener, broker.sock and the path-bound human proof (P19 333, before federation R3, mos-0989) | gander; reviewers duckworth | #1694 | done | — | Duckworth approves DESIGN.md then the manifest; bus, webui and cli suites and every scripts/test-*.sh green on Sage's gate; the mutants killed (sage) | `docs/plans/2026-10-20_human-boundary.md` § Brief: the human boundary across uids and humans (P19 333) | Landed 7247d80c7 on 666173292: 39 manifest paths of 527b9a1e6 (CANDIDATE.sha256 537d30ae), patch-id 6f3777d593e6 matches f48725cfc..527b9a1e6 on the manifest, blob diff empty, tree matches merge-tree. Gate gander-0066 2334/0/1, all 10 shells, 38/38 mutants. Approved rev 2973 and rev 2986 (Duckworth, c30156). Overlap: 202 cli README and 194 Honker branches rebase onto it. BUILD-LOG and C1 DEFERRED follow doc-only. |
|
||||
@@ -250,7 +250,7 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 211 | Force-push guard: scripts/git-hooks/pre-push refuses non-fast-forward and delete pushes from every worktree, and scripts/slot-busy.sh exits 1 on BUSY (#1709, Vikunja #426, mos-1078/1083) | darkwing; reviewers dewey | #1709 | in-progress | — | Dewey approves the manifest; the new or changed scripts/test-*.sh and every other scripts/test-*.sh green on Sage's gate; the mutants killed; hook installed in the canonical checkout with a scripted refused force-push (sage) | `docs/plans/2026-10-20_force-push-guard.md` § Brief: a pre-push hook that refuses force-pushes, and a busy check that fails on BUSY (#426) | — |
|
||||
| 212 | Case 2 C2-01 packages/library: mapping, scope, reader, resolver, R-rules, renderItems, survey | gosalyn; reviewers webby | #1713 | done | — | Webby approves the manifest. The library tests and the cli suite are green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-01 packages/library: mapping, scope, reader, resolver, R-rules, renderItems, survey | Landed ee7b2f137 (pushed 09:13Z) on f6c70f944, alone per mos-1162: the 21 manifest paths from a2c72ac95. Patch-id ea84d3e35470 equals the candidate's; blobs and modes match; verify-commit ok (21 paths). No 212 path changed after c771a36f4. Gate: Sage's landing gate 08:51-09:03Z on 4ced5e63d plus 212's and 197's paths, GATE_PASSED, node 981/0, selftests 429/0. Gosalyn r3 slot 451/0, test-queue 28/0. Row 197 waits for r6 (lane proof stopped, sage-1881). |
|
||||
| 213 | Case 2 C2-08 creative roles, persona file and block, M1, M2, M6, M10, prompt passed by file | morgana; reviewers webby | #1714 | done | — | Webby approves the manifest. The business, bus and harness suites, `scripts/test-config.sh` and every `scripts/test-*.sh` are green on Sage's gate, and the `models` mutant is killed. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-08 creative roles, persona file and block, M1, M2, M6, M10, prompt passed by file | LANDED 361ba2387 (39 paths incl. 4 packet files). Patch-id f313e69b6f7e = c771a36f4..2b3e67e36; verify-commit ok, 35 manifest paths. Same combined gate as 195: business 200/0 bus 542/0 harness 140/0 cli 663/0, test-config 31/0 and all 10 scripts green, models mutant L1 killed. Webby N2 is row 235 acceptance (mos-1163). |
|
||||
| 214 | Case 2 C2-11a editor wikilink node, after measuring whether [[ round-trips | herb; reviewers filbert | #1715 | done | — | Filbert approves the manifest. The webui suite is green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-11a editor wikilink node, after measuring whether [[ round-trips | LANDED 3a8e4abad (pushed 78b69e1e6..3a8e4abad, 6 commits cherry-picked onto 78b69e1e6). Gate GREEN 04:10:34Z, all package suites and scripts; queue package runs via test-queue.sh (156). Filbert approve c31679 rev 4093. Range-diff equal except BUILD-LOG context. |
|
||||
| 214 | Case 2 C2-11a editor wikilink node, after measuring whether [[ round-trips | herb; reviewers filbert | #1715 | in-progress | — | Filbert approves the manifest. The webui suite is green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-11a editor wikilink node, after measuring whether [[ round-trips | — |
|
||||
| 215 | Case 2 C2-04 the library entry in the business file, consumer skips, M9, mirror, library.file and library.status | herb; reviewers filbert | #1716 | done | — | Filbert approves the manifest. The business, seat, cli, project, bus and webui suites are green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-04 the library entry in the business file, consumer skips, M9, mirror, library.file and library.status | LANDED e54e05463 on 6096b051b (sage-2094). Patch-id 2f68188b6c9d equals a36523713..dde3445ab; 118 paths, blobs and modes equal; tree 5b1613245 equals merge-tree. No path overlap with rows 66/243; no hash pins either way. Gate: Filbert APPROVE rev 2924; herb-0095 grant sage-2071 2634 pass 0 fail, 1 webui skip (editor rebuild needs esbuild 0.28.2, env, not a 215 path), accepted. |
|
||||
| 216 | Case 2 C2-05a lookup index and queries | researcher; reviewers filbert | #1717 | done | 268 done | Filbert approves the manifest. The library suite is green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05a lookup index and queries | LANDED fbe57a05b (replay of r5 dae76ccc2 onto 8e2885d26, 3 commits, 0 patch-id mismatches), pushed 21:09Z with 582b86935. Sage joint gate GREEN 21:05:34Z on fbe57a05b, every package suite but queue and every scripts/test-*.sh green. Filbert APPROVE r2 c31384 rev 3697. N3 (get returns a universe own supporting files) binds the C2-05c row; N1 doc, N2 universeInfo echo and BUILD.md pronoun nit go to a later docs commit. |
|
||||
| 217 | Case 2 C2-06 the citation guard, the page store, the runner texts and the retry | beakley; reviewers webby | #1718 | done | 268 done, 283 done | Webby approves the manifest. The library, bus and harness suites are green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-06 the citation guard, the page store, the runner texts and the retry | LANDED d0a6a87cd (pushed 11:15Z 10-24, with 296): 9 cherry-picks on 296, range-diff 5 = and 4 ! (BUILD-LOG/SESSIONS append conflicts kept both), blobs equal 96659ccf4 (79 paths); Webby c31549 rev 3901; gate GREEN 11:14:53Z own npm ci, library 142 bus 974 business 270 cli 988 harness 172 0 fail, all scripts rc 0; PUSH_READY; #1718 closed c31559; Vikunja 533 comment 1054. |
|
||||
@@ -291,7 +291,7 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 252 | Console inbox Approve and Deny for grant requests (#435, J2) | scrooge; reviewers webby | #1753 | done | — | Webby approves DESIGN.md then manifest; webui, bus, cli suites and every test-*.sh green on Sage's gate; DESIGN mutants killed; REQ-WEB-2 PRD amendment landed first (sage) | `docs/plans/2026-10-21_console-inbox-approve.md` § Gate | Landed 45ea3fa0d (replay of Scrooge 580037105 onto 30e6bb680, range-diff all =, 10 commits). Webby APPROVE c31229 rev 3612. Sage gate on 45ea3fa0d: every package suite 0 fail 0 skipped (bus 907, cli 943, webui 410), every scripts/test-*.sh rc 0, J1-J19 all killed except J11c and J18 (equivalent per BUILD.md), all restores match. Old-test numstat 1 1 vs fe4ee8c7b held. |
|
||||
| 253 | F27: case2-unit.sh and case1-accept.sh move to --tester-socket and refuse --tester-port with stack-release's migration wording; no .53/.54 copy with 196 until this lands (mos-1198 item 4) | gander; reviewers duckworth | #1758 | done | 196 done | reviewer approves DESIGN.md then the manifest; cli and webui suites whole and every scripts/test-*.sh on Sage's slot; mutants per DESIGN.md; static check covers scripts and tests (sage) | `docs/plans/2026-10-21_tester-socket-scripts.md` § Brief: case2-unit.sh and case1-accept.sh move to --tester-socket (F27) | Landed 48e450ce8 on refactor (fast-forward from aca16404c, 22 commits; landed sha = candidate, so range-diff and patch-id are identical by construction). Manifest 591020a1 (7 paths) rechecked against the commit: 0 mismatches. Gate: run 5 whole, cli 55 files, webui 58 files, all 10 scripts/test-*.sh green; M1-M40 killed 40/40. Duckworth APPROVE round 1, Gitea #1758 comment 30696. |
|
||||
| 254 | Library sync follow-up: client timeout, STATUS codes, README (222 deferrals, #1759) | megavolt; reviewers dewey | #1759 | done | 196 done | Dewey approves the manifest; bus, library and webui suites whole and every scripts/test-*.sh green on Sage's slot; the timeout and STATUS mutants killed (sage) | `docs/plans/2026-10-21_library-sync-followup.md` § Gate | Landed 331597709 (candidate b31300d79 blobs and modes on 41b0cf755; patch-id 96216216 equal, range-diff differs only in the message) plus doc eb9672c91 (Dewey N1 README sentence closed; N2 four 502 codes to DEFERRED, binding the Console library routes row). Merged-tree rerun on Sage's slot 23:44-23:55Z: library 77/0, bus 628/0, webui 305/0 with 1 skip, cli 749/0. Megavolt's gate megavolt-0102 covers scripts and both mutants. |
|
||||
| 255 | Bundled Pocket ID for users with no OIDC provider, design (Q203, #1760) | launchpad; reviewers webby | — | in-progress | 252 done | Webby approves DESIGN.md; design only, build rows follow after Sage checks it against Q203, O6, REQ-WEB-2 and REQ-INST-1 (sage) | `docs/plans/2026-10-21_bundled-pocket-id.md` § Gate | Vikunja 458, Gitea #1760, mos-1202 item 2. REQ-INST-2 lands in PRD 1.10 as post-v1 (mos-1204). Design only: no install, no download, no .53/.54, dragon-lin keeps Authentik. |
|
||||
| 255 | Bundled Pocket ID for users with no OIDC provider, design (Q203, #1760) | launchpad; reviewers webby | — | queued | 252 done | Webby approves DESIGN.md; design only, build rows follow after Sage checks it against Q203, O6, REQ-WEB-2 and REQ-INST-1 (sage) | `docs/plans/2026-10-21_bundled-pocket-id.md` § Gate | Vikunja 458, Gitea #1760, mos-1202 item 2. REQ-INST-2 lands in PRD 1.10 as post-v1 (mos-1204). Design only: no install, no download, no .53/.54, dragon-lin keeps Authentik. |
|
||||
| 256 | the human deletes a creative instance; any other actor refused, fire unchanged (REQ-COS-3, before the v1 tag) | honker; reviewers webby | #1761 | done | 194 done | Webby approves the manifest; touched test files whole plus business, bus, cli and webui suites and every scripts/test-*.sh green on Sage's slot; both mutants killed (sage) | `docs/plans/2026-10-21_creative-delete-human.md` § Brief: the human deletes a creative instance (REQ-COS-3, after row 194) | LANDED f12441d4f ff from 0165be266 (4 Honker commits, patch-id b28e6374). Webby APPROVE manifest-r3 01eb75aa (10 paths), request c30518. Gate 10:33-10:52Z: 4 touched files 31/0, 18 packages 3757/0 (bus 788, business 231, cli 832, webui 335), 10 scripts rc=0, mutants M1-M4b killed; skips named, env only (webui esbuild pin, test-queue root, test-task live x2). Overlap 13/257 clean. Lands before the 10-27 v1 tag. |
|
||||
| 257 | Q198 S1: pressure parser and pure rules evaluator (post-v1) | morgana; reviewers filbert | #1762 | done | — | Reviewer approves the manifest; touched test files whole plus the package suite green on Sage's slot; both brief mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: Q198 S1 pressure parser and pure rules evaluator | Landed 73692e1bb, pushed 17:41:58Z 10-24: Morgana's 4 commits cherry-picked onto 487500a16, patches unchanged; 9 supervisor paths match Filbert r2 manifest b176a88f (APPROVE c30190, rev 3037). Gate RED 17:20Z (webui row278 sign-out timing, old test, row touches no webui), full rerun GREEN 17:41:11Z, cli skip FED R7 allowed. push-check clean. #1762 c31613, closed. Carry 447286192 lands doc-only. |
|
||||
| 258 | Email E01: mail PRD addendum draft and schemas (post-v1) | ludwig; reviewers della | #1763 | in-progress | — | Reviewer approves the manifest; the row's named tests whole plus the mail suite and touched suites green on Sage's slot; reviewer-named mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: E01 mail PRD addendum draft and schemas | — |
|
||||
@@ -303,7 +303,7 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 264 | T1 item 7: independent sessions, compaction counts and clear context | gizmoduck; reviewers duckworth | #1769 | done | — | The named reviewer approves the manifest. The design's T1-T7 acceptance tests run whole plus every touched suite on Sage's slot; T3 waits on Vikunja 466 (N2, Claude's compaction count format and the managed dataRoot reader). The design's section 6 mutants are killed. (sage) | `docs/plans/2026-10-21_t1-sessions.md` § T1 item 7: independent sessions, compaction counts and clear context | LANDED 84f53540d ff on e479521d3 14:18:23Z, 21 commits = gizmoduck/row264-r13 tip (no rewrite, range-diff identity). Manifest 257408e9 approved Duckworth rev 3214 (c30640). Gate r13 2cc34aef8: 20 files, bus 827, cli 837, webui 345/1 skip, 10 shells; M1-M4 assertion kills (mos-1279 B, M2 4 files). Overlap none (13, 257). N1 actor_run binds row 269; N2 esbuild skip later gate (sage-2695). |
|
||||
| 265 | Case 2 C2-09b rooms: room.open, room.send with @tags, room.read | goldie; reviewers boyd | #1770 | done | 219 done | Boyd approves the manifest. The brief's tests run whole plus the bus suite and every touched suite on Sage's slot. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-09b rooms: room.open, room.send with @tags, room.read | LANDED 200dd396c (cherry-pick of ef4c93853, 50 blobs equal, log appends equal) 05:13Z on full gate 04:57-05:12Z: all package suites except queue 0 fail 0 skip (bus 957, cli 986, seat 218), every scripts/test-*.sh green. Boyd c31501 incl mos-1567 mount read. 22 gzip logs scanned decompressed, clean. #1770 closed c31510. Bundle 02c3c286. |
|
||||
| 266 | Case 2 C2-10c Console room view: merged timeline and @name completion | fethry; reviewers boyd, dewey | #1771 | done | 225 done, 265 done | Dewey approves the manifest. The webui suite is green on Sage's gate, along with every touched suite. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-10c Console room view: merged timeline and @name completion | LANDED 3e5041b43 18:00:49Z 10-24, patch-ids equal to Fethry b8b26ae4d..6418ec063; gate GREEN 18:00:08Z first run (bus 1000/0, webui 458/0, cli 989+1 FED R7 allowed, 12 scripts rc 0); Boyd c31609, Dewey c31610; #1771 c31615 closed; Dewey N2 T9 race goes to Mos |
|
||||
| 267 | Case 2 C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | morgana; reviewers filbert | #1772 | in-progress | 216 done, 217 done, 224 done | Filbert approves the manifest. The brief's tests and the end-to-end crossover run whole plus every touched suite on Sage's slot. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | R8 accepted (sage-2218). Webby's R8 noise note (gosalyn-0127) is for the builder. |
|
||||
| 267 | Case 2 C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | morgana; reviewers filbert | #1772 | queued | 216 done, 217 done, 224 done | Filbert approves the manifest. The brief's tests and the end-to-end crossover run whole plus every touched suite on Sage's slot. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | R8 accepted (sage-2218). Webby's R8 noise note (gosalyn-0127) is for the builder. |
|
||||
| 268 | Case 2 C2-01c playground levels: universe-level prefixes and draft universes | gizmoduck; reviewers webby | #1773 | done | — | Webby approves the manifest. The brief's tests run whole plus the library suite and every touched suite on Sage's slot; the brief's gate grep over packages and docs/case2 finds no library-playground-outside-book. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-01c playground levels: universe-level prefixes and draft universes | Landed c27207f6e fast-forward on ce6a96ad6 (1 commit, 9 paths, digest caa0fa4e). r4 is a carry of r3 aca53c4f0: range-diff =, patch-id 2942acc8 equal, blobs equal. Webby APPROVE round 2 on ecd9b35eb stands; carries webby-0112 (r3) and webby-0113 (r4, notes 34e1ab2bf). Gate: Gizmoduck r4 rerun brief 14/14, library 83/83, business 209/209, 0 skips; gate grep empty. 194 rebases next (business.test.mjs). |
|
||||
| 269 | 264b T1 item 7: per-session native store, workspace and single-writer fence | gizmoduck; reviewers duckworth | #1774 | done | 264 done | Duckworth approves this slice's manifest. Its design tests run whole plus every touched suite on Sage's slot, and its mutants are killed (RULINGS Q1). Tests T1 run half, T2 workspace and path mutants; whichever of 191 and 264b lands second wires 191's admission checks (Q5). (sage) | `docs/plans/2026-10-21_t1-sessions.md` § T1 item 7: independent sessions, compaction counts and clear context | Landed efcc9ea8d fast-forward on 94c33a43c (13 commits, 12 paths, manifest 455c12ee). r3 is a carry of r2 aafcc857c, range-diff = (Duckworth 0194, c30756, rev 3307). Gate r3 18:37-18:50Z all green, 0 skips: bus 834, seat 172, cli 869, case2-unit 43, singles 38. M1-M12 kills carry. Re-pin needs the Console restart by Jason or Mos right after the host. A 264a rollback refuses a v2 sessions.json, see BUILD.md Rollback. |
|
||||
| 270 | 264c T1 item 7: compaction count, exact for Pi | gizmoduck; reviewers duckworth | #1775 | done | 269 done | Duckworth approves this slice's manifest. Its design tests run whole plus every touched suite on Sage's slot, and its mutants are killed (RULINGS Q1). Test T3 Pi half; Claude shows unknown with the Vikunja 466 reason (Q6). (sage) | `docs/plans/2026-10-21_t1-sessions.md` § T1 item 7: independent sessions, compaction counts and clear context | LANDED 7328da8ca (with 271, mos-1351) 02:13Z 10-23 on 767bb62c7: 33 commits cherry-picked from gizmoduck/row270-271-r4 49cee846e (base 25c09f19f), range-diff all '=', 40 paths identical to 49cee846e. Manifest f4174458 (15 paths) matches the tip. Duckworth APPROVE c30930 rev 3389. C2 run 5 GREEN on 53406f3e4: bus 873, seat 202, cli 905, ten scripts, 38/38 mutants killed. #1775 closes. |
|
||||
@@ -320,11 +320,11 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 281 | A fire or a delete revokes the instance's host and Gitea grants (194/236 follow-up, MVP, mos-1271) | megavolt; reviewers dewey | #1786 | done | 236 done | Dewey approves the design, then the manifest. Bus, business, cli and every touched test file run whole, plus the Docker gitea-grant test and every scripts/test-*.sh, green on Sage's gate. M1-M4 killed. Lands before .53 Case 1 hires a granted instance. Red goes to Sage, then Mos. (sage) | `docs/plans/2026-10-22_fire-revokes-grants.md` § Brief: no grant outlives its instance | LANDED e479521d3 ff on 385a7194c (17 commits, manifest b73d4c81). Slot on 7979fb41e green: bus 819, business 231, cli 837, dewey-bus 76 with gitea-grant-docker run, shells green under 3x limits, M1-M22 killed. M1 hang fixed in b4a (mos-1273). Skips: test-task row 244 live-provider pair, test-queue canonical root. DEFERRED: N1 host-unknown hint verb, N2 fire tool text, to the follow-up row. Dewey APPROVE c30614. |
|
||||
| 282 | PRD REQ-LIB-6 rewritten to Q223 and Q226 (mos-1320 item 8) | gosalyn; reviewers webby | #1787 | done | — | Webby approves against the ruling. requirements.test.mjs and every scripts/test-*.sh that reads the PRD or requirements.json are green on Sage's gate. Jason gets a report. (sage) | `docs/plans/2026-10-20_case2-rows.md` § PRD REQ-LIB-6 rewritten to Q223 and Q226 (mos-1320 item 8) | Landed 647424442 on 86a665bdf: 1841f7d4e and 6b5b06819 rebased, patch-ids equal (4e50b4b6, 16a7a02f), range-diff =, tree 4f30ed10a = Gosalyn's gated trial tree. Webby APPROVE rev 3308 c30764 on 6b5b06819. Gate 19:06Z on the tip tree: bus+tasks requirements and tasks verbs 37/0/0, 0 skips; no scripts/test-*.sh reads the PRD (control ok). PRD 1.15. 1.16 is row 291, waits for Jason. |
|
||||
| 283 | Case 2 C2-01d supporting folders, the supporting scope, the editor field and supportingPath (M12) | honker; reviewers webby | #1788 | done | 268 done, 282 done | Webby approves the manifest. The library and business suites are green on Sage's gate, along with every scripts/test-*.sh. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-01d supporting folders, the supporting scope, the editor field and supportingPath (M12) | LANDED 8d2856ee3 (replay of 0bf308dba onto 59226f878, 13 patch-ids equal) plus DEFERRED N1 93694c518. Webby APPROVE r1 c31338 rev 3677, r2 c31342 rev 3683 (mos-1528 G1 mapping.test:52). Sage full gate GREEN 20:37:16Z: all package suites but queue plus every scripts/test-*.sh, 0 fail, library 98/0, webui npm ci, editor build required. supporting.test first-run red placed (mos-1272, 54d9e07bb). #1788 closed c31358. Live unchanged 45dca69f6. |
|
||||
| 284 | Case 2 C2-05c the supporting scope and blob in the lookups | della; reviewers webby | #1789 | done | 224 done, 283 done | Dewey approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate. Grep packages/*/tests for the scope enum pin and ['canon', 'playground'] before in-review; update each. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05c the supporting scope and blob in the lookups (sage-2833) | LANDED ce0b6ed41 (fast-forward of Della r4 on 9e2689dff), pushed 00:09:52Z 10-25. Sage gate GREEN 00:09:04Z on ce0b6ed41: every package suite but queue (cli 999/0 + allowed FED R7 skip) and every scripts/test-*.sh rc 0. Webby APPROVE r2 c31654 rev 4070 on manifest-r4 de505cfd; landed tree matches. Della whole-file runs 51/0. #1789 closed with c31655. |
|
||||
| 284 | Case 2 C2-05c the supporting scope and blob in the lookups | della; reviewers webby | #1789 | in-review, round 1, request posted | 224 done, 283 done | Dewey approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate. Grep packages/*/tests for the scope enum pin and ['canon', 'playground'] before in-review; update each. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05c the supporting scope and blob in the lookups (sage-2833) | — |
|
||||
| 285 | Case 2 C2-08b role changes for agent writes and the chief's read grant | magica; reviewers poe, webby | #1790 | done | 213 done, 291 done | Webby approves the manifest. Business suite, test-config.sh and every scripts/test-*.sh green on Sage's gate. Grep for CREATIVE_KINDS and 64-hex pins of changed role files. Sage checks it against mos-1309 item 5. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-08b role changes for agent writes and the chief's read grant (mos-1309 item 5) | LANDED 1f3d0350f 13:33:42Z: candidate 2e4503dc7 (14 commits) cherry-picked onto 25874bc86. Logs kept both sides; otherwise the tree equals the candidate except on 7 base paths. Poe c31568 rev 3919, Webby c31569 rev 3920. Sage gate GREEN 13:28:46Z with its own npm ci: 4236 package tests, 0 fail, 1 allowed FED R7 skip; 12 scripts rc 0. No CREATIVE_KINDS, no role-file hash pins. Roles match mos-1309 item 5. 286 rebases as r5. |
|
||||
| 286 | Case 2 C2-03b push and per-seat credentials for the library mirror (with R4, mos-1323) | rockerduck; reviewers boyd, dewey | #1791 | done | 222 done | Dewey approves the manifest. Library and bus suites and every scripts/test-*.sh green on Sage's gate, mutant killed. A search of the run output for the fixture token finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-03b push and per-seat credentials for the library mirror | LANDED 5d7801dc1 14:37:02Z: r6 75f6d56b1 (19 commits) picked onto d55944edb; logs kept both sides, code equals the candidate. Boyd c31587 rev 3942, Dewey c31588 rev 3943 (r2 c31584/c31585). Sage gate GREEN 14:36:42Z, own npm ci: 4251 tests, 0 fail, 1 allowed FED R7 skip; 12 scripts rc 0; fixture values in 0 of 29 outputs; B285-M1 kills T7/T9. r6 shortened two fixtures after push-check STOP secrets (sage-4112). Chief seed per sage-4100. |
|
||||
| 287 | Case 2 C2-21 the grant executor for a library project | steelbeak; reviewers boyd, dewey | #1792 | done | 226 done, 285 done | Dewey approves the manifest. Bus suite, Gitea Docker test, install test and every scripts/test-*.sh green on Sage's gate. A search of the run output for the fixture admin and seat tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-21 the grant executor for a library project | LANDED 0e935776e 16:12:35Z 10-24 (cand c2338ed58 + a5370b198 on 9b6345466). Boyd APPROVE c31602 rev 3967, Dewey APPROVE c31603 rev 3968. Sage gate GREEN 16:11:38Z: bus 998/0 (Gitea Docker F-A/F-B + X-G3, minted 4 hits 0), business 283/0, cli 989 +1 allowed FED R7 skip, webui 442/0, 12 scripts rc 0. F-C negative record-only follow-up. Dewey N1-N3 non-blocking. #1792 closed c31606. No P19 task. |
|
||||
| 288 | Case 2 C2-02 agent writes, the notice, revert and her Console saves | bubba; reviewers webby | #1793 | in-progress | 215 done, 282 done, 283 done, 284 done, 285 done, 286 done | Webby approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate, mutants killed. A search of the run output for the fixture tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-02 agent writes, the notice, revert and her Console saves | A2 revert contract (morgana-0199, sage-3596): library.revert is a human verb. Args {project, commit}, strict keys; project is the business.projects key (the chat repo link), not a UUID. Result {project, path, reverted, commit}. Refusals: 409 stale-base, and 409 library-revert-not-agent for an agent caller. Owner Bubba under Q245 (mos-1506). |
|
||||
| 288 | Case 2 C2-02 agent writes, the notice, revert and her Console saves | bubba; reviewers webby | #1793 | briefed | 215 done, 282 done, 283 done, 284 done, 285 done, 286 done | Webby approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate, mutants killed. A search of the run output for the fixture tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-02 agent writes, the notice, revert and her Console saves | A2 revert contract (morgana-0199, sage-3596): library.revert is a human verb. Args {project, commit}, strict keys; project is the business.projects key (the chat repo link), not a UUID. Result {project, path, reverted, commit}. Refusals: 409 stale-base, and 409 library-revert-not-agent for an agent caller. Owner Bubba under Q245 (mos-1506). |
|
||||
| 289 | Case 2 C2-11b Console library pages and her saves (Haiku subagent, decision 129) | researcher; reviewers filbert | #1794 | briefed | 214 done, 288 done | Filbert approves the manifest. The webui suite and every scripts/test-*.sh are green on Sage's gate. Grep for hash pins on bus.js and serve.mjs before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-11b Console library pages and her saves | — |
|
||||
| 290 | Case 2 C2-12b the setup sheet rewrite for free chat, supporting folders and saves | louie; reviewers webby | #1795 | done | 217 done, 218 done, 285 done, 291 done | Doc only. Webby approves it against the ruling. Before landing, grep packages/*/tests and scripts/test-*.sh to confirm no test reads the file. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-12b the setup sheet rewrite for free chat, supporting folders and saves | LANDED 3d7dff345 on refactor, pushed 14:55:11Z: cherry-pick of 963303403..22510988d onto 18334d713, four commits equal by patch-id and range-diff, SETUP-SHEET.md blob 37b451c6 as approved. Gate per brief (doc only): Webby approve c31596 rev 3954; grep of packages/*/tests, scripts/test-*.sh and tests/ for SETUP-SHEET finds nothing (positive control hits). No suite run: no test reads the file (decision 137). #1795 closed c31597. |
|
||||
| 291 | PRD 1.16 library.write routes under REQ-LIB-6 (mos-1328) | gosalyn; reviewers webby | #1796 | done | 282 done | Webby approves the text. Jason says yes to the exact text (Mos asks him, mos-1328 step 3); no landing before that. requirements.test.mjs and every scripts/test-*.sh that reads the PRD or requirements.json are green on Sage's gate. Mos gets the landing commit. (sage) | `docs/plans/2026-10-22_prd-1-16-brief.md` § PRD 1.16 library.write routes under REQ-LIB-6 (mos-1328) | Landed 4874d1e83 on e909ef51a: 482e865ac replayed, patch-id equal (cef7de74), range-diff =. Webby APPROVE c30848 on 482e865ac; Jason approved the text in Q229. Gate 16:15Z on the tip tree: every package suite but queue, 0 fail 0 skipped (tasks 100, bus 891, cli 941, plugins 119, webui 392, business 231), every scripts/test-*.sh rc 0 (queue-root and row 244 skips only). PRD 1.16. 1.17 is row 308. |
|
||||
@@ -366,11 +366,11 @@ Generated from `docs/plans/queue.json` revision 4095 by `queue render`. Do not e
|
||||
| 327 | Push check in the repository: scripts/push-check.sh passes a binary only when an approved review candidate lists its path and sha256, plus scripts/test-push-check.sh (#1825, mos-1572 A) | bradford; reviewers dewey, poe | #1825 | done | — | Poe gives the first Codex review, Dewey reviews the landing candidate; scripts/test-push-check.sh and every other scripts/test-*.sh green on Sage's gate; the mutants killed; Sage's next push runs through scripts/push-check.sh (sage) | `docs/plans/2026-10-24_push-guard-binary-manifest.md` § Brief: push-check.sh passes a binary only when the reviewed candidate lists its path and sha256 | LANDED 68c08b4e7 (pushed 07:18:03Z 10-24): 3 commits on 6a5e12511, blobs equal round 3 d858c9f8b; Poe c31525 rev 3882, Dewey c31526 rev 3883; gate GREEN 07:15:49Z with its own npm ci (first run red on empty canonical node_modules, sage-4023); 6 push-check mutants KILLED; next push 42ba0f5bc ran through scripts/push-check.sh --fetch, PUSH_READY; #1825 closed c31530. |
|
||||
| 328 | T9 library-credential test: the second broker start passes Node's TIMEOUT_MAX interval so no timer tick overlaps the verb sync; mutant fails a 50-run stress loop (#1826, Vikunja 622, mos-1594) | fethry; reviewers boyd, dewey | #1826 | done | — | Boyd gives the first Codex review, Dewey reviews the landing candidate; touched tests run whole, the 50-run stress loop passes with the fix and M1 fails it; bus and every scripts/test-*.sh green on Sage's gate (sage) | `docs/plans/2026-10-24_t9-library-sync-race.md` § Brief: the T9 verb sync on the second start runs with no timer tick able to overlap it | LANDED 8bb5b3c73 19:40Z 10-24 (8 Fethry commits on 5e77cdd09). Gate GREEN 19:38:54Z on 8bb5b3c73, no drift. Boyd APPROVE c31621, Dewey APPROVE c31622. #1826 closed c31625; Vikunja 622 done. |
|
||||
| 329 | Model proxy P1: model-proxy package, pinned fetch with sha256 refusal, mosaic proxy init, proxy unit (237, mos-1600) | magica; reviewers boyd, dewey | #1827 | done | — | Boyd first review, re-measuring both release hashes; Dewey landing review; BUILD.md has the acceptance output. Sage's landing gate: every package suite but queue plus every scripts/test-*.sh green, touched test files whole, refusals each tested, named mutants killed (brief Gate). (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P1 the model-proxy package, pinned fetch, proxy init and the proxy unit | Landed 61ebf2c34 (pushed 23:31:27Z 10-24); Magica r2 commits cherry-picked onto 669cdf42c. Boyd c31642 rev 4048, Dewey c31643 rev 4047. Sage fresh gate GREEN 23:29:14Z (mos-1634). #1827 closed c31650; Vikunja 237 comment 1109, stays open for P2-P7. DEFERRED: N2, R2-N1 to row 331; N1 to P7. |
|
||||
| 330 | Model proxy P4: Console proxy page (OAuth sign-in, API keys, priority, key list, usage) via bus verbs (Q250, mos-1606/1608) | poe; reviewers filbert, gladstone | #1828 | in-progress | — | Gladstone first review; Filbert landing review; starts now, lands after P1 rebased on it; webui with MOSAIC_REQUIRE_EDITOR_BUILD=1. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_proxy-page-brief.md` § Brief: P4 the Console proxy page | — |
|
||||
| 331 | Model proxy P2: per-agent model keys, reconcile and launch preflight (237, mos-1600) | magica; reviewers boyd, dewey | #1829 | in-progress | 329 done | Boyd first review; Dewey landing review; three named mutants killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P2 per-agent model keys, reconcile and the launch preflight | P2 input from magica-0020 (acceptance-probe-4): 8.0.42 revocation lags ~105ms after v8 PUT (first call 200, then 401); reconcile/revoke must poll to 401, not assume instant. Per-key model objects give 422; no per-key model restriction. |
|
||||
| 330 | Model proxy P4: Console proxy page (OAuth sign-in, API keys, priority, key list, usage) via bus verbs (Q250, mos-1606/1608) | poe; reviewers filbert, gladstone | #1828 | briefed | — | Gladstone first review; Filbert landing review; starts now, lands after P1 rebased on it; webui with MOSAIC_REQUIRE_EDITOR_BUILD=1. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_proxy-page-brief.md` § Brief: P4 the Console proxy page | — |
|
||||
| 331 | Model proxy P2: per-agent model keys, reconcile and launch preflight (237, mos-1600) | sage; reviewers boyd, dewey | #1829 | briefed | 329 done | Boyd first review; Dewey landing review; three named mutants killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P2 per-agent model keys, reconcile and the launch preflight | P2 input from magica-0020 (acceptance-probe-4): 8.0.42 revocation lags ~105ms after v8 PUT (first call 200, then 401); reconcile/revoke must poll to 401, not assume instant. Per-key model objects give 422; no per-key model restriction. |
|
||||
| 332 | Model proxy P3: harness config from the proxy (237, mos-1600) | fethry; reviewers dewey, gladstone | #1830 | in-progress | — | Gladstone first review; Dewey landing review; named mutant killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P3 harness config from the proxy | mos-1616: amendment docs/plans/2026-10-24_p3-pi-routes-amendment.md (blob 079debd5605c, c8a9bcf94) replaces P3 item 4's non-Anthropic line and adds tests and a mutant. Starts now on a new Codex thread against P2's {baseUrl, key}; lands only after 329 and 331 land and its own gate (mos-1351). |
|
||||
| 333 | Model proxy P5: usage plug-in and per-key limits, per-key count only (237, mos-1600) | sage; reviewers boyd, duckworth | #1831 | briefed | 331 done | Boyd first review; Dewey landing review; named mutant killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P5 usage plug-in and per-key limits | — |
|
||||
| 334 | Case 2 proxy unit: case2-unit.sh renders P1's mosaic-proxy.service and the bus Wants/After under --proxy (237, mos-1616) | rockerduck; reviewers boyd, webby | #1832 | in-progress | 329 done | Codex builder after 329 lands; Boyd first review, Webby Claude review; run list from imports, case1-accept off; mutants: bus loses After= under --proxy, proxy ExecStart skips run.mjs; Sage landing gate: every package suite but queue, every scripts/test-*.sh (sage) | `docs/plans/2026-10-24_case2-proxy-unit-brief.md` § Brief: Case 2 proxy unit in case2-unit.sh and case2-install.sh | — |
|
||||
| 334 | Case 2 proxy unit: case2-unit.sh renders P1's mosaic-proxy.service and the bus Wants/After under --proxy (237, mos-1616) | sage; reviewers boyd, webby | #1832 | queued | 329 done | Codex builder after 329 lands; Boyd first review, Webby Claude review; run list from imports, case1-accept off; mutants: bus loses After= under --proxy, proxy ExecStart skips run.mjs; Sage landing gate: every package suite but queue, every scripts/test-*.sh (sage) | `docs/plans/2026-10-24_case2-proxy-unit-brief.md` § Brief: Case 2 proxy unit in case2-unit.sh and case2-install.sh | — |
|
||||
|
||||
<!-- mosaic-queue:end -->
|
||||
|
||||
|
||||
+46
-971
File diff suppressed because it is too large.
Load diff
@@ -105,7 +105,7 @@ export const PROJECT_FILE_VERBS = Object.freeze(['project.files', 'project.file'
|
||||
// here also makes server.mjs await their host effects instead of serializing a Promise as {}.
|
||||
const LIBRARY_LOOKUPS = Object.freeze({
|
||||
'library.find': { method: 'find', fields: ['universe', 'query', 'type', 'book', 'scope', 'offset'], required: ['universe', 'query'] },
|
||||
'library.get': { method: 'get', fields: ['universe', 'path', 'scope', 'from', 'links_from'], required: ['universe', 'path'] },
|
||||
'library.get': { method: 'get', fields: ['universe', 'path', 'from', 'links_from'], required: ['universe', 'path'] },
|
||||
'library.search': { method: 'search', fields: ['universe', 'text', 'book', 'scope', 'offset'], required: ['universe', 'text'] },
|
||||
'library.manuscript': { method: 'manuscript', fields: ['universe', 'book', 'scope', 'chapter', 'from', 'to'], required: ['universe', 'book'] },
|
||||
'library.universe': { method: 'universeInfo', fields: ['universe'], required: ['universe'] },
|
||||
|
||||
@@ -27,8 +27,8 @@ const TEXTS = {
|
||||
'Second World/Characters/Elsewhere.md': note('character', 'Elsewhere', 'Other ferry.'),
|
||||
};
|
||||
|
||||
async function world(t, { projects, adapter, claimed = true, now = () => NOW, files = TEXTS } = {}) {
|
||||
const f = scratchRepo(t, files), dataRoot = join(f.root, 'data');
|
||||
async function world(t, { projects, adapter, claimed = true, now = () => NOW } = {}) {
|
||||
const f = scratchRepo(t, TEXTS), dataRoot = join(f.root, 'data');
|
||||
mkdirSync(dataRoot);
|
||||
const business = { id: 'acme', human: 'jason', vars: { 'bus.tester': true },
|
||||
projects: projects ?? { books: mappingEntry() }, arbiters: { technical: 'coder', delivery: 'coder' },
|
||||
@@ -235,19 +235,3 @@ test('runtime actually injects the lookup adapter, without exposing human librar
|
||||
await assert.rejects(runtime.broker.request(cap, { verb: 'library.file', args: { project: 'books', path: GET.path } }),
|
||||
{ code: 'human-required' });
|
||||
});
|
||||
|
||||
test('C2-05c broker forwards supporting scope and returns the served blob without adding write verbs', async t => {
|
||||
const projects = { books: mappingEntry() };
|
||||
projects.books.universes.harbor.supporting = ['Book One/Support/'];
|
||||
const path = 'Book One/Support/Helper.md';
|
||||
const f = await world(t, { projects, files: { ...TEXTS, [path]: note('summary', 'Helper', 'Supporting fixture.') } });
|
||||
assert.deepEqual((await f.call('library.find', { universe: 'harbor', query: '', scope: 'supporting' })).results.map(x => x.path), [path]);
|
||||
assert.deepEqual((await f.call('library.search', { universe: 'harbor', text: 'Supporting fixture', scope: 'supporting' })).results.map(x => x.path), [path]);
|
||||
assert.equal(await f.call('library.get', { universe: 'harbor', path }), null);
|
||||
const result = await f.call('library.get', { universe: 'harbor', path, scope: 'supporting' });
|
||||
assert.equal(result.scope, 'supporting');
|
||||
assert.equal(result.commit, f.commit);
|
||||
assert.equal(result.blob, git(f.mirror, 'rev-parse', `${f.commit}:${path}`));
|
||||
assert.equal(await f.call('library.get', { universe: 'second', path, scope: 'supporting' }), null);
|
||||
await assert.rejects(f.call('library.manuscript', { universe: 'harbor', book: 'Book One', scope: 'supporting' }), { code: 'query-argument-invalid' });
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
// REQ-LIMIT-1: editable concurrency policy, never a compiled-in capacity ceiling.
|
||||
import { requireObject, requireId, requireString, rejectUnknownKeys } from "./util.mjs";
|
||||
import { refuse } from "./errors.mjs";
|
||||
import { BusinessError, refuse } from "./errors.mjs";
|
||||
|
||||
const name = (value, at) => requireString(value, at, { max: 200 });
|
||||
const count = (value, at) => {
|
||||
@@ -15,10 +15,19 @@ export function checkModels(value, where = "launch.models") {
|
||||
return Object.fromEntries(Object.entries(value).map(([key, entry]) => {
|
||||
requireId(key, where);
|
||||
requireObject(entry, `${where}.${key}`);
|
||||
rejectUnknownKeys(entry, ["provider", "model"], `${where}.${key}`);
|
||||
rejectUnknownKeys(entry, entry.provider === "proxy" ? ["provider", "model", "route"] : ["provider", "model"], `${where}.${key}`);
|
||||
if (entry.provider === "proxy") {
|
||||
const missing = !Object.hasOwn(entry, "route");
|
||||
if (missing || !["anthropic", "glm", "codex"].includes(entry.route)) {
|
||||
throw Object.assign(new BusinessError(`${where}.${key}.route must name anthropic, glm or codex`), {
|
||||
code: missing ? "proxy-route-missing" : "proxy-route-unknown",
|
||||
});
|
||||
}
|
||||
}
|
||||
return [key, {
|
||||
provider: name(entry.provider, `${where}.${key}.provider`),
|
||||
model: name(entry.model, `${where}.${key}.model`),
|
||||
...(entry.provider === "proxy" && Object.hasOwn(entry, "route") ? { route: entry.route } : {}),
|
||||
}];
|
||||
}));
|
||||
}
|
||||
@@ -82,7 +91,7 @@ export function checkAccount(value, where = "launch.account") {
|
||||
requireObject(value, where);
|
||||
rejectUnknownKeys(value, ["name", "credential"], where);
|
||||
const accountName = requireId(value.name, `${where}.name`);
|
||||
if (typeof value.credential !== "string" || !CREDENTIAL.test(value.credential)) {
|
||||
if (typeof value.credential !== "string" || (value.credential !== "proxy" && !CREDENTIAL.test(value.credential))) {
|
||||
refuse(`${where}.credential must name environment variables, joined with "+"`);
|
||||
}
|
||||
return { name: accountName, credential: value.credential };
|
||||
|
||||
@@ -38,11 +38,11 @@ test('REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery
|
||||
test('REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent',async()=>{
|
||||
const {migrateLaunch}=await import('../src/migrate-launch.mjs');const f=fixture(),old=structuredClone(f.doc);old.roles.pm.vars.model='claude-opus-5-5';for(const [name,r] of Object.entries(old.roles))if(name!=='pm')r.vars.model='claude-sonnet-5-5';old.launch={by:'chief',instances:['coder','reviewer'],max:{opus:4,sonnet:4}};writeJson(f.file,old);const bytes=readFileSync(f.file,'utf8'),mtime=statSync(f.file).mtimeMs;
|
||||
const mapping={models:f.doc.launch.models,families:{opus:'opus',sonnet:'sonnet'}};const next=migrateLaunch(old,mapping,f.file,{rolesDir:f.rolesDir});assert.deepEqual(next.launch.limits, f.doc.launch.limits);assert.equal(next.roles.pm.vars.model,'opus');assert.equal(next.roles.coder.vars.model,'sonnet');assert.deepEqual(migrateLaunch(next,mapping,f.file,{rolesDir:f.rolesDir}),next);
|
||||
assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'missing',sonnet:'sonnet'}},f.file,{rolesDir:f.rolesDir}));assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.throws(()=>migrateLaunch(old,{...mapping,models:{...mapping.models,proxy:{provider:'proxy',model:'claude-opus-5-5'}},instances:{pm:'proxy'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);const onlyOpus=structuredClone(old);onlyOpus.launch.max={opus:4};assert.throws(()=>migrateLaunch(onlyOpus,mapping,f.file,{rolesDir:f.rolesDir}),/unknown or ambiguous/);const allOpus=structuredClone(old);for(const r of Object.values(allOpus.roles))r.vars.model='claude-opus-5-5';assert.throws(()=>migrateLaunch(allOpus,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.equal(readFileSync(f.file,'utf8'),bytes);assert.equal(statSync(f.file).mtimeMs,mtime);
|
||||
assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'missing',sonnet:'sonnet'}},f.file,{rolesDir:f.rolesDir}));assert.throws(()=>migrateLaunch(old,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.throws(()=>migrateLaunch(old,{...mapping,models:{...mapping.models,proxy:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}},instances:{pm:'proxy'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);const onlyOpus=structuredClone(old);onlyOpus.launch.max={opus:4};assert.throws(()=>migrateLaunch(onlyOpus,mapping,f.file,{rolesDir:f.rolesDir}),/unknown or ambiguous/);const allOpus=structuredClone(old);for(const r of Object.values(allOpus.roles))r.vars.model='claude-opus-5-5';assert.throws(()=>migrateLaunch(allOpus,{...mapping,families:{opus:'opus',sonnet:'opus'}},f.file,{rolesDir:f.rolesDir}),/ambiguous/);assert.equal(readFileSync(f.file,'utf8'),bytes);assert.equal(statSync(f.file).mtimeMs,mtime);
|
||||
});
|
||||
test('REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor',async()=>{
|
||||
const {launchSettings}=await import('../src/launch-settings.mjs');const f=fixture(),system={environment:'development',dataRoot:join(f.root,'data'),'execution.backend':'docker','execution.provider':'anthropic','execution.model':'sonnet','execution.adapter':'pi'};const settings=launchSettings({dir:f.root,rolesDir:f.rolesDir,system,sessions:()=>[{business:'acme',provider:'anthropic',model:'claude-opus-5-5'}]});const view=settings.read('acme');assert.equal(view.usage.total,1);assert.equal(view.instances.pm.modelKey,'opus');
|
||||
const result=settings.set('acme',{revision:view.revision,limits:{total:0},instances:{coder:'opus'}},'jason');assert.equal(result.limits.total,0);assert.equal(result.instances.coder.modelKey,'opus');const models=structuredClone(result.models);models.opus.provider='proxy';const updated=settings.set('acme',{revision:result.revision,models},'jason');assert.equal(updated.instances.pm.provider,'proxy');assert.throws(()=>settings.set('acme',{revision:result.revision,instances:{coder:'ghost'}},'jason'));assert.throws(()=>settings.set('acme',{revision:result.revision,roles:{}},'jason'));
|
||||
const result=settings.set('acme',{revision:view.revision,limits:{total:0},instances:{coder:'opus'}},'jason');assert.equal(result.limits.total,0);assert.equal(result.instances.coder.modelKey,'opus');const models=structuredClone(result.models);models.opus.provider='proxy';models.opus.route='anthropic';const updated=settings.set('acme',{revision:result.revision,models},'jason');assert.equal(updated.instances.pm.provider,'proxy');assert.throws(()=>settings.set('acme',{revision:result.revision,instances:{coder:'ghost'}},'jason'));assert.throws(()=>settings.set('acme',{revision:result.revision,roles:{}},'jason'));
|
||||
});
|
||||
test('REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts',async()=>{
|
||||
const {limitHit}=await import('../src/launch.mjs');const {sessionModel}=await import('../../harness/src/bundle.mjs');
|
||||
@@ -151,14 +151,14 @@ test('B7 kept instance: the models keys it names and the instances key are the h
|
||||
const chief='chief-of-staff.chief';let {revision}=settings.read('acme');
|
||||
const models=structuredClone(settings.read('acme').models);
|
||||
const key=doc.roles.coder.vars.model;
|
||||
const moved={...models,[key]:{provider:'proxy',model:'claude-sonnet-5-5'}};
|
||||
const moved={...models,[key]:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
for(const actor of [chief,'tester']){
|
||||
const bytes=file();
|
||||
assert.throws(()=>settings.set('acme',{revision,models:moved},actor),code('instance-kept'),actor);
|
||||
assert.throws(()=>settings.set('acme',{revision,instances:{coder:'opus'}},actor),code('instance-kept'),actor);
|
||||
assert.equal(file(),bytes,actor);
|
||||
}
|
||||
({revision}=settings.set('acme',{revision,models:{...models,spare:{provider:'proxy',model:'claude-opus-5-5'}}},chief));
|
||||
({revision}=settings.set('acme',{revision,models:{...models,spare:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
({revision}=settings.set('acme',{revision,models:{...settings.read('acme').models,[key]:moved[key]}},'jason'));
|
||||
settings.set('acme',{revision,instances:{coder:'opus'}},'jason');
|
||||
assert.equal(JSON.parse(file()).roles.coder.vars.model,'opus');
|
||||
@@ -185,7 +185,7 @@ test('M10 creative instance: models keys it names, the instances key and its rou
|
||||
const g={...f,doc};const {settings}=await routeSettings(g);const file=()=>readFileSync(f.file,'utf8');
|
||||
const chief='chief-of-staff.chief';let {revision}=settings.read('acme');
|
||||
const models=structuredClone(settings.read('acme').models);
|
||||
const sonnet={...models,sonnet:{provider:'proxy',model:'claude-sonnet-5-5'}};
|
||||
const sonnet={...models,sonnet:{provider:'proxy',route:'anthropic',model:'claude-sonnet-5-5'}};
|
||||
for(const actor of [chief,'tester']){
|
||||
const bytes=file();
|
||||
assert.throws(()=>settings.set('acme',{revision,models:sonnet},actor),code('organization-creative-human-only'),actor);
|
||||
@@ -195,7 +195,7 @@ test('M10 creative instance: models keys it names, the instances key and its rou
|
||||
assert.equal(file(),bytes,actor);
|
||||
}
|
||||
// A key no creative instance names stays the chief's.
|
||||
({revision}=settings.set('acme',{revision,models:{...models,opus:{provider:'proxy',model:'claude-opus-5-5'}}},chief));
|
||||
({revision}=settings.set('acme',{revision,models:{...models,opus:{provider:'proxy',route:'anthropic',model:'claude-opus-5-5'}}},chief));
|
||||
assert.throws(()=>settings.set('acme',{revision,instances:{bean:'opus'}},'jason'),code('organization-creative-instance'));
|
||||
({revision}=settings.set('acme',{revision,models:sonnet},'jason'));
|
||||
({revision}=settings.setRoutes('acme',{revision,routes:{bean:{harness:'pi',model:'sonnet',thinking:'high',fallback:{harness:'pi',model:'opus',thinking:'low'}}}},'jason'));
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// P3: the proxy account is a declared credential source, never a secret value.
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { checkAccount, checkModels } from '../src/launch.mjs';
|
||||
|
||||
test('P3 proxy model validation preserves each explicit wire route and the proxy model id', () => {
|
||||
for (const route of ['anthropic', 'glm', 'codex']) {
|
||||
const models = { selected: { provider: 'proxy', model: 'proxy-only-id', route } };
|
||||
assert.deepEqual(checkModels(models), models, route);
|
||||
}
|
||||
});
|
||||
|
||||
test('P3 a proxy model without route refuses proxy-route-missing', () => {
|
||||
assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id' } }), {
|
||||
code: 'proxy-route-missing',
|
||||
});
|
||||
});
|
||||
|
||||
test('P3 an unknown proxy route refuses proxy-route-unknown', () => {
|
||||
for (const route of ['openai-codex', 'unknown', '', null, 7]) {
|
||||
assert.throws(() => checkModels({ selected: { provider: 'proxy', model: 'proxy-only-id', route } }), {
|
||||
code: 'proxy-route-unknown',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('P3 nonproxy models retain their provider/model-only shape and reject route metadata', () => {
|
||||
assert.deepEqual(checkModels({ selected: { provider: 'zai', model: 'glm-fixture' } }), {
|
||||
selected: { provider: 'zai', model: 'glm-fixture' },
|
||||
});
|
||||
assert.throws(() => checkModels({ selected: { provider: 'zai', model: 'glm-fixture', route: 'glm' } }), /unsupported/);
|
||||
});
|
||||
|
||||
test('P3 launch.account accepts the proxy credential source without naming host variables', () => {
|
||||
assert.deepEqual(checkAccount({ name: 'proxy', credential: 'proxy' }), { name: 'proxy', credential: 'proxy' });
|
||||
});
|
||||
|
||||
test('P3 existing environment-set accounts retain their validated representation', () => {
|
||||
for (const credential of ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN+ANTHROPIC_BASE_URL']) {
|
||||
assert.deepEqual(checkAccount({ name: 'max', credential }), { name: 'max', credential });
|
||||
}
|
||||
for (const credential of ['', 'fx332-fake', 'proxy+ANTHROPIC_API_KEY', 'PROXY+proxy']) {
|
||||
assert.throws(() => checkAccount({ name: 'proxy', credential }), /launch\.account\.credential/);
|
||||
}
|
||||
});
|
||||
@@ -157,6 +157,7 @@ import {
|
||||
runnerOf,
|
||||
SESSION_CREDENTIALS,
|
||||
sessionEnv,
|
||||
isProviderVariable,
|
||||
sessionExit,
|
||||
sessionStore,
|
||||
sessionWorkspace,
|
||||
@@ -216,6 +217,9 @@ export function createLauncher({
|
||||
host,
|
||||
system,
|
||||
env = process.env,
|
||||
// P2 supplies only {baseUrl,key}; a factory may supply the current agent's
|
||||
// context per check. P3 never reads a key store or calls the proxy itself.
|
||||
proxy = null,
|
||||
tracker = false,
|
||||
launches = true,
|
||||
makeLoader = createLoader,
|
||||
@@ -388,7 +392,18 @@ export function createLauncher({
|
||||
let harness = await harnessOf(primary);
|
||||
let route = "primary";
|
||||
let routeReason = null;
|
||||
const failed = call(primary.harness, "preflight", () => harness.preflight({ env }));
|
||||
const proxyFor = async (selected) => {
|
||||
if (selected.provider !== "proxy") return null;
|
||||
const context = typeof proxy === "function" ? await proxy({ business: b.id, instance }) : proxy;
|
||||
if (!context || typeof context.key !== "string" || !context.key
|
||||
|| typeof context.baseUrl !== "string" || !/^http:\/\/127\.0\.0\.1:[0-9]+$/.test(context.baseUrl)) {
|
||||
throw new Refusal("no-session-credential", "proxy model needs its own session proxy context");
|
||||
}
|
||||
// Copy only the agreed seam; never keep a store or management handle.
|
||||
return { baseUrl: context.baseUrl, key: context.key };
|
||||
};
|
||||
let sessionProxy = await proxyFor(primary);
|
||||
const failed = call(primary.harness, "preflight", () => harness.preflight({ env: sessionProxy ? sessionEnv(env, "preflight", sessionProxy) : env, proxy: sessionProxy }));
|
||||
if (failed) {
|
||||
if (!fallback) throw new Refusal(failed.code, failed.message);
|
||||
// The fallback only on a failed primary preflight, and only at launch (row 65). Any refusal of
|
||||
@@ -397,7 +412,8 @@ export function createLauncher({
|
||||
if (e instanceof Refusal) e.message += ` (primary ${primary.harness}: ${failed.message})`;
|
||||
throw e;
|
||||
});
|
||||
const also = call(fallback.harness, "preflight", () => second.preflight({ env }));
|
||||
sessionProxy = await proxyFor(fallback);
|
||||
const also = call(fallback.harness, "preflight", () => second.preflight({ env: sessionProxy ? sessionEnv(env, "preflight", sessionProxy) : env, proxy: sessionProxy }));
|
||||
if (also) throw new Refusal(also.code, `fallback ${fallback.harness}: ${also.message} (primary ${primary.harness}: ${failed.message})`);
|
||||
[model, harness, route, routeReason] = [fallback, second, "fallback", failed.code];
|
||||
}
|
||||
@@ -408,12 +424,18 @@ export function createLauncher({
|
||||
if (account !== null) {
|
||||
// The usage records keep this name (bus schema 3i), so it must never be a credential's value.
|
||||
const holds = [...new Set(SESSION_CREDENTIALS.flat())].filter((k) => env[k] === account);
|
||||
if (sessionProxy?.key === account) holds.push("session proxy key");
|
||||
if (holds.length) throw new Refusal("account-is-credential", `launch.account.name is the value of ${holds.join(", ")}; it names the account, never its credential`);
|
||||
const named = b.launch.account.credential.split("+");
|
||||
if (!SESSION_CREDENTIALS.some((set) => set.join("+") === named.join("+")) || !named.every((k) => Boolean(env[k])))
|
||||
throw new Refusal("account-credential-missing", `account ${account} names ${named.join(" with ")}, which the bus host doesn't hold as a session login`);
|
||||
const other = [...new Set(SESSION_CREDENTIALS.flat())].filter((k) => !named.includes(k) && Boolean(env[k]));
|
||||
if (other.length) throw new Refusal("account-credential-ambiguous", `account ${account} names ${named.join(" with ")}, but the bus host also sets ${other.join(", ")}`);
|
||||
if (sessionProxy || b.launch.account.credential === "proxy") {
|
||||
if (!sessionProxy || b.launch.account.credential !== "proxy")
|
||||
throw new Refusal("account-credential-missing", `account ${account} needs the declared proxy credential`);
|
||||
} else {
|
||||
const named = b.launch.account.credential.split("+");
|
||||
if (!SESSION_CREDENTIALS.some((set) => set.join("+") === named.join("+")) || !named.every((k) => Boolean(env[k])))
|
||||
throw new Refusal("account-credential-missing", `account ${account} names ${named.join(" with ")}, which the bus host doesn't hold as a session login`);
|
||||
const other = [...new Set(SESSION_CREDENTIALS.flat())].filter((k) => !named.includes(k) && Boolean(env[k]));
|
||||
if (other.length) throw new Refusal("account-credential-ambiguous", `account ${account} names ${named.join(" with ")}, but the bus host also sets ${other.join(", ")}`);
|
||||
}
|
||||
}
|
||||
const unavailable = sandboxProblem({ bwrap });
|
||||
if (unavailable) throw new Refusal("sandbox-unavailable", unavailable);
|
||||
@@ -432,7 +454,7 @@ export function createLauncher({
|
||||
throw new Refusal("limit-check-failed", `${may?.check ?? "bus"}: ${may?.code ?? "malformed-answer"}`);
|
||||
}
|
||||
admission(admissionGeneration);
|
||||
return { resolved, model, account, harness, route, routeReason, admissionGeneration };
|
||||
return { resolved, model, account, harness, route, routeReason, admissionGeneration, sessionProxy };
|
||||
}
|
||||
|
||||
// Bundle, spawn, bind, register, hand over the capability.
|
||||
@@ -503,8 +525,8 @@ export function createLauncher({
|
||||
if (c.outcome === "kept") record({ event: "checkout-kept", instance, project: c.project, reason: c.reason });
|
||||
else if (c.outcome === "fetched") record({ event: "checkout-fetched", instance, project: c.project, reason: c.reason });
|
||||
}
|
||||
let harness, route, routeReason;
|
||||
({resolved,model,account,harness,route,routeReason}=await check(instance,{pm:instance===b.launch.by,thread,session,human}));
|
||||
let harness, route, routeReason, sessionProxy;
|
||||
({resolved,model,account,harness,route,routeReason,sessionProxy}=await check(instance,{pm:instance===b.launch.by,thread,session,human}));
|
||||
admission(admissionGeneration);
|
||||
const { run, runDir } = newRun(dataRoot, b.id);
|
||||
const sessionDir = store ? store.session : join(runDir, "session");
|
||||
@@ -525,6 +547,7 @@ export function createLauncher({
|
||||
dir: join(runDir, "bundle"),
|
||||
resolved,
|
||||
models: b.launch.models,
|
||||
proxy: sessionProxy,
|
||||
contract: readFileSync(resolved.contract, "utf8"),
|
||||
arbiter: Object.values(b.arbiters).includes(instance),
|
||||
tracker,
|
||||
@@ -548,6 +571,12 @@ export function createLauncher({
|
||||
// Row 199 (D11): or publishes it, once a reviewed commit routes git.push.remote within-role.
|
||||
const held = [...resolved.limits.authority.withinRole, ...resolved.limits.authority.crossRole];
|
||||
const git = land || ["git.push.working", "review.verdict", "git.push.remote"].some((a) => held.includes(a)) ? gitSocketPath(dataRoot) : null;
|
||||
// Secrets go only to spawn, never session.json. Keep this split at the
|
||||
// actual serialization boundary, even if a harness adds another key.
|
||||
const harnessEnv = {}, transientEnv = {};
|
||||
for (const [name, value] of Object.entries(bundle.env)) {
|
||||
(sessionProxy && isProviderVariable(name) ? transientEnv : harnessEnv)[name] = value;
|
||||
}
|
||||
writeSessionFile(runDir, {
|
||||
...sessionDefaults,
|
||||
business: b.id,
|
||||
@@ -565,7 +594,7 @@ export function createLauncher({
|
||||
sessionDir,
|
||||
adapter,
|
||||
bundle: files,
|
||||
harnessEnv: bundle.env,
|
||||
harnessEnv,
|
||||
turnEnd,
|
||||
toolSocket,
|
||||
turnMarker,
|
||||
@@ -589,7 +618,7 @@ export function createLauncher({
|
||||
try {
|
||||
admission(admissionGeneration);
|
||||
spawnedAt.set(run, Date.now());
|
||||
child = spawnSession({ runDir, env: sessionEnv(env, run), paths, business: b.id, role: instance, bwrap });
|
||||
child = spawnSession({ runDir, env: { ...sessionEnv(env, run, sessionProxy), ...transientEnv }, paths, business: b.id, role: instance, bwrap });
|
||||
} catch (e) {
|
||||
spawnedAt.delete(run);
|
||||
unregisterRuntime(dataRoot, managed.id);
|
||||
|
||||
@@ -82,6 +82,8 @@ function prepare(t, more = (doc) => doc) {
|
||||
const f = fixture(root, "acme", (doc) => more(edit(doc)));
|
||||
for (const k of SESSION_CREDENTIALS.flat()) delete f.env[k];
|
||||
f.env.CLAUDE_CODE_OAUTH_TOKEN = "stand-in";
|
||||
if (f.doc.roles.chief.vars.harness === "pi" || f.doc.roles.chief.vars["fallback.harness"] === "pi")
|
||||
f.env.ZAI_API_KEY = "fx332-pi";
|
||||
// The project root is a repository on main, so each launch can clone it.
|
||||
const project = f.doc.projects.stack.root;
|
||||
gitIn(project, "init", "-q", "-b", "main");
|
||||
@@ -145,6 +147,29 @@ function ask(path, line) {
|
||||
|
||||
const log = (f) => readFileSync(launchLogFile(f.dataRoot, "acme"), "utf8").trim().split("\n").map((l) => JSON.parse(l));
|
||||
|
||||
// Named mutant: proxy key serialized into session.json. Keep the real launcher,
|
||||
// harness env generation, session writer and runner; only the model adapter is fake.
|
||||
test('P3 proxy key reaches the spawned runner but never session.json or the bundle', { skip, timeout: 30000 }, async t => {
|
||||
const proxy = { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' };
|
||||
const prepared = prepare(t, doc => {
|
||||
doc.launch.models['claude-opus-5-5'] = { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' };
|
||||
return doc;
|
||||
});
|
||||
const { launcher, f, close } = await setup(t, doc => doc, prepared, { proxy });
|
||||
const launched = await launcher.launchPm();
|
||||
const session = readSessions(f.dataRoot).find(s => s.run === launched.run);
|
||||
assert.ok(session);
|
||||
const environ = readFileSync(`/proc/${session.runnerPid}/environ`, 'utf8').split('\0');
|
||||
assert.ok(environ.includes(`ANTHROPIC_API_KEY=${proxy.key}`));
|
||||
assert.ok(!environ.some(value => value.startsWith('CLAUDE_CODE_OAUTH_TOKEN=')));
|
||||
const stored = readFileSync(join(session.runDir, 'session.json'), 'utf8');
|
||||
assert.ok(!stored.includes(proxy.key), 'session.json must never persist the proxy key');
|
||||
const bundleFiles = readdirSync(join(session.runDir, 'bundle'), { recursive: true, withFileTypes: true })
|
||||
.filter(entry => entry.isFile()).map(entry => join(entry.parentPath, entry.name));
|
||||
for (const file of bundleFiles) assert.ok(!readFileSync(file, 'utf8').includes(proxy.key), file);
|
||||
assert.equal(await close(), 0);
|
||||
});
|
||||
|
||||
test("bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest", { skip, timeout: 30000 }, async (t) => {
|
||||
// Row 122: uncertain write receipts cannot prevent the window's first chief launch.
|
||||
const prepared = prepare(t);
|
||||
@@ -672,14 +697,15 @@ test("a Claude Code launch with no session credential refuses before it starts",
|
||||
assert.deepEqual(readdirSync(join(f.dataRoot, "launches")), ["acme.jsonl"], "no run was made");
|
||||
});
|
||||
|
||||
test("a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables", { skip, timeout: 30000 }, async (t) => {
|
||||
test("a pi launch with no own credential refuses no-session-credential", { skip, timeout: 30000 }, async (t) => {
|
||||
const given = prepare(t);
|
||||
delete given.f.env.CLAUDE_CODE_OAUTH_TOKEN;
|
||||
delete given.f.env.ZAI_API_KEY;
|
||||
assert.deepEqual(SESSION_CREDENTIALS.flat().filter((k) => k in given.f.env), []);
|
||||
const { f, launcher } = await setup(t, undefined, given);
|
||||
const chief = await launcher.launchPm();
|
||||
assert.equal(chief.harness, "pi");
|
||||
assert.deepEqual(log(f).map((e) => [e.event, e.instance]), [["launch", "chief"]]);
|
||||
await assert.rejects(launcher.launchPm(), /PM launch refused: no-session-credential/);
|
||||
assert.deepEqual(log(f).map((e) => [e.event, e.code]), [["refused", "no-session-credential"]]);
|
||||
assert.deepEqual(readSessions(f.dataRoot), []);
|
||||
});
|
||||
|
||||
// Row 65: a harness module no core file names, switched on in the organization file, runs a real
|
||||
@@ -696,6 +722,7 @@ test("row 65 a failed primary preflight launches the fallback on a fixture harne
|
||||
write("harness", "down", `export * from ${pi};\nexport const preflight = () => ({ code: "fixture-down", message: "fixture preflight fails" });\n`);
|
||||
write("harness", "fixture", `export * from ${pi};\nexport const adapter = () => ${JSON.stringify(given.adapter)};\n`);
|
||||
});
|
||||
given.f.env.ZAI_API_KEY = "fx332-pi";
|
||||
const { f, launcher } = await setup(t, undefined, given, { makeLoader });
|
||||
const chief = await launcher.launchPm();
|
||||
assert.deepEqual({ ...chief, run: undefined }, { run: undefined, instance: "chief", harness: "fixture", model: "claude-sonnet-5-5" });
|
||||
|
||||
@@ -83,7 +83,13 @@ export function sessionModel(resolved, models = null, which = "primary") {
|
||||
if (models === null) return { harness, provider: null, model, thinking };
|
||||
const entry = Object.hasOwn(models, model) ? models[model] : null;
|
||||
if (!entry) throw new BundleError(`instance ${resolved.instance}: unknown model table selection ${model}`);
|
||||
return { harness, provider: entry.provider, model: entry.model, modelKey: model, thinking };
|
||||
if (entry.provider === "proxy") {
|
||||
const missing = !Object.hasOwn(entry, "route");
|
||||
if (missing || !["anthropic", "glm", "codex"].includes(entry.route))
|
||||
throw new BundleError("proxy model needs an explicit anthropic, glm or codex route", missing ? "proxy-route-missing" : "proxy-route-unknown");
|
||||
}
|
||||
return { harness, provider: entry.provider, model: entry.model, modelKey: model, thinking,
|
||||
...(entry.provider === "proxy" ? { proxyRoute: entry.route } : {}) };
|
||||
}
|
||||
|
||||
// Row 91 (#1585): the project clones the host made or kept in the workspace.
|
||||
@@ -309,10 +315,14 @@ function prompt({ contract, resolved, session, tools, untyped, builtins, persona
|
||||
// personaDir <configDir>/personas, where a creative instance's persona file is read from
|
||||
// (row 213); an instance with persona.sha256 and no personaDir refuses
|
||||
// Returns { manifest, files, policy, tools, env } with absolute paths; env is the module's
|
||||
// adapter variables, which the host writes into session.json.
|
||||
export function buildBundle({ dir, resolved, contract, arbiter = false, tracker = false, library = false, credentials = [], session, harness, route = "primary", routeReason = null, harnessVersion = null, models = null, land = false, skillsDir = null, personaDir = null }) {
|
||||
// adapter variables. In proxy mode the host splits credentials into its
|
||||
// transient spawn environment before writing the remaining variables to session.json.
|
||||
export function buildBundle({ dir, resolved, contract, arbiter = false, tracker = false, library = false, credentials = [], session, harness, route = "primary", routeReason = null, harnessVersion = null, models = null, land = false, skillsDir = null, personaDir = null, proxy = null }) {
|
||||
if (route !== "primary" && route !== "fallback") throw new BundleError(`route ${JSON.stringify(route)} isn't primary or fallback`);
|
||||
const model = sessionModel(resolved, models, route);
|
||||
if (model.provider === "proxy" && !proxy) throw new BundleError("proxy model needs its own session credential", "no-session-credential");
|
||||
if (proxy && (typeof proxy.key !== "string" || !proxy.key || typeof proxy.baseUrl !== "string"
|
||||
|| !/^http:\/\/127\.0\.0\.1:[0-9]+$/.test(proxy.baseUrl))) throw new BundleError("invalid session proxy context");
|
||||
const web = webPlan(resolved, model.harness, harness.builtinWeb());
|
||||
const tools = typedTools({ resolved, arbiter, tracker, library, projects: (session.checkouts ?? []).map((c) => c.project), webTyped: !web.builtin, land });
|
||||
const untyped = untypedActions(resolved, tools);
|
||||
@@ -346,7 +356,7 @@ export function buildBundle({ dir, resolved, contract, arbiter = false, tracker
|
||||
write("tools.json", JSON.stringify(tools, null, 2) + "\n"),
|
||||
];
|
||||
// The module's own files. A name the bundle already wrote refuses at write (flag wx).
|
||||
const own = harness.bundle({ dir, files: { ...files }, session, write, quote });
|
||||
const own = harness.bundle({ dir, files: { ...files }, session: { ...session, ...model }, write, quote, models, proxy });
|
||||
Object.assign(files, own.files);
|
||||
digests.push(...own.digests);
|
||||
const sources = { gate: SOURCES.gate, tools: SOURCES.tools, ...own.sources };
|
||||
@@ -373,6 +383,6 @@ export function buildBundle({ dir, resolved, contract, arbiter = false, tracker
|
||||
sources: Object.fromEntries(Object.entries(sources).map(([k, p]) => [k, { path: p, sha256: sha256(readFileSync(p)) }])),
|
||||
};
|
||||
writeFileSync(files.manifest, JSON.stringify(manifest, null, 2) + "\n", { mode: 0o600, flag: "wx" });
|
||||
const env = harness.env({ files, policy, tools, session: { ...session, ...model } });
|
||||
const env = harness.env({ files, policy, tools, session: { ...session, ...model }, models, proxy });
|
||||
return { manifest, files, policy, tools, env };
|
||||
}
|
||||
@@ -228,25 +228,24 @@ export function typedTools({ resolved, arbiter = false, tracker = false, project
|
||||
if (library) {
|
||||
const universe = str("Universe ID in the configured library", { minLength: 1 });
|
||||
const project = str("Library project ID; omit only when the business has one library");
|
||||
const scope = str("canon by default; playground and supporting are opt-in", { enum: ["canon", "playground", "supporting"] });
|
||||
const manuscriptScope = str("canon by default; playground is opt-in", { enum: ["canon", "playground"] });
|
||||
const scope = str("canon by default; playground is opt-in", { enum: ["canon", "playground"] });
|
||||
const book = str("Book folder from library_universe");
|
||||
const offset = { type: "integer", minimum: 0, description: "next from the previous page" };
|
||||
const line = { type: "integer", minimum: 1, description: "One-based line number" };
|
||||
const base = { universe, project };
|
||||
add("library_find", "library.find", null, "Find names in one universe, at the served commit. At most 50 results; continue with next as offset. Playground and supporting are opt-in.", obj({
|
||||
add("library_find", "library.find", null, "Find names in one universe, at the served commit. At most 50 results; continue with next as offset.", obj({
|
||||
...base, query: str("Case-insensitive name or filename substring; empty matches all"),
|
||||
type: str("Mapped type", { enum: ["character", "place", "research", "tracker", "summary"] }),
|
||||
book, scope, offset,
|
||||
}, ["universe", "query"]));
|
||||
add("library_get", "library.get", null, "Read a note and its blob at the served commit, canon by default. Playground/supporting paths need matching scope; mismatch returns null. next pages lines; links_next pages visible links in supporting/playground/canon order.", obj({
|
||||
...base, path: str("Mapped note path relative to the library"), scope, from: line, links_from: offset,
|
||||
add("library_get", "library.get", null, "Read a mapped note and visible links in one universe at the served commit. next pages lines; links_next pages links. An explicit own-universe playground path is readable.", obj({
|
||||
...base, path: str("Mapped note path relative to the library"), from: line, links_from: offset,
|
||||
}, ["universe", "path"]));
|
||||
add("library_search", "library.search", null, "Search text in one universe at the served commit. At most 50 hits; use next as offset. Playground and supporting are opt-in.", obj({
|
||||
add("library_search", "library.search", null, "Search text in one universe at the served commit. At most 50 hits; use next as offset. Playground is opt-in.", obj({
|
||||
...base, text: str("Nonempty case-insensitive substring", { minLength: 1 }), book, scope, offset,
|
||||
}, ["universe", "text"]));
|
||||
add("library_manuscript", "library.manuscript", null, "Read one chapter of a book at the served commit, at most 400 lines. Omit chapter for the first; continue with next or next_chapter.", obj({
|
||||
...base, book, scope: manuscriptScope, chapter: str("Chapter filename without extension"), from: line, to: line,
|
||||
...base, book, scope, chapter: str("Chapter filename without extension"), from: line, to: line,
|
||||
}, ["universe", "book"]));
|
||||
add("library_universe", "library.universe", null, "Read a universe's mapping at the served commit: books, types, playground prefixes, and hybrid sources/constraints/notes or draft metadata.", obj(base, ["universe"]));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ test('lookup schemas require a universe even for get, include paging, and cannot
|
||||
for (const key of ['repo', 'commit', 'business', 'accept']) assert.equal(Object.hasOwn(tool.parameters.properties, key), false);
|
||||
}
|
||||
const byName = Object.fromEntries(tools.map(t => [t.name, t]));
|
||||
assert.deepEqual(byName.library_find.parameters.properties.scope.enum, ['canon', 'playground', 'supporting']);
|
||||
assert.deepEqual(byName.library_find.parameters.properties.scope.enum, ['canon', 'playground']);
|
||||
assert.deepEqual(byName.library_find.parameters.properties.type.enum, [...TYPES]);
|
||||
assert.equal(byName.library_find.parameters.properties.offset.minimum, 0);
|
||||
assert.equal(byName.library_get.parameters.properties.from.minimum, 1);
|
||||
@@ -69,14 +69,3 @@ test('bundle flag reaches both harness tool manifests and creative prompt withou
|
||||
assert.doesNotMatch(prompt, /Bus tools: [^\n]*(read_spec|list_agents|inbox|trail|write_record|raise_decision|list_tasks)/);
|
||||
}
|
||||
});
|
||||
|
||||
test('C2-05c scope schemas expand only find/search/get, keeping manuscript and tool names unchanged', t => {
|
||||
const tools = typedTools({ resolved: role(t, 'ideas'), library: true });
|
||||
assert.deepEqual(tools.map(t => t.name), ['send_message', ...LOOKUPS]);
|
||||
for (const name of ['library_find', 'library_search', 'library_get']) {
|
||||
const tool = tools.find(t => t.name === name);
|
||||
assert.deepEqual(tool.parameters.properties.scope.enum, ['canon', 'playground', 'supporting']);
|
||||
assert.ok(!tool.parameters.required.includes('scope'));
|
||||
}
|
||||
assert.deepEqual(tools.find(t => t.name === 'library_manuscript').parameters.properties.scope.enum, ['canon', 'playground']);
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
// P3: generate real harness config through buildBundle; credentials never enter disk artifacts.
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdirSync, readFileSync, statSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { buildBundle } from '../src/bundle.mjs';
|
||||
import { HARNESS, REPO_SKILLS, resolvedFor, scratch } from './helpers.mjs';
|
||||
|
||||
const models = {
|
||||
a: { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' },
|
||||
z: { provider: 'proxy', model: 'glm-fixture', route: 'glm' },
|
||||
g: { provider: 'proxy', model: 'gpt-fixture', route: 'codex' },
|
||||
};
|
||||
function build(t, selection, proxy, declared) {
|
||||
const root = scratch(t, 'p332-'), runDir = join(root, 'run');
|
||||
mkdirSync(runDir, { mode: 0o700 });
|
||||
const valid = resolvedFor(t, 'pm');
|
||||
assert.ok(Object.hasOwn(declared, selection), 'fixture selection must exist in declared launch.models');
|
||||
const resolved = { ...valid, vars: { ...valid.vars, harness: 'pi', model: selection } };
|
||||
const bundle = buildBundle({
|
||||
dir: join(runDir, 'bundle'), resolved, models: declared,
|
||||
contract: '# Fixture\n', harness: HARNESS.pi, harnessVersion: 'fixture',
|
||||
skillsDir: REPO_SKILLS, proxy,
|
||||
session: { run: 'r332', launchedBy: 'chief', workspace: join(root, 'ws'),
|
||||
toolSocket: join(runDir, 'tools.sock'), turnMarker: join(runDir, 'turn.done') },
|
||||
});
|
||||
const file = join(runDir, 'home', '.pi', 'agent', 'models.json');
|
||||
return { ...bundle, file, runDir, text: readFileSync(file, 'utf8') };
|
||||
}
|
||||
function assertSafe(value) {
|
||||
if (typeof value === 'string') assert.ok(!value.startsWith('!'), value);
|
||||
else if (value && typeof value === 'object') for (const item of Object.values(value)) assertSafe(item);
|
||||
}
|
||||
|
||||
test('P3 Anthropic route uses messages at proxy root and the declared model id', t => {
|
||||
const b = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, { a: models.a });
|
||||
const { anthropic } = JSON.parse(b.text).providers;
|
||||
assert.equal(anthropic.api, 'anthropic-messages');
|
||||
assert.equal(anthropic.baseUrl, 'http://127.0.0.1:12345');
|
||||
assert.deepEqual(anthropic.models.map(m => m.id), ['claude-fixture']);
|
||||
assert.equal(b.env.PI_PROVIDER, 'anthropic');
|
||||
assert.equal(b.env.PI_MODEL, 'claude-fixture');
|
||||
});
|
||||
|
||||
test('P3 omitted route refuses proxy-route-missing before model config generation', t => {
|
||||
assert.throws(() => build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, {
|
||||
a: { provider: 'proxy', model: 'claude-fixture' },
|
||||
}), { code: 'proxy-route-missing' });
|
||||
});
|
||||
|
||||
test('P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility', t => {
|
||||
const b = build(t, 'z', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, { z: models.z });
|
||||
const glm = JSON.parse(b.text).providers['mosaic-proxy-glm'];
|
||||
assert.equal(glm.api, 'openai-completions');
|
||||
assert.equal(glm.baseUrl, 'http://127.0.0.1:12345/v1');
|
||||
assert.deepEqual(glm.models.map(m => m.id), ['glm-fixture']);
|
||||
assert.equal(glm.compat.thinkingFormat, 'zai');
|
||||
assert.equal(glm.compat.zaiToolStream, true);
|
||||
assert.equal(b.env.PI_PROVIDER, 'mosaic-proxy-glm');
|
||||
});
|
||||
|
||||
test('P3 GPT route selects a stack-owned provider instead of pi Codex OAuth', t => {
|
||||
const b = build(t, 'g', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, { g: models.g });
|
||||
const providers = JSON.parse(b.text).providers;
|
||||
assert.equal(Object.hasOwn(providers, 'openai-codex'), false);
|
||||
const gpt = providers['mosaic-proxy-codex'];
|
||||
assert.equal(gpt.api, 'openai-responses');
|
||||
assert.equal(gpt.baseUrl, 'http://127.0.0.1:12345/v1');
|
||||
assert.deepEqual(gpt.models.map(m => m.id), ['gpt-fixture']);
|
||||
assert.equal(b.env.PI_PROVIDER, 'mosaic-proxy-codex');
|
||||
});
|
||||
|
||||
test('P3 a declared Codex route generates only the single build-time responses provider', t => {
|
||||
const b = build(t, 'g', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, {
|
||||
g: models.g,
|
||||
});
|
||||
const providers = JSON.parse(b.text).providers;
|
||||
assert.deepEqual(Object.keys(providers), ['mosaic-proxy-codex']);
|
||||
assert.equal(providers['mosaic-proxy-codex'].api, 'openai-responses');
|
||||
assert.equal(providers['mosaic-proxy-codex'].apiKey, '$ANTHROPIC_API_KEY');
|
||||
});
|
||||
|
||||
test('P3 models file is private, references the one session key, and stores no executable values or keys', t => {
|
||||
const key = 'fx332-agent-a';
|
||||
const b = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key }, { a: models.a, z: models.z });
|
||||
const document = JSON.parse(b.text);
|
||||
assert.deepEqual(Object.keys(document.providers).sort(), ['anthropic', 'mosaic-proxy-glm']);
|
||||
for (const provider of Object.values(document.providers)) assert.equal(provider.apiKey, '$ANTHROPIC_API_KEY');
|
||||
assertSafe(document);
|
||||
assert.ok(!b.text.includes(key));
|
||||
assert.equal(b.env.ANTHROPIC_API_KEY, key);
|
||||
assert.equal(statSync(b.file).mode & 0o777, 0o600);
|
||||
for (const dir of ['home', 'home/.pi', 'home/.pi/agent']) assert.equal(statSync(join(b.runDir, dir)).mode & 0o777, 0o700);
|
||||
for (const file of Object.values(b.files)) assert.ok(!readFileSync(file, 'utf8').includes(key), file);
|
||||
assert.ok(!JSON.stringify(b.manifest).includes(key));
|
||||
});
|
||||
|
||||
test('P3 every launch regenerates proxy port, declared models and own key without caching', t => {
|
||||
const first = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' }, { a: models.a, z: models.z });
|
||||
const second = build(t, 'a', { baseUrl: 'http://127.0.0.1:23456', key: 'fx332-agent-b' }, {
|
||||
a: { provider: 'proxy', model: 'changed-model-id', route: 'anthropic' },
|
||||
z: { provider: 'proxy', model: 'changed-glm-id', route: 'glm' },
|
||||
});
|
||||
assert.equal(second.env.ANTHROPIC_API_KEY, 'fx332-agent-b');
|
||||
assert.ok(!JSON.stringify(second).includes('fx332-agent-a'));
|
||||
const { providers } = JSON.parse(second.text);
|
||||
assert.deepEqual(Object.keys(providers), ['anthropic', 'mosaic-proxy-glm']);
|
||||
assert.equal(providers.anthropic.baseUrl, 'http://127.0.0.1:23456');
|
||||
assert.deepEqual(providers.anthropic.models.map(m => m.id), ['changed-model-id']);
|
||||
assert.equal(providers['mosaic-proxy-glm'].baseUrl, 'http://127.0.0.1:23456/v1');
|
||||
assert.deepEqual(providers['mosaic-proxy-glm'].models.map(m => m.id), ['changed-glm-id']);
|
||||
assert.equal(JSON.parse(first.text).providers.anthropic.baseUrl, 'http://127.0.0.1:12345');
|
||||
});
|
||||
@@ -7,15 +7,12 @@
|
||||
import { raise } from './problems.mjs';
|
||||
import { TYPES } from './mapping.mjs';
|
||||
import { indexFor } from './index-build.mjs';
|
||||
import { listTree } from './reader.mjs';
|
||||
|
||||
// The same cap as packages/harness/src/tools.mjs REPLY_CAP. The query tests assert the two stay equal.
|
||||
export const QUERY_REPLY_CAP = 40_000;
|
||||
export const LOOKUP_LIMIT = 50;
|
||||
export const MANUSCRIPT_LINES = 400;
|
||||
const SCOPES = Object.freeze(['canon', 'playground', 'supporting']);
|
||||
const MANUSCRIPT_SCOPES = Object.freeze(['canon', 'playground']);
|
||||
const SCOPE_RANK = Object.freeze({ supporting: 0, playground: 1, canon: 2 });
|
||||
const SCOPES = Object.freeze(['canon', 'playground']);
|
||||
|
||||
const bytes = value => JSON.stringify(value).length;
|
||||
const invalid = message => raise('query-argument-invalid', message);
|
||||
@@ -25,9 +22,9 @@ function textArg(value, name) {
|
||||
if (typeof value !== 'string') invalid(`${name} must be text`);
|
||||
return value;
|
||||
}
|
||||
function scopeArg(value, allowed = SCOPES) {
|
||||
function scopeArg(value) {
|
||||
if (value === undefined) return 'canon';
|
||||
if (!allowed.includes(value)) invalid(`scope must be one of ${allowed.join(", ")}`);
|
||||
if (!SCOPES.includes(value)) invalid('scope must be "canon" or "playground"');
|
||||
return value;
|
||||
}
|
||||
function positionArg(value, name, fallback) {
|
||||
@@ -112,8 +109,7 @@ export async function find(source, { universe: name, query, type, book, scope, o
|
||||
});
|
||||
}
|
||||
|
||||
// get: one file in the requested scope (canon default), its served-tree blob, front matter,
|
||||
// lines and visible links both ways. Links keep all visible scopes, ordered supporting/playground/canon.
|
||||
// get: one visible file, its front matter, its lines from `from`, and its visible links both ways.
|
||||
// Returns null when the file is missing or not visible, so a caller cannot tell the two apart. Lines page
|
||||
// by `from` (reply `next`), links page together by `links_from` (reply `links_next`); `links_out` come
|
||||
// before `links_in`. Every page carries the front matter. Links take at most half the cap, so a hub note
|
||||
@@ -121,33 +117,27 @@ export async function find(source, { universe: name, query, type, book, scope, o
|
||||
// least one line, so links shrink when a line needs the room; read on with `from: next` and
|
||||
// `links_from: links_next`. A `from` past the last line returns links alone. Only front matter, or a
|
||||
// line that cannot fit with no links beside it, is refused.
|
||||
export async function get(source, { universe: name, path, scope, from, links_from: linksFrom } = {}) {
|
||||
export async function get(source, { universe: name, path, from, links_from: linksFrom } = {}) {
|
||||
const universe = universeArg(source.mapping, name);
|
||||
const requestedScope = scopeArg(scope);
|
||||
const startLine = positionArg(from, 'from', 1);
|
||||
const linkStart = offsetArg(linksFrom);
|
||||
if (typeof path !== 'string') invalid('path must be text');
|
||||
const index = await indexFor(source);
|
||||
const file = index.files.get(path);
|
||||
if (!file || file.scope !== requestedScope || !sees(index.mapping, universe, file)) return null;
|
||||
if (!file || !sees(index.mapping, universe, file)) return null;
|
||||
const reachable = links => links.filter(link => {
|
||||
const other = index.files.get(link.path);
|
||||
return other !== undefined && sees(index.mapping, universe, other);
|
||||
}).sort((a, b) => SCOPE_RANK[index.files.get(a.path).scope] - SCOPE_RANK[index.files.get(b.path).scope]);
|
||||
});
|
||||
const outs = reachable(index.linksOut.get(file.path) ?? []);
|
||||
const ins = reachable(index.linksIn.get(file.path) ?? []);
|
||||
const links = [...outs.map(link => ({ out: true, link })), ...ins.map(link => ({ out: false, link }))];
|
||||
// The reader/index does not keep tree oids. Resolve only in this immutable served
|
||||
// snapshot, never HEAD; listTree already checks/bounds the tree and its object IDs.
|
||||
const entry = (await listTree(source.repo, index.commit)).find(entry => entry.path === file.path);
|
||||
if (!entry || entry.mode !== '100644' || entry.type !== 'blob') raise('library-commit', 'indexed file is absent from the served tree');
|
||||
const blob = entry.oid;
|
||||
const lines = file.lines.slice(startLine - 1);
|
||||
const linkRest = Math.max(0, links.length - linkStart);
|
||||
const page = (nLines, nLinks) => {
|
||||
const taken = links.slice(linkStart, linkStart + nLinks);
|
||||
return {
|
||||
path: file.path, commit: index.commit, blob, scope: file.scope, frontmatter: file.frontmatter,
|
||||
path: file.path, commit: index.commit, scope: file.scope, frontmatter: file.frontmatter,
|
||||
lines: lines.slice(0, nLines),
|
||||
links_out: taken.filter(item => item.out).map(item => item.link),
|
||||
links_in: taken.filter(item => !item.out).map(item => item.link),
|
||||
@@ -211,7 +201,7 @@ export async function manuscript(source, { universe: name, book, scope, chapter,
|
||||
const start = positionArg(from, 'from', 1);
|
||||
const end = positionArg(to, 'to', Infinity);
|
||||
if (end < start) invalid('to must not be before from');
|
||||
const { index, files } = await visible(source, universe, { scope: scopeArg(scope, MANUSCRIPT_SCOPES), book: bookName, type: 'manuscript' });
|
||||
const { index, files } = await visible(source, universe, { scope: scopeArg(scope), book: bookName, type: 'manuscript' });
|
||||
let at = 0;
|
||||
if (chapterName !== undefined) {
|
||||
const matches = files.filter(file => file.stem === chapterName);
|
||||
|
||||
@@ -29,22 +29,3 @@ export const note = (type, name, body = '', extra = []) => ['---', `type: ${type
|
||||
// `exclude` (a path prefix today); swapping these two constants is the whole change to the tests.
|
||||
export const EXCLUSION = { exclude: 'Book One/Research' };
|
||||
export const EXCLUDED_PATHS = ['Book One/Research/Ferry Logs.md'];
|
||||
|
||||
// C2-05c: synthetic scope fixture, including same-prefix precedence and a draft.
|
||||
export const SUPPORT_FILES = {
|
||||
'Book One/Characters/Canon.md': note('character', 'Canon', 'Scope fixture canon.'),
|
||||
'Book One/Playground/Plan.md': note('summary', 'Plan', 'Scope fixture playground.'),
|
||||
'Book One/Support/Notes/Helper.md': note('summary', 'Helper', 'Scope fixture supporting.'),
|
||||
'Notes/HarborSupport/Loose.md': note('summary', 'Loose', 'Scope fixture supporting loose.'),
|
||||
'Drafts/Idea/Support/Seed.md': note('summary', 'Seed', 'Scope fixture supporting draft.'),
|
||||
};
|
||||
export const withSupporting = entry => ({
|
||||
...entry,
|
||||
universes: {
|
||||
...entry.universes,
|
||||
harbor: { ...entry.universes.harbor,
|
||||
playground: [...entry.universes.harbor.playground, 'Book One/Support/'],
|
||||
supporting: ['Book One/Support/', 'Notes/HarborSupport/'] },
|
||||
idea: { kind: 'draft', name: 'Idea', playground: ['Drafts/Idea/'], supporting: ['Drafts/Idea/Support/'] },
|
||||
},
|
||||
});
|
||||
@@ -1,13 +1,11 @@
|
||||
// Query tests for design 3 (C2-05a): universe isolation, scope labels, unmapped files, hybrids, paging
|
||||
// under the reply cap, refusals and manuscript paging. Fixtures are made up and built under the scratch area.
|
||||
import { test } from 'node:test';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import assert from 'node:assert/strict';
|
||||
import { REPLY_CAP } from '../../harness/src/tools.mjs';
|
||||
import { find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from '../src/query.mjs';
|
||||
import { mapping, MARKER, git } from './helpers.mjs';
|
||||
import { scratchRepo, note, EXCLUSION, EXCLUDED_PATHS, SUPPORT_FILES, withSupporting } from './query-fixture.mjs';
|
||||
import { mapping, MARKER } from './helpers.mjs';
|
||||
import { scratchRepo, note, EXCLUSION, EXCLUDED_PATHS } from './query-fixture.mjs';
|
||||
|
||||
// A hybrid over harbor and second. Its one constraint is EXCLUSION (query-fixture.mjs) and it declares no
|
||||
// books or playground.
|
||||
@@ -347,9 +345,9 @@ test('PRD 1.14: a draft universe has no canon, so its lookups return files only
|
||||
assert.ok(found.results.every(r => r.scope === 'playground' && r.universe === 'idea' && r.book === null));
|
||||
const hits = (await search(s, { universe: 'idea', text: 'draft', scope: 'playground' })).results;
|
||||
assert.equal(hits.length, 2);
|
||||
const rin = await get(s, { universe: 'idea', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' });
|
||||
const rin = await get(s, { universe: 'idea', path: 'Drafts/New World/Characters/Rin.md' });
|
||||
assert.equal(rin.scope, 'playground');
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Drafts/New World/Characters/Rin.md', scope: 'playground' }), null);
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Drafts/New World/Characters/Rin.md' }), null);
|
||||
});
|
||||
|
||||
test('PRD 1.14: library_universe on a draft returns its kind, name and prefixes', async t => {
|
||||
@@ -365,102 +363,7 @@ test('PRD 1.14: library_universe on a draft returns its kind, name and prefixes'
|
||||
test('a hybrid gets a source playground file as null, while the source gets it with scope playground', async t => {
|
||||
const ref = scratchRepo(t, FILES);
|
||||
const path = 'Book One/Playground/What If.md';
|
||||
assert.equal(await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path, scope: 'playground' }), null);
|
||||
const own = await get(src(ref), { universe: 'harbor', path, scope: 'playground' });
|
||||
assert.equal(await get(src(ref, mapping(WITH_BLEND)), { universe: 'blend', path }), null);
|
||||
const own = await get(src(ref), { universe: 'harbor', path });
|
||||
assert.equal(own.scope, 'playground');
|
||||
});
|
||||
|
||||
// mos-1330 item3: the new get contract defaults to canon even for an explicit playground path.
|
||||
test('C2-05c get without scope returns null for a playground path', async t => {
|
||||
const s = src(scratchRepo(t, FILES));
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Book One/Playground/What If.md' }), null);
|
||||
});
|
||||
|
||||
// Row284: scope is explicit for get as well as lists; blob and lines share a served snapshot.
|
||||
test('C2-05c supporting find/search/get are opt-in at book, universe and draft level', async t => {
|
||||
const s = src(scratchRepo(t, SUPPORT_FILES), mapping(withSupporting));
|
||||
const expected = ['Book One/Support/Notes/Helper.md', 'Notes/HarborSupport/Loose.md'];
|
||||
assert.deepEqual(paths(await find(s, { universe: 'harbor', query: '', scope: 'supporting' })), expected);
|
||||
assert.deepEqual((await search(s, { universe: 'harbor', text: 'Scope fixture', scope: 'supporting' })).results.map(x => x.path), expected);
|
||||
assert.deepEqual(paths(await find(s, { universe: 'harbor', query: '' })), ['Book One/Characters/Canon.md']);
|
||||
assert.deepEqual((await search(s, { universe: 'harbor', text: 'Scope fixture' })).results.map(x => x.path), ['Book One/Characters/Canon.md']);
|
||||
for (const path of expected) {
|
||||
assert.equal(await get(s, { universe: 'harbor', path }), null);
|
||||
assert.equal(await get(s, { universe: 'harbor', path, scope: 'playground' }), null);
|
||||
assert.equal((await get(s, { universe: 'harbor', path, scope: 'supporting' })).scope, 'supporting');
|
||||
assert.equal(await get(s, { universe: 'second', path, scope: 'supporting' }), null);
|
||||
}
|
||||
const draftPath = 'Drafts/Idea/Support/Seed.md';
|
||||
assert.deepEqual(paths(await find(s, { universe: 'idea', query: '', scope: 'supporting' })), [draftPath]);
|
||||
assert.equal((await get(s, { universe: 'idea', path: draftPath, scope: 'supporting' })).scope, 'supporting');
|
||||
assert.equal(await get(s, { universe: 'idea', path: draftPath }), null);
|
||||
assert.equal((await find(s, { universe: 'harbor', query: '', book: 'Book One', scope: 'supporting' })).results.length, 1);
|
||||
});
|
||||
|
||||
test('C2-05c an absent supporting prefix returns nothing without refusal', async t => {
|
||||
const s = src(scratchRepo(t, SUPPORT_FILES));
|
||||
assert.deepEqual((await find(s, { universe: 'harbor', query: '', scope: 'supporting' })).results, []);
|
||||
assert.deepEqual((await search(s, { universe: 'harbor', text: 'Scope fixture', scope: 'supporting' })).results, []);
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Book One/Characters/Canon.md', scope: 'supporting' }), null);
|
||||
assert.equal(await get(s, { universe: 'harbor', path: 'Book One/Support/Notes/Helper.md', scope: 'supporting' }), null);
|
||||
});
|
||||
|
||||
test('C2-05c each get blob equals its served tree object, even after source HEAD advances', async t => {
|
||||
const ref = scratchRepo(t, SUPPORT_FILES), s = src(ref, mapping(withSupporting));
|
||||
const canon = 'Book One/Characters/Canon.md';
|
||||
const priorBlob = git(ref.repo, 'rev-parse', `${ref.commit}:${canon}`);
|
||||
writeFileSync(join(ref.repo, canon), note('character', 'Canon changed', 'New HEAD must not be read.'));
|
||||
git(ref.repo, 'add', '-A'); git(ref.repo, 'commit', '-qm', 'advance head fixture');
|
||||
assert.notEqual(git(ref.repo, 'rev-parse', `HEAD:${canon}`), priorBlob);
|
||||
for (const [scope, path] of [['canon', canon], ['playground', 'Book One/Playground/Plan.md'], ['supporting', 'Book One/Support/Notes/Helper.md']]) {
|
||||
const result = await get(s, { universe: 'harbor', path, scope });
|
||||
assert.equal(result.commit, ref.commit);
|
||||
assert.equal(result.blob, git(ref.repo, 'rev-parse', `${ref.commit}:${path}`));
|
||||
assert.ok(!JSON.stringify(result.lines).includes('New HEAD must not be read'));
|
||||
}
|
||||
});
|
||||
|
||||
test('C2-05c full outgoing and incoming links stay in scope order across pages without losing cross-scope links', async t => {
|
||||
const files = {}, groups = { supporting: [], playground: [], canon: [] };
|
||||
for (const [scope, folder] of [['canon', 'Book One/Characters'], ['playground', 'Book One/Playground'], ['supporting', 'Book One/Support']]) {
|
||||
for (let n = 0; n < 100; n++) {
|
||||
const path = `${folder}/${scope}-${String(n).padStart(3, '0')}-${'x'.repeat(80)}.md`;
|
||||
groups[scope].push(path);
|
||||
files[path] = `[[Book One/Characters/Hub]]\n`;
|
||||
}
|
||||
}
|
||||
const all = [...groups.canon, ...groups.playground, ...groups.supporting];
|
||||
files['Book One/Characters/Hub.md'] = all.map(path => `[[${path.slice(0, -3)}]]`).join('\n');
|
||||
// Other-universe links are never returned, regardless of rank.
|
||||
files['Second World/Other.md'] = '[[Book One/Characters/Hub]]\n';
|
||||
const s = src(scratchRepo(t, files), mapping(withSupporting));
|
||||
const outs = [], ins = [];
|
||||
let offset = 0, pages = 0;
|
||||
for (; pages < 20; pages++) {
|
||||
const page = await get(s, { universe: 'harbor', path: 'Book One/Characters/Hub.md', from: 999_999, links_from: offset });
|
||||
assert.ok(JSON.stringify(page).length <= QUERY_REPLY_CAP);
|
||||
outs.push(...page.links_out.map(x => x.path)); ins.push(...page.links_in.map(x => x.path));
|
||||
if (page.links_next === null) break;
|
||||
offset = page.links_next;
|
||||
}
|
||||
const expected = [...groups.supporting, ...groups.playground, ...groups.canon];
|
||||
assert.ok(pages > 0 && pages < 20, 'links occupy multiple bounded pages');
|
||||
assert.deepEqual(outs, expected);
|
||||
assert.deepEqual(ins, expected);
|
||||
assert.equal(new Set(outs).size, 300);
|
||||
assert.equal(new Set(ins).size, 300);
|
||||
});
|
||||
|
||||
test('C2-05c manuscript still refuses supporting rather than silently widening its scope', async t => {
|
||||
const s = src(scratchRepo(t, SUPPORT_FILES), mapping(withSupporting));
|
||||
await assert.rejects(manuscript(s, { universe: 'harbor', book: 'Book One', scope: 'supporting' }), { code: 'query-argument-invalid' });
|
||||
});
|
||||
|
||||
test('C2-05c scope expansion keeps hybrid sources canon-only and refuses all/array scopes', async t => {
|
||||
const s = src(scratchRepo(t, SUPPORT_FILES), mapping(entry => withSupporting(WITH_BLEND(entry))));
|
||||
assert.deepEqual((await find(s, { universe: 'blend', query: '', scope: 'supporting' })).results, []);
|
||||
assert.equal(await get(s, { universe: 'blend', path: 'Book One/Support/Notes/Helper.md', scope: 'supporting' }), null);
|
||||
assert.equal((await get(s, { universe: 'blend', path: 'Book One/Characters/Canon.md' })).scope, 'canon');
|
||||
for (const scope of ['all', ['canon', 'supporting']])
|
||||
await assert.rejects(get(s, { universe: 'harbor', path: 'Book One/Characters/Canon.md', scope }), { code: 'query-argument-invalid' });
|
||||
});
|
||||
@@ -327,3 +327,32 @@ organization file or unavailable bus.
|
||||
For the re-pin introducing this kind, Jason enables both channels through
|
||||
plugins.set immediately after activate in Mos's window, then smokes CLI thread
|
||||
listing and Console chat. No development seat performs that live step.
|
||||
|
||||
## Per-session proxy context (P3)
|
||||
|
||||
The launcher's injected `proxy` is either a `{ baseUrl, key }` context supplied by
|
||||
P2, or a factory receiving `{ business, instance }` and returning that context.
|
||||
Checks may repeat before spawn; the factory must return that agent's current
|
||||
credential. P3 does not acquire, issue or revoke keys. No context means existing
|
||||
nonproxy launch behavior; a selected proxy model without context refuses.
|
||||
|
||||
The harness `preflight`, `bundle` and `env` calls receive an optional `proxy`
|
||||
argument; `bundle` and `env` also receive the declared model table. In proxy
|
||||
mode the launcher removes instance provider variables, then separates the
|
||||
harness's credential variables from `harnessEnv` before writing `session.json`.
|
||||
Only the spawned runner's environment receives those variables.
|
||||
|
||||
A proxy `launch.models` entry requires `route: anthropic|glm|codex`. Omission
|
||||
refuses `proxy-route-missing`; unknown routes refuse `proxy-route-unknown`. Other providers
|
||||
retain provider/model-only entries. `launch.account.credential: proxy` names the
|
||||
proxy credential source. Pi needs its own provider key or a supplied proxy key;
|
||||
Claude OAuth alone cannot satisfy pi preflight.
|
||||
|
||||
Pi writes private, fresh run-local `home/.pi/agent/models.json`, with
|
||||
`$ANTHROPIC_API_KEY` references. Anthropic uses messages at the proxy root; GLM
|
||||
uses completions at `/v1` with z.ai compatibility fields. GPT uses the stack-owned
|
||||
`mosaic-proxy-codex` provider, never pi's Codex OAuth provider. Its build-time API
|
||||
value is `openai-responses` per Sage's sage-4331 ruling: both shapes passed the
|
||||
pinned offline probe, so this is a reasoning-based tie-break rather than an
|
||||
evidence-decided pick. Row209 phase A step7 verifies the first real Codex turn.
|
||||
There is no runtime API selection or fallback.
|
||||
@@ -53,8 +53,8 @@ function binary(env) {
|
||||
}
|
||||
|
||||
// A session needs a credential from the host's environment and the binary it runs.
|
||||
export function preflight({ env }) {
|
||||
if (!hasSessionCredential(env)) {
|
||||
export function preflight({ env, proxy = null }) {
|
||||
if (!(typeof proxy?.key === "string" && proxy.key) && !hasSessionCredential(env)) {
|
||||
const names = SESSION_CREDENTIALS.map((set) => set.join(" with ")).join(", ");
|
||||
return { code: "no-session-credential", message: `the bus host has none of ${names}; the bus unit's EnvironmentFile sets one when the bus starts` };
|
||||
}
|
||||
@@ -116,12 +116,13 @@ export function bundle({ dir, files: core, session, write, quote }) {
|
||||
return { files, digests, sources: { claudeGate: GATE, mcpServer: MCP_SERVER, ...UNSLOP } };
|
||||
}
|
||||
|
||||
export function env({ files, policy, session }) {
|
||||
export function env({ files, policy, session, proxy = null }) {
|
||||
return {
|
||||
MOSAIC_TOOLS: claudeBuiltins(policy).join(","),
|
||||
MOSAIC_CLAUDE_SETTINGS: files.settings,
|
||||
MOSAIC_CLAUDE_MCP_CONFIG: files.mcp,
|
||||
MOSAIC_THINKING: session.thinking,
|
||||
...(proxy ? { ANTHROPIC_BASE_URL: proxy.baseUrl, ANTHROPIC_AUTH_TOKEN: proxy.key } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
// Pi extension, which stays in packages/harness (a module can't change that boundary). The
|
||||
// launcher, the bundle and the usage reader call these on the host; the runner gets the answers
|
||||
// as data in session.json. packages/plugins/README.md lists the interface.
|
||||
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { createHash } from "node:crypto";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
export const interfaceVersion = 1;
|
||||
@@ -12,6 +13,10 @@ export const interfaceVersion = 1;
|
||||
const REPO = fileURLToPath(new URL("../../../../", import.meta.url));
|
||||
const PACKAGE = "@earendil-works/pi-coding-agent";
|
||||
const BIN = join(REPO, "node_modules", ".bin", "pi");
|
||||
// Sage sage-4331: reasoning-based tie-break; both pinned-proxy shapes passed.
|
||||
// First real Codex verification remains row209 phase A step7. No runtime switch.
|
||||
const PROXY_CODEX_API = "openai-responses";
|
||||
const PROXY_PROVIDERS = Object.freeze({ anthropic: "anthropic", glm: "mosaic-proxy-glm", codex: "mosaic-proxy-codex" });
|
||||
const EXTENSION = fileURLToPath(new URL("../../../harness/src/pi-extension.mjs", import.meta.url));
|
||||
// Row 66 (#1559): the unslop check, loaded as a second extension. It logs to MOSAIC_UNSLOP_LOG,
|
||||
// which the runner sets, and the runner tells the operator.
|
||||
@@ -30,7 +35,11 @@ export const adapter = () => join(REPO, "adapters", "pi", "adapter.sh");
|
||||
export const levels = () => LEVELS;
|
||||
|
||||
// The session runs pi from the repository's node_modules, which the sandbox mounts.
|
||||
export function preflight() {
|
||||
export function preflight({ env = {}, proxy = null } = {}) {
|
||||
if (!(typeof proxy?.key === "string" && proxy.key)
|
||||
&& !["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "OPENROUTER_API_KEY", "ZAI_API_KEY"].some(name => Boolean(env[name]))) {
|
||||
return { code: "no-session-credential", message: "pi needs its own provider key or a session proxy key" };
|
||||
}
|
||||
if (!existsSync(BIN)) return { code: "harness-binary-missing", message: `pi isn't installed at ${BIN}; run npm ci in the repository` };
|
||||
return null;
|
||||
}
|
||||
@@ -57,16 +66,52 @@ export const builtins = ({ tools }) => [...tools];
|
||||
export const typedName = (name) => name;
|
||||
export const reliesOn = () => RELIES_ON;
|
||||
export const gateTimeout = () => null;
|
||||
export const bundle = () => ({ files: {}, digests: [], sources: { piExtension: EXTENSION, ...UNSLOP } });
|
||||
export function bundle({ dir, models, proxy = null }) {
|
||||
const sources = { piExtension: EXTENSION, ...UNSLOP };
|
||||
if (!proxy) return { files: {}, digests: [], sources };
|
||||
const providers = {};
|
||||
for (const entry of Object.values(models ?? {})) {
|
||||
if (entry.provider !== "proxy") continue;
|
||||
const route = entry.route;
|
||||
if (!Object.hasOwn(PROXY_PROVIDERS, route)) throw new Error("proxy model has no supported route");
|
||||
const provider = PROXY_PROVIDERS[route];
|
||||
if (typeof entry.model !== "string" || !entry.model || entry.model.startsWith("!")) throw new Error("unsafe proxy model id");
|
||||
const api = route === "anthropic" ? "anthropic-messages"
|
||||
: route === "glm" ? "openai-completions" : PROXY_CODEX_API;
|
||||
providers[provider] ??= {
|
||||
baseUrl: proxy.baseUrl + (route === "anthropic" ? "" : "/v1"),
|
||||
api, apiKey: "$ANTHROPIC_API_KEY",
|
||||
...(route === "glm" ? { compat: { thinkingFormat: "zai", zaiToolStream: true } } : {}),
|
||||
models: [],
|
||||
};
|
||||
if (!providers[provider].models.some(model => model.id === entry.model)) {
|
||||
providers[provider].models.push({ id: entry.model, reasoning: true });
|
||||
}
|
||||
}
|
||||
const text = JSON.stringify({ providers }, null, 2) + "\n";
|
||||
// Even an accidental collision between a configured model id and the key fails closed.
|
||||
if (typeof proxy.key !== "string" || !proxy.key || text.includes(proxy.key)) throw new Error("unsafe proxy model configuration");
|
||||
const runDir = dirname(dir);
|
||||
for (const part of ["home", "home/.pi", "home/.pi/agent"]) {
|
||||
const path = join(runDir, part);
|
||||
mkdirSync(path, { recursive: true, mode: 0o700 });
|
||||
const stat = lstatSync(path);
|
||||
if (!stat.isDirectory() || (stat.mode & 0o777) !== 0o700) throw new Error("pi proxy config needs private run-local directories");
|
||||
}
|
||||
const file = join(runDir, "home", ".pi", "agent", "models.json");
|
||||
writeFileSync(file, text, { mode: 0o600, flag: "wx" });
|
||||
return { files: { proxyModels: file }, digests: [["../home/.pi/agent/models.json", createHash("sha256").update(text).digest("hex")]], sources };
|
||||
}
|
||||
|
||||
// The tool limit is the built-ins plus the typed tools, which the extension serves.
|
||||
export function env({ policy, tools, session }) {
|
||||
export function env({ policy, tools, session, proxy = null }) {
|
||||
return {
|
||||
MOSAIC_TOOLS: [...policy.tools, ...tools.map((t) => t.name)].join(","),
|
||||
MOSAIC_EXTENSIONS: [EXTENSION, UNSLOP.unslopExtension].join(","),
|
||||
PI_PROVIDER: session.provider ?? "",
|
||||
PI_PROVIDER: proxy ? PROXY_PROVIDERS[session.proxyRoute] : session.provider ?? "",
|
||||
PI_MODEL: session.model,
|
||||
MOSAIC_THINKING: session.thinking,
|
||||
...(proxy ? { ANTHROPIC_API_KEY: proxy.key } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -97,9 +97,9 @@ test("row 65 claude-code version asks MOSAIC_CLAUDE_BIN when set, else claude on
|
||||
assert.equal(claude.version({ env: { PATH: join(dir, "none") } }), null);
|
||||
});
|
||||
|
||||
test("row 65 pi preflight passes with the repository's pi, and its version is the package pin", async () => {
|
||||
test("row 65 pi preflight refuses missing credentials, and its version is the package pin", async () => {
|
||||
const pi = await load("pi");
|
||||
assert.equal(pi.preflight({ env: {} }), null);
|
||||
assert.equal(pi.preflight({ env: {} }).code, "no-session-credential");
|
||||
const pkg = JSON.parse(readFileSync(join(REPO, "package.json"), "utf8"));
|
||||
assert.equal(pi.version({ env: {} }), pkg.dependencies?.["@earendil-works/pi-coding-agent"] ?? pkg.devDependencies?.["@earendil-works/pi-coding-agent"]);
|
||||
// Row 66: the unslop extension's files, bound read-only at their own paths.
|
||||
|
||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user