test: give row 219 persona fixture its explicit session

Apply mos-1408 and sage-3178 without creating the directory being asserted. Preserve the first red evidence and select TAP explicitly for the next approved run.
This commit is contained in:
Rocko committed 2026-10-22 23:26:17 -05:00
1 parent c7bf3622dd
commit b97a3ff975
16 files changed
+346 -8

No files matched your search

+24
View File
@@ -205,3 +205,27 @@ live cases, so not used as the Docker worst-case estimate).
Mos1316/1317 first-run launcher/creative/chat-browser reds, any old-test red
or a second red stop before fixes and go to Sage/Mos. No run evidence yet.
## First red and approved test-only correction: mos-1408 / sage-3178-3179
Run c7bf3622d stopped at launcher.test's row213 persona-mismatch assertion:
04:07:22.895-04:07:51.870Z, creative 4/0/0, threads 19/0/0,
user-principal 23/0/0, launcher 33/1/0: total 79 pass, 1 fail, 0 skip.
The approved threadsState snapshot had no session; row269's session-required
admission fired before bundle/persona reading. Original logs remain in
run-4a9c/ and derived-counts-first-stop.json reads their default spec output.
No retry or fix occurred before Mos's ruling. Slot returned after empty
Node/Chromium cwd sweep and all 14 source hashes checked.
Mos-1408 permits only an explicit SESSION in that snapshot and literal-path
assertions: the native threads/acme/<thread>/sessions/<SESSION>/session exists,
and the legacy threads/acme/<thread>/session does not. No sessionStore() call
in the assertion: it creates directories and could manufacture the evidence.
Every other assertion stays exactly as before; no second host op is wrapped.
No product change. Runner explicitly selects --test-reporter=tap (packet-only)
and uses new run-4a9c-mos1408/ output, preserving the failed first attempt.
The next CLEAR reruns from the beginning: whole files, suites, shells, all
23 mutants, reader audit. Any red or second edit must return to Sage/Mos.
Sage-3179: commit/push during the current gap; hold re-claim until our own
slot, after 292 then 294. No tests or queue writes under another seat's slot.
+6 -4
View File
@@ -265,10 +265,10 @@ index bfe55b61e..d8248284c 100644
(!threaded && s.instance === r.instance && (spawnedAt.get(s.run) ?? Date.parse(s.startedAt)) <= at)));
}
diff --git a/packages/cli/tests/launcher.test.mjs b/packages/cli/tests/launcher.test.mjs
index 2202c7753..0a34fe27a 100644
index 2202c7753..a9a7d2d40 100644
--- a/packages/cli/tests/launcher.test.mjs
+++ b/packages/cli/tests/launcher.test.mjs
@@ -773,21 +773,28 @@ test("row 213 a creative instance's persona is read from <configDir>/personas: o
@@ -773,21 +773,30 @@ test("row 213 a creative instance's persona is read from <configDir>/personas: o
const dir = join(given.root, "config", "personas", "acme");
mkdirSync(dir, { recursive: true, mode: 0o700 });
writeFileSync(join(dir, "bean.md"), "Not the pinned text.\n", { mode: 0o600 });
@@ -281,10 +281,11 @@ index 2202c7753..0a34fe27a 100644
+ // Row 219: creative instances launch from their thread, not from a chief's standalone request.
+ // The mismatch occurs before bindLaunch, so only the host's thread-state snapshot is a fixture.
+ const thread = 'persona-thread';
+ const SESSION = 'persona-session';
+ const { f, launcher } = await setup(t, undefined, given, { wrap: host => ({
+ ...host,
+ op: message => message.op === 'threadsState'
+ ? Promise.resolve([{ thread, instance: 'bean', holder: null, pending: 1 }])
+ ? Promise.resolve([{ thread, session: SESSION, instance: 'bean', holder: null, pending: 1 }])
+ : host.op(message),
+ }) });
+ // The bundle's refusal remains launch-failed with the persona mismatch as its reason.
@@ -300,7 +301,8 @@ index 2202c7753..0a34fe27a 100644
assert.equal(runs.length, 1);
- assert.deepEqual(readdirSync(join(f.dataRoot, "launches", "acme", runs[0])), ["session"]);
+ assert.deepEqual(readdirSync(join(f.dataRoot, "launches", "acme", runs[0])), []);
+ assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "session")), true);
+ assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "sessions", SESSION, "session")), true);
+ assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "session")), false);
});
test("row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts", { timeout: 30000 }, async (t) => {
+14
View File
@@ -0,0 +1,14 @@
from pathlib import Path
import os,json
busy=[]
for p in Path('/proc').glob('[0-9]*'):
try:
if int(p.name)==os.getpid():continue
comm=(p/'comm').read_text().strip()
if not any(x in comm for x in ['node','python','bash']):continue
args=(p/'cmdline').read_bytes().split(b'\0')
if (comm.startswith('node') and b'--test' in args) or any(x.rsplit(b'/',1)[-1] in (b'run-mutants.py',b'gate-run.sh') for x in args):
busy.append(dict(pid=int(p.name),cwd=str((p/'cwd').resolve()),name=comm))
except (PermissionError,FileNotFoundError,ProcessLookupError):pass
print('BUSY_CHECK',json.dumps(busy))
raise SystemExit(bool(busy))
@@ -3,7 +3,7 @@ b0c66c8999b567896923f6c876911dba936c6eca1ccc7aaeada51369fd613594 packages/bus/t
de4913f50801a11fd172e3f2c2b3cb41ab04e84d32a6650d1c8662b5e227ea3d packages/bus/tests/threads.test.mjs
8f7d6745fffb2a0898ac80c012084ac48964748da6439a8c56facc6529ffb19b packages/bus/tests/user-principal.test.mjs
b74275ce43249bafc97edc87a6a3aa0431c62fe1a28cd9fa265246e6d6da219b packages/cli/src/launcher.mjs
fc301cde49e6db1286e90d6ac3410f5f4d87351bec61f1bae27c235a041848b6 packages/cli/tests/launcher.test.mjs
6e5446030f4bbec714598cc64bf096e9b2a0bd3da1d77817b848fcd67e0d2db9 packages/cli/tests/launcher.test.mjs
a219036737419870e0aa9d0da20843759a66be5bafff44d3292593833f8fcb9a packages/cli/tests/thread-launch.test.mjs
cbfd54e6b375561d1e4679ee8d78a3285f970d9a7198cec9d22a06510a36afba packages/webui/src/chat-http.mjs
f49a49c6ec69783190d3f5eaf34316cb4d2c44d10d2ee9336fe1383207afefff packages/webui/src/chat.mjs
+2 -1
View File
@@ -5,7 +5,7 @@ from pathlib import Path
from datetime import datetime,timezone
ROOT=Path(__file__).resolve().parents[4]
PACKET=Path(__file__).resolve().parent
OUT=PACKET/'run-4a9c';OUT.mkdir(exist_ok=True)
OUT=PACKET/'run-4a9c-mos1408';OUT.mkdir(exist_ok=True)
def stamp():return datetime.now(timezone.utc).isoformat()
def verify():
for line in (PACKET/'candidate-manifest.sha256').read_text().splitlines():
@@ -20,6 +20,7 @@ def sweep():
except (FileNotFoundError,PermissionError,ProcessLookupError):pass
return found
def execute(label,args,cwd=ROOT,deadline=300,docker=False):
if args[0]=='node' and '--test' in args and '--test-reporter=tap' not in args:args=[args[0],'--test-reporter=tap',*args[1:]]
verify();short=tempfile.mkdtemp(prefix='r',dir='/mnt/storage/scratch/tmp')
env=os.environ.copy();env.update(TMPDIR=short,NO_COLOR='1',COMPOSE_PROJECT_NAME='rocko-r219-gate')
env.pop('MOSAIC_GITEA_CREDENTIAL_FILE',None);env.pop('MOSAIC_LIVE_PROVIDER',None)
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1,130 @@
[
{
"label": "single-bus-creative.test",
"args": [
"node",
"--test",
"packages/bus/tests/creative.test.mjs"
],
"start": "2026-10-23T04:07:22.895462+00:00",
"end": "2026-10-23T04:07:23.260724+00:00",
"seconds": 0.365,
"exit": 0,
"timeout": false,
"counts": {
"tests": null,
"pass": null,
"fail": null,
"cancelled": null,
"skipped": null
},
"skips": [],
"log": "agents/rocko/work/queue-219/run-4a9c/single-bus-creative.test.tap",
"tmpdir": "/mnt/storage/scratch/tmp/rsrt5bzap",
"derived_spec_counts": {
"tests": 4,
"pass": 4,
"fail": 0,
"cancelled": 0,
"skipped": 0
},
"failed_test_names": []
},
{
"label": "single-bus-threads.test",
"args": [
"node",
"--test",
"packages/bus/tests/threads.test.mjs"
],
"start": "2026-10-23T04:07:23.262757+00:00",
"end": "2026-10-23T04:07:24.629883+00:00",
"seconds": 1.367,
"exit": 0,
"timeout": false,
"counts": {
"tests": null,
"pass": null,
"fail": null,
"cancelled": null,
"skipped": null
},
"skips": [],
"log": "agents/rocko/work/queue-219/run-4a9c/single-bus-threads.test.tap",
"tmpdir": "/mnt/storage/scratch/tmp/r5anojtow",
"derived_spec_counts": {
"tests": 19,
"pass": 19,
"fail": 0,
"cancelled": 0,
"skipped": 0
},
"failed_test_names": []
},
{
"label": "single-bus-user-principal.test",
"args": [
"node",
"--test",
"packages/bus/tests/user-principal.test.mjs"
],
"start": "2026-10-23T04:07:24.631177+00:00",
"end": "2026-10-23T04:07:25.246596+00:00",
"seconds": 0.615,
"exit": 0,
"timeout": false,
"counts": {
"tests": null,
"pass": null,
"fail": null,
"cancelled": null,
"skipped": null
},
"skips": [],
"log": "agents/rocko/work/queue-219/run-4a9c/single-bus-user-principal.test.tap",
"tmpdir": "/mnt/storage/scratch/tmp/rg47u_3c2",
"derived_spec_counts": {
"tests": 23,
"pass": 23,
"fail": 0,
"cancelled": 0,
"skipped": 0
},
"failed_test_names": []
},
{
"label": "single-cli-launcher.test",
"args": [
"node",
"--test",
"packages/cli/tests/launcher.test.mjs"
],
"start": "2026-10-23T04:07:25.247904+00:00",
"end": "2026-10-23T04:07:51.870129+00:00",
"seconds": 26.622,
"exit": 1,
"timeout": false,
"counts": {
"tests": null,
"pass": null,
"fail": null,
"cancelled": null,
"skipped": null
},
"skips": [],
"log": "agents/rocko/work/queue-219/run-4a9c/single-cli-launcher.test.tap",
"tmpdir": "/mnt/storage/scratch/tmp/r8oua_z8g",
"derived_spec_counts": {
"tests": 34,
"pass": 33,
"fail": 1,
"cancelled": 0,
"skipped": 0
},
"failed_test_names": [
"row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason",
"failing tests:",
"row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason"
]
}
]
@@ -0,0 +1 @@
{"head": "c7bf3622dd617ea1e3e68a1c9ce44774e2cfe9da", "manifest": "cd791883449f0d64fca06a9a855f855c93d7db74ced53ccebbcb0bad5a0206a7", "start": "2026-10-23T04:07:22.892671+00:00"}
@@ -0,0 +1,2 @@
Error response from daemon: network rocko-r219-gate_default not found
exit status 1
@@ -0,0 +1,4 @@
{"label": "single-bus-creative.test", "args": ["node", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T04:07:22.895462+00:00", "end": "2026-10-23T04:07:23.260724+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-4a9c/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rsrt5bzap"}
{"label": "single-bus-threads.test", "args": ["node", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T04:07:23.262757+00:00", "end": "2026-10-23T04:07:24.629883+00:00", "seconds": 1.367, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-4a9c/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r5anojtow"}
{"label": "single-bus-user-principal.test", "args": ["node", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T04:07:24.631177+00:00", "end": "2026-10-23T04:07:25.246596+00:00", "seconds": 0.615, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-4a9c/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rg47u_3c2"}
{"label": "single-cli-launcher.test", "args": ["node", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T04:07:25.247904+00:00", "end": "2026-10-23T04:07:51.870129+00:00", "seconds": 26.622, "exit": 1, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-4a9c/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r8oua_z8g"}
@@ -0,0 +1,14 @@
organization: {"event":"reload-needs-restart","business":"demo"}
organization: {"event":"reload-needs-restart","business":"demo"}
✔ M6: a creative raise refuses decision-not-allowed, cited or not, and no decision row appears; the assistant still raises (34.696206ms)
✔ a creative instance sends only to the user and hears only from the user (41.081291ms)
✔ M10 through the broker: the chief and the tester are refused on bean, the human's limits.set of its models key works (81.11191ms)
✔ row 256 T6 the human deletes a creative instance through the broker; the chief and the tester are refused at the verb (57.456912ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 334.223966
@@ -0,0 +1,27 @@
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (36.004676ms)
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (68.738374ms)
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (32.515768ms)
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (610.990913ms)
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (23.409918ms)
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (28.817937ms)
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (30.260544ms)
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (32.327162ms)
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (29.133476ms)
✔ REQ-ROLE-2 REQ-THREAD-1 Q169: a role.revoke the human approved ends every thread run of the assistant (26.476132ms)
✔ Q169 REQ-USER-2: assistant.stop ends the human's own assistant thread runs, and only the human's (39.418785ms)
✔ REQ-USER-2: the human verbs refuse another owner's thread (28.785396ms)
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (22.979076ms)
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (25.496215ms)
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (90.366693ms)
✔ project.create refuses a repository name without its matching repo before any write (16.151198ms)
✔ project.create keeps unrelated names with and without a repository (11.187274ms)
✔ C2-09a: explicit creative instances bind independent threads, default sessions and holders (47.776915ms)
✔ C2-09a: explicit missing, non-thread and malformed selectors create no thread or session (20.207317ms)
ℹ tests 19
ℹ suites 0
ℹ pass 19
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1299.709199
@@ -0,0 +1,31 @@
✔ R3: bindUser binds a granted user and refuses one with no live grant (14.786261ms)
✔ R3: a user named like the business human, the tester or a principal word is refused, whatever the grants say (9.870795ms)
✔ R3: each collaborator verb is allowed to a granted user (19.637409ms)
✔ R3: every verb off the collaborator list refuses a user access-refused before its own checks (105.182773ms)
✔ R3: task, web and host verbs refuse a user access-refused (25.672551ms)
✔ R3 leak: project.list shows granted projects only (13.27019ms)
✔ R3 leak: thread.create needs the project and the thread instance granted, and an ungranted id reads as one that does not exist (15.965771ms)
✔ R3 leak: thread.list shows the user its own threads that are still granted, never others (35.018528ms)
✔ R3 leak: names shows granted instances only (15.057536ms)
✔ R3: thread.send is from user:<id> and writes no human.input (13.514578ms)
✔ R3: a reply-chain message.send into another user thread is refused (16.631267ms)
✔ R3: the run reply to a user message reaches that user thread.messages, with no waiting and no notice (18.899841ms)
✔ R3: a reply to: user without a matching in_reply_to is refused user-reply-required (28.916725ms)
✔ R3: a non-thread run, the human and the tester cannot send to: user (17.965675ms)
✔ R3: a user thread run cannot message the owner, while its uncited gated raise reaches only the owner inbox, B9 (19.241443ms)
✔ R3: a removed or expired grant refuses the next request access-revoked, and the file is read per request (17.997053ms)
✔ R3: a user refusal is recorded as action.refused by user:<id> (14.840437ms)
✔ R3: a business with a role keyed user refuses invalid-business (10.081108ms)
✔ R3: name.set refuses the name user (10.301262ms)
✔ R3 r4: while halted, a granted user's thread.send refuses processing-halted and thread.messages still answers (14.447561ms)
✔ R3 r4: the chief's hire refuses an instance named user with the code it gives human and tester (15.786706ms)
✔ R3 r4: a non-function access throws before the store is read (0.121803ms)
✔ C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project (16.966486ms)
ℹ tests 23
ℹ suites 0
ℹ pass 23
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 545.0572
@@ -0,0 +1,84 @@
✔ C2-04: launcher workspace clones code but never the library (1405.320275ms)
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1322.785792ms)
usage: {"event":"usage-unknown","business":"acme","run":"r6724498202ca","instance":"chief","turn":"4d5e8541-7110-44bb-8a7a-ed92208a0fd3","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"rd57aefe67267","instance":"coder","turn":"b9afd99d-fad8-48ce-8c03-ca9f9b329cfb","source":"@none","code":"baseline-unknown"}
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (726.266248ms)
usage: {"event":"usage-unknown","business":"acme","run":"r6e78d96da940","instance":"chief","turn":"0286a736-4a58-46ff-92bb-e974030f5bd7","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r7a24261c88d1","instance":"pm","turn":"a6496c08-1b00-4b40-8d0e-03bc7e972248","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r6e78d96da940","instance":"chief","turn":"cdf4283b-3be0-415c-88d2-ea1e45163617","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r6e78d96da940","instance":"chief","turn":"046a20f2-e7eb-477b-b6e6-b7588b603cbd","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r7a24261c88d1","instance":"pm","turn":"9a07e317-c472-4f17-bb7d-2309cf341af7","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r7a24261c88d1","instance":"pm","turn":"b0ebda74-f2a9-440a-a173-39dcae896036","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r6e78d96da940","instance":"chief","turn":"15238cb8-619f-4a31-b853-fb55d9b86e79","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r7a24261c88d1","instance":"pm","turn":"8a3ef9b0-73bb-4a3f-bf0e-06dcbc0f60c4","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"r6e78d96da940","instance":"chief","turn":"4077ae80-1bfc-4cdd-bfca-27c992282797","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 (1123.845931ms)
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (4152.636087ms)
✔ a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none (617.243337ms)
✔ 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 (412.306281ms)
usage: {"event":"usage-unknown","business":"acme","run":"rcf551273e0ad","instance":"coder","turn":"c4220d02-0bf0-4122-aa52-925afe04df92","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 (700.748992ms)
✔ a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder (638.103132ms)
✔ after a restart, the new host's first tick starts a holder whose decision is still held (890.273051ms)
✔ 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 (632.625787ms)
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (266.198371ms)
✔ a runner that stops at once ends its launch with the runner's reason (345.619813ms)
✔ a Claude Code launch with no session credential refuses before it starts (189.183758ms)
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (338.515656ms)
usage: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/mnt/storage/scratch/rocko-r219/packages/plugins/harness/down is missing","kept":[]}
plugins: {"event":"plugin-refused","kind":"harness","name":"down","code":"missing","message":"/mnt/storage/scratch/rocko-r219/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 (364.92973ms)
✔ a runner killed from the host ends its launch as killed, not failed (396.074165ms)
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (192.417417ms)
✔ 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 (190.827519ms)
✖ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (192.548301ms)
✔ row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts (189.824532ms)
usage: {"event":"usage-unknown","business":"acme","run":"rf7aede34a71b","instance":"chief","turn":"799876e4-fe02-4621-aaac-dfc5cf192082","source":"@none","code":"baseline-unknown"}
usage: {"event":"usage-unknown","business":"acme","run":"ref958a5bcbb6","instance":"coder","turn":"ce0a5214-37f5-48d4-ae90-c9f6745e058d","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 (1782.388685ms)
✔ 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 (1025.160483ms)
✔ 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 (3976.016342ms)
✔ bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was (236.101723ms)
✔ bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned (195.720542ms)
✔ bus start --no-launch starts no thread tick; the same host with launches runs it (1179.765366ms)
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (174.297238ms)
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (187.137601ms)
✔ a launch client that never closes its side doesn't hold the host's close (184.807395ms)
✔ a runner that ignores SIGTERM is killed when the host closes (1359.638326ms)
✔ kill switch refuses chief and hire before launch work and a clear permits a later request (317.536928ms)
✔ kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle (326.035999ms)
✔ a launch waiting across halt and resume cannot use its stale admission (196.129785ms)
ℹ tests 34
ℹ suites 0
ℹ pass 33
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 26568.728775
✖ failing tests:
test at packages/cli/tests/launcher.test.mjs:766:1
✖ row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason (192.548301ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'refused',
+ 'session-required',
- 'launch-failed',
1
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219/packages/cli/tests/launcher.test.mjs:788:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ 'refused', 'session-required', 1 ],
expected: [ 'refused', 'launch-failed', 1 ],
operator: 'deepStrictEqual',
diff: 'simple'
}
+4 -2
View File
@@ -776,10 +776,11 @@ test("row 213 a creative instance's persona is read from <configDir>/personas: o
// Row 219: creative instances launch from their thread, not from a chief's standalone request.
// The mismatch occurs before bindLaunch, so only the host's thread-state snapshot is a fixture.
const thread = 'persona-thread';
const SESSION = 'persona-session';
const { f, launcher } = await setup(t, undefined, given, { wrap: host => ({
...host,
op: message => message.op === 'threadsState'
? Promise.resolve([{ thread, instance: 'bean', holder: null, pending: 1 }])
? Promise.resolve([{ thread, session: SESSION, instance: 'bean', holder: null, pending: 1 }])
: host.op(message),
}) });
// The bundle's refusal remains launch-failed with the persona mismatch as its reason.
@@ -794,7 +795,8 @@ test("row 213 a creative instance's persona is read from <configDir>/personas: o
const runs = readdirSync(join(f.dataRoot, "launches", "acme"));
assert.equal(runs.length, 1);
assert.deepEqual(readdirSync(join(f.dataRoot, "launches", "acme", runs[0])), []);
assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "session")), true);
assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "sessions", SESSION, "session")), true);
assert.equal(existsSync(join(f.dataRoot, "threads", "acme", thread, "session")), false);
});
test("row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts", { timeout: 30000 }, async (t) => {