docs: preserve row 219 full gate on the post-295 merge
This commit is contained in:
1 parent
054da642f9
commit
f0a6b3cf46
131 files changed
+52426
-19
No files matched your search
@@ -340,3 +340,56 @@ push only after authorized. Estimate3-5min. No tests/mutants/Node/push until
|
||||
Sage CLEAR. Dewey delta review follows; later full no-carry restart includes
|
||||
all10 changed files, bus/cli/webui, all10 shells, all24 mutants and reader
|
||||
control/audit. Further old-test red stops and goes to Mos through Sage.
|
||||
|
||||
# Full restart r6, sage-3345 / mos-1439
|
||||
|
||||
Merge 054da642f9b0680bd7743583e4c67266d7e14e2a, parents 2efd127ce617a9bff8dc3bee3a3b657b0c175c07 and b899095e4.
|
||||
Tree e86a84a852c9739f157033e3772243b293742983 matches Sage before any run.
|
||||
No conflicts or manual product/test edits. Same16 paths, new manifest
|
||||
4a2271ddbd4212324f39e608c3a35a4ae834c045cb0d13a619715017ded0ffef.
|
||||
Fresh worktree /mnt/storage/scratch/rocko-r219-g3345, node_modules linked immediately.
|
||||
Runner uses mktemp -d /mnt/storage/scratch/tmp/rXXXXXX and validates
|
||||
[A-Za-z0-9/.-] for each stage; no previous results carry.
|
||||
10 whole singles; bus,cli,webui,harness suites; all10 shell scripts
|
||||
including test-task with Docker;24 mutants;reader audit.
|
||||
Timeout -k10: singles300s,suites1800s,shells7200s,mutants180s;
|
||||
7200s exceeds3x the prior conservative25min shell baseline.
|
||||
Every child has a process group; any red stops, no retry/edit.
|
||||
Finally remove owned networks including rocko-r219-g3345_default,
|
||||
sweep, preserve packet evidence, remove node_modules link and this worktree.
|
||||
|
||||
## Post-295 gate result
|
||||
|
||||
## Completed gate, sage-3345
|
||||
|
||||
Full run 2026-10-23 10:12:57Z-10:29:22Z on merge054da642f9.
|
||||
Ten singles183/0/0; bus889/0/1; cli927/0/0; webui373/0/1;
|
||||
harness151/0/0. Node total2523pass/0fail/2skip,0cancelled.
|
||||
All10 shell files green,449pass/0fail.24 assertion kills,0timeout kills,
|
||||
0survivors,0invalid. T15 finished in66.9s with ERR_ASSERTION on the
|
||||
missing 'no longer available' status; T24 got decision-required instead
|
||||
of host-creative-role (same exact later-fence mismatch as r4).
|
||||
Both Bean pins and the sandbox-dependent native-history test ran, no skip.
|
||||
|
||||
Skips: X-G3 scratch Gitea1.27.1 unavailable (Node stage uses deadDocker);
|
||||
WebUI rebuild needs esbuild0.28.2 but host has0.28.1; queue verify/render
|
||||
requires canonical checkout; test-task live provider cases intentionally
|
||||
skipped twice (row244, no provider call). GATE-RESULTS.json quotes all5
|
||||
skip lines, including the duplicated live-provider line.
|
||||
|
||||
Reader audit: all16 changed paths plus unchanged public/bus.js,237 reader
|
||||
hits and22 64-hex lines. None of those pins freezes a changed file. Positive
|
||||
control channel-proof.test.mjs webui bus.mjs pin matches actual bytes;
|
||||
public/bus.js stays unchanged. Full audit in reader-audit.json.
|
||||
|
||||
16 candidate hashes restored. Driver cwd node/chromium sweep empty.
|
||||
Owned rocko-r219-gate_default removed; worktree-basename network
|
||||
rocko-r219-g3345_default already absent (rm attempted as instructed).
|
||||
No retries, unexpected reds or guard interventions in this run. Results
|
||||
from prior environmental failures were not carried.
|
||||
|
||||
Historical environmental failures remain in run-0780-mos1429/ (harness
|
||||
underscore TMPDIR) and run-0780-mos1432/ (Docker address pool exhaustion).
|
||||
Mos1432 required alphanumeric paths; Mos1437/Mos1439 and sage3339/3345
|
||||
resolved the network issue outside this candidate. No product/test fix
|
||||
for either. Tests and source remain byte-identical to the checked merge.
|
||||
@@ -1 +1 @@
|
||||
80793d824e05baaef4820f4be7790aba55971b6f
|
||||
2efd127ce617a9bff8dc3bee3a3b657b0c175c07
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index d76085739..11061c778 100644
|
||||
index 7befba0c0..20da8b84c 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -4,7 +4,7 @@ import { initializeControl, processingStatus } from '../../processing-control/sr
|
||||
@@ -20,7 +20,7 @@ index d76085739..11061c778 100644
|
||||
// user in threads. Its runs claim a thread, not the role, and every message to or from it names its
|
||||
// thread (REQ-MSG-1).
|
||||
// Row 146 (#1640): the sender of the bus's notice to launch.by. A role instance name matches the
|
||||
@@ -598,7 +598,7 @@ export class Broker {
|
||||
@@ -610,7 +610,7 @@ export class Broker {
|
||||
);
|
||||
}
|
||||
#threaded(business, role) {
|
||||
@@ -29,7 +29,7 @@ index d76085739..11061c778 100644
|
||||
}
|
||||
// Row 264a (#1769): a claim holds one session of a thread, and each session has its own holder.
|
||||
#sessionHolder(session) {
|
||||
@@ -6068,24 +6068,27 @@ export class Broker {
|
||||
@@ -6171,24 +6171,27 @@ export class Broker {
|
||||
.all('SELECT id,at,name,repo FROM projects WHERE business=? ORDER BY seq', s.business)
|
||||
.filter((p) => !s.user || this.#granted(s, 'project.list', p.id, null));
|
||||
}
|
||||
@@ -65,7 +65,7 @@ index d76085739..11061c778 100644
|
||||
if (this.#store.get('SELECT 1 FROM threads WHERE project=? AND name=?', a.project, a.name)) fail('thread-exists');
|
||||
const tid = randomUUID();
|
||||
this.#store.run(
|
||||
@@ -6094,13 +6097,13 @@ export class Broker {
|
||||
@@ -6197,13 +6200,13 @@ export class Broker {
|
||||
this.#now(),
|
||||
s.business,
|
||||
a.project,
|
||||
@@ -157,7 +157,7 @@ index a6086e56c..7275ad902 100644
|
||||
assert.doesNotMatch(source, /\bimport\s*\(/);
|
||||
assert.doesNotMatch(readFileSync(new URL('../src/landing.mjs', import.meta.url), 'utf8'), /\bimport\b/);
|
||||
diff --git a/packages/bus/tests/threads.test.mjs b/packages/bus/tests/threads.test.mjs
|
||||
index 8b31da9f9..280e03184 100644
|
||||
index 27193a745..ae44fb66a 100644
|
||||
--- a/packages/bus/tests/threads.test.mjs
|
||||
+++ b/packages/bus/tests/threads.test.mjs
|
||||
@@ -601,3 +601,56 @@ test('project.create keeps unrelated names with and without a repository', t =>
|
||||
@@ -261,7 +261,7 @@ index 4dcd1ebeb..8471ddf85 100644
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project, name: 'old instance', instance: 'assistant' }), 'access-refused');
|
||||
+});
|
||||
diff --git a/packages/cli/src/launcher.mjs b/packages/cli/src/launcher.mjs
|
||||
index bfe55b61e..d8248284c 100644
|
||||
index f1ee4043e..cb9631ddf 100644
|
||||
--- a/packages/cli/src/launcher.mjs
|
||||
+++ b/packages/cli/src/launcher.mjs
|
||||
@@ -53,7 +53,7 @@
|
||||
@@ -273,7 +273,7 @@ index bfe55b61e..d8248284c 100644
|
||||
// a launch from a session or --pm refuses thread-required. Every tick
|
||||
// (threadTickMs) the host asks the broker for the business's threads
|
||||
// (launch op threadsState) and:
|
||||
@@ -139,6 +139,7 @@ import { createServer } from "node:net";
|
||||
@@ -142,6 +142,7 @@ import { createServer } from "node:net";
|
||||
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync } from "node:fs";
|
||||
import { dirname, join, relative } from "node:path";
|
||||
import { configDir, loadBusiness, resolveInstance, systemVars } from "../../business/src/index.mjs";
|
||||
@@ -281,7 +281,7 @@ index bfe55b61e..d8248284c 100644
|
||||
import { limitHit } from "../../business/src/launch.mjs";
|
||||
import { BundleError, buildBundle, hasFallback, readSkills, sessionModel } from "../../harness/src/bundle.mjs";
|
||||
import { createLoader } from "../../plugins/src/loader.mjs";
|
||||
@@ -176,8 +177,6 @@ const STOP_TIMEOUT_MS = 30000;
|
||||
@@ -179,8 +180,6 @@ const STOP_TIMEOUT_MS = 30000;
|
||||
const LINE_MAX = 4096;
|
||||
// How often the host asks for the threads' state; a poll period, not a limit.
|
||||
const THREAD_TICK_MS = 2000;
|
||||
@@ -290,7 +290,7 @@ index bfe55b61e..d8248284c 100644
|
||||
// Row 194: the broker's LIFECYCLE_REQUEST_MS. A regenerate's old run must be gone by then.
|
||||
const LIFECYCLE_REQUEST_MS = 60000;
|
||||
|
||||
@@ -331,7 +330,7 @@ export function createLauncher({
|
||||
@@ -334,7 +333,7 @@ export function createLauncher({
|
||||
try { b=loadBusiness(host.business,{dir:configDir(env),rolesDir:rolesDir(env)}); } catch(e){throw new Refusal("organization-refused",e.message);}
|
||||
if (!b.launch) throw new Refusal("launch-not-configured", `business ${b.id} has no launch block`);
|
||||
if (!(pm ? instance === b.launch.by : b.launch.instances.includes(instance) || (human && Object.hasOwn(b.roles, instance)))) throw new Refusal("instance-not-listed");
|
||||
@@ -299,7 +299,7 @@ index bfe55b61e..d8248284c 100644
|
||||
if (threaded && !thread) throw new Refusal("thread-required", `${instance} runs only for a thread`);
|
||||
if (!threaded && thread) throw new Refusal("thread-not-allowed", `${instance} isn't a thread instance`);
|
||||
if (threaded && !session) throw new Refusal("session-required", `${instance} runs for one session of a thread`);
|
||||
@@ -997,7 +996,7 @@ export function createLauncher({
|
||||
@@ -1014,7 +1013,7 @@ export function createLauncher({
|
||||
function ending(r) {
|
||||
const runs = r.runs ?? [];
|
||||
const at = Date.parse(r.at);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
142a210882535108159e045c61be288bc8703910a8ee0169137bc1eb80baff64 packages/bus/src/broker.mjs
|
||||
09569596eba8d129d0aa78c52dbf92d2a26a8f2b1960d54898eb90a810398465 packages/bus/src/broker.mjs
|
||||
b0c66c8999b567896923f6c876911dba936c6eca1ccc7aaeada51369fd613594 packages/bus/tests/creative.test.mjs
|
||||
3efd0238da60e0bfcd3b25e5256b9c213085119a86a7b852b13e7a60340d3a24 packages/bus/tests/grant-executor.test.mjs
|
||||
b7ea857637947c7a9ca45c56cea47e37e06f0fd8446ea91316990d9fa7299a7a packages/bus/tests/project-runtime.test.mjs
|
||||
264d82944c53b638bf6a14cc0706cf9ba184d668211c2b9c1031cdbe88e84bb9 packages/bus/tests/threads.test.mjs
|
||||
760c4a5dc2881a47be2a174f92c4fcb1b6e46abb299cb045a2e3dcbc485fb334 packages/bus/tests/threads.test.mjs
|
||||
8f7d6745fffb2a0898ac80c012084ac48964748da6439a8c56facc6529ffb19b packages/bus/tests/user-principal.test.mjs
|
||||
b74275ce43249bafc97edc87a6a3aa0431c62fe1a28cd9fa265246e6d6da219b packages/cli/src/launcher.mjs
|
||||
20423a8614ada8f2d1156ab2b041e93582986a1277e86520b0909e66892e4aec packages/cli/src/launcher.mjs
|
||||
2c3f120dfdc0b52bf8ab38a88e86251be75d4b0d218e23df489dcaf815d6bc15 packages/cli/tests/launcher.test.mjs
|
||||
7f308fdf601e839194f026beb3fea279eba1e356ce2756aa4a42fa4873b79b30 packages/cli/tests/thread-launch.test.mjs
|
||||
39c6d207e026debb7db8aade5534503847d0f5c84d560ba28f3cd65490378363 packages/webui/src/chat-http.mjs
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
## Full restart r5: sage-3313 / post-302 merge
|
||||
|
||||
Merged b899095e4 onto 07802dc57ad36337351da70af15c447bea38ab8b, clean, merge 06d7cc2f0ffc544abfb2755f99dce76ca164212c.
|
||||
Both row302 and row219 changes in broker.mjs and threads.test.mjs retained
|
||||
by the automatic merge; no manual product/test edits. New 16-path manifest
|
||||
420befed0aa8291736d34187ac7e745b7660efed15348ece045a7dd8957c9124.
|
||||
No previous runs carried. All 10 whole touched files, bus/cli/webui/harness
|
||||
suites, all shell files, 24 mutants, reader audit. Fresh short TMPDIR per
|
||||
stage, process groups, timeout -k 10; previous time limits remain.
|
||||
Packet runner now writes a fresh run-0780-mos1429 directory and includes
|
||||
harness explicitly. It classifies GNU timeout exit 124/137 or signal -9 as
|
||||
timeout too, so a timed-out mutant can never be called assertion-killed.
|
||||
No mutation/test/product changes for that runner classification correction.
|
||||
Every old-test red (including compactions-launch:229) stops for Mos.
|
||||
|
||||
|
||||
## Runner-only restart under mos-1432 / sage-3323
|
||||
|
||||
Previous full run stopped at harness claude-session.test.mjs:298. Saved
|
||||
TMPDIR /mnt/storage/scratch/tmp/rh85v_4j3 contains underscore; the fixture's
|
||||
slug replaces only / and . while Claude normalizes underscore too. Sage's
|
||||
clean-base diagnostic reproduces 10/0 with alphanumeric TMPDIR and 9/1
|
||||
with underscore. Latent test bug is a separate row; no code/test fix here.
|
||||
Runner now creates each stage TMPDIR with mktemp -d
|
||||
/mnt/storage/scratch/tmp/rXXXXXX and rejects any full path outside
|
||||
[A-Za-z0-9/.-]. New output run-0780-mos1432 preserves the prior red logs.
|
||||
Same merge 06d7cc2f0 and 16-path manifest 420befed; no results carried.
|
||||
Full restart waits for Sage CLEAR after 295. No tests or Node in preparation.
|
||||
@@ -0,0 +1 @@
|
||||
07802dc57ad36337351da70af15c447bea38ab8b
|
||||
@@ -0,0 +1,832 @@
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index b05922479..4c59c3a4a 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -4,7 +4,7 @@ import { initializeControl, processingStatus } from '../../processing-control/sr
|
||||
import { NAME as HARNESS_NAME } from '../../plugins/src/kinds.mjs';
|
||||
import { loadRequirements } from '../../tasks/src/requirements.mjs';
|
||||
import { MERGE, LandingRefusal, readLanding } from './landing.mjs';
|
||||
-import { ID_PATTERN, THREAD_DEFINITION, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';
|
||||
+import { ID_PATTERN, THREAD_DEFINITIONS, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';
|
||||
|
||||
// Kept closed while S1 lands; its vocabulary is the integration authority.
|
||||
export const ACTIONS = Object.freeze([
|
||||
@@ -314,7 +314,7 @@ const enrollBinding = (enroll) => ({
|
||||
});
|
||||
// r6 E3: the installer line's comment, then the tag's 32 hex digits.
|
||||
const INSTALLER_COMMENT = 'mosaic-installer-';
|
||||
-// Row 121 (#1615): an instance of THREAD_DEFINITION (vocabulary.mjs since row 155) talks with the
|
||||
+// Row 121 (#1615): an instance of THREAD_DEFINITIONS (vocabulary.mjs since row 213) talks with the
|
||||
// user in threads. Its runs claim a thread, not the role, and every message to or from it names its
|
||||
// thread (REQ-MSG-1).
|
||||
// Row 146 (#1640): the sender of the bus's notice to launch.by. A role instance name matches the
|
||||
@@ -602,7 +602,7 @@ export class Broker {
|
||||
);
|
||||
}
|
||||
#threaded(business, role) {
|
||||
- return this.#business(business).roles[role]?.definition === THREAD_DEFINITION;
|
||||
+ return THREAD_DEFINITIONS.includes(this.#business(business).roles[role]?.definition);
|
||||
}
|
||||
// Row 264a (#1769): a claim holds one session of a thread, and each session has its own holder.
|
||||
#sessionHolder(session) {
|
||||
@@ -6079,24 +6079,27 @@ export class Broker {
|
||||
.all('SELECT id,at,name,repo FROM projects WHERE business=? ORDER BY seq', s.business)
|
||||
.filter((p) => !s.user || this.#granted(s, 'project.list', p.id, null));
|
||||
}
|
||||
- // A thread belongs to the user who made it and to the business's one thread instance.
|
||||
+ // A thread belongs to the user who made it and to one declared thread instance.
|
||||
// Row 177 (#1675): a tester's thread is owned by `tester`, so neither reaches the other's.
|
||||
case 'thread.create': {
|
||||
if (!s.tester && !s.user) this.#human(s);
|
||||
- keys(a, ['project', 'name'], ['project', 'name']);
|
||||
+ keys(a, ['project', 'name', 'instance'], ['project', 'name']);
|
||||
if (!name(a.name)) fail('invalid-request');
|
||||
+ const instances = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
+ const instance = a.instance === undefined
|
||||
+ ? (instances.length === 1 ? instances[0] : null)
|
||||
+ : identifier(a.instance);
|
||||
// FED R3 (design 3.5): a user's grant must cover the project and the thread instance, checked
|
||||
// before the project is looked up, so an ungranted id reads the same whether it exists or not.
|
||||
if (s.user) {
|
||||
- const threaded = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
- if (threaded.length !== 1 || !this.#granted(s, 'thread.create', identifier(a.project), threaded[0])) fail('access-refused');
|
||||
+ if (!instance || !instances.includes(instance) || !this.#granted(s, 'thread.create', identifier(a.project), instance))
|
||||
+ fail('access-refused');
|
||||
}
|
||||
if (!this.#store.get('SELECT 1 FROM projects WHERE id=? AND business=?', identifier(a.project), s.business))
|
||||
fail('project-not-found');
|
||||
- // The bus never picks between instances; the business file declares exactly one.
|
||||
- const instances = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
- if (!instances.length) fail('thread-instance-missing');
|
||||
- if (instances.length > 1) fail('thread-instance-ambiguous');
|
||||
+ // The human selects an instance; omission is compatible only with one candidate.
|
||||
+ if (!instances.length || (a.instance !== undefined && !instances.includes(instance))) fail('thread-instance-missing');
|
||||
+ if (a.instance === undefined && instances.length > 1) fail('thread-instance-ambiguous');
|
||||
if (this.#store.get('SELECT 1 FROM threads WHERE project=? AND name=?', a.project, a.name)) fail('thread-exists');
|
||||
const tid = randomUUID();
|
||||
this.#store.run(
|
||||
@@ -6105,13 +6108,13 @@ export class Broker {
|
||||
this.#now(),
|
||||
s.business,
|
||||
a.project,
|
||||
- instances[0],
|
||||
+ instance,
|
||||
this.#owner(s),
|
||||
a.name,
|
||||
);
|
||||
// Row 264a (#1769, D3): every thread has a default session from the start.
|
||||
- this.#newSession(s, { id: tid, business: s.business, instance: instances[0], owner: this.#owner(s) }, 'default', 'default', true);
|
||||
- return { id: tid, instance: instances[0] };
|
||||
+ this.#newSession(s, { id: tid, business: s.business, instance, owner: this.#owner(s) }, 'default', 'default', true);
|
||||
+ return { id: tid, instance };
|
||||
}
|
||||
// Row 177 (#1675): each lists its own threads. The human's list leaves out the tester's,
|
||||
// and the tester's lists only its own (row 175 listed it the business human's).
|
||||
diff --git a/packages/bus/tests/creative.test.mjs b/packages/bus/tests/creative.test.mjs
|
||||
index 6cfbf1cd6..6d421ba19 100644
|
||||
--- a/packages/bus/tests/creative.test.mjs
|
||||
+++ b/packages/bus/tests/creative.test.mjs
|
||||
@@ -44,15 +44,18 @@ function setup(t) {
|
||||
const caps = {};
|
||||
caps.human = b.bindHuman({ business: 'demo', human: 'jason', via: 'cli', outsideAgent: true });
|
||||
const project = b.request(caps.human, { verb: 'project.create', args: { name: 'demo' } }).id;
|
||||
- const thread = b.request(caps.human, { verb: 'thread.create', args: { project, name: 'main' } }).id;
|
||||
+ const thread = b.request(caps.human, { verb: 'thread.create', args: { project, name: 'main', instance: 'assistant' } }).id;
|
||||
+ const threads = { assistant: thread };
|
||||
for (const role of Object.keys(roles)) {
|
||||
- caps[role] = b.bindLaunch({ business: 'demo', role, run: `${role}-run`, harness: 'pi', ...(role === 'assistant' ? { thread } : {}) });
|
||||
+ if (['bean', 'quill'].includes(role))
|
||||
+ threads[role] = b.request(caps.human, { verb: 'thread.create', args: { project, name: role, instance: role } }).id;
|
||||
+ caps[role] = b.bindLaunch({ business: 'demo', role, run: `${role}-run`, harness: 'pi', ...(threads[role] ? { thread: threads[role] } : {}) });
|
||||
b.request(caps[role], { verb: 'role.claim' });
|
||||
}
|
||||
caps.tester = b.bindTester({ business: 'demo' });
|
||||
const call = (who, verb, args = {}) => b.request(caps[who], { verb, args });
|
||||
const count = (sql) => store.get(sql).n;
|
||||
- return { call, count, store };
|
||||
+ return { call, count, store, threads };
|
||||
}
|
||||
|
||||
const raise = { action: 'policy.change', question: 'Change?', options: [{ key: 'yes', text: 'Yes' }, { key: 'no', text: 'No' }], recommendation: 'yes', blocking: false };
|
||||
@@ -72,7 +75,7 @@ test('M6: a creative raise refuses decision-not-allowed, cited or not, and no de
|
||||
});
|
||||
|
||||
test('a creative instance sends only to the user and hears only from the user', (t) => {
|
||||
- const { call, count } = setup(t);
|
||||
+ const { call, count, threads } = setup(t);
|
||||
for (const who of ['bean', 'quill']) {
|
||||
call(who, 'message.send', { to: 'human', body: 'hello' });
|
||||
for (const to of ['chief', 'assistant', 'pm', 'bean', 'quill'].filter((n) => n !== who)) {
|
||||
@@ -81,7 +84,7 @@ test('a creative instance sends only to the user and hears only from the user',
|
||||
for (const from of ['chief', 'pm']) {
|
||||
assert.throws(() => call(from, 'message.send', { to: who, body: 'hello' }), { code: 'message-sender-refused' }, `${from} to ${who}`);
|
||||
}
|
||||
- call('human', 'message.send', { to: who, body: 'hello' });
|
||||
+ call('human', 'thread.send', { thread: threads[who], body: 'hello' });
|
||||
}
|
||||
assert.equal(count("SELECT count(*) n FROM messages WHERE from_role IN ('bean','quill')"), 2);
|
||||
assert.equal(count("SELECT count(*) n FROM messages WHERE to_role IN ('bean','quill')"), 2);
|
||||
diff --git a/packages/bus/tests/grant-executor.test.mjs b/packages/bus/tests/grant-executor.test.mjs
|
||||
index e449b7d77..46235d16b 100644
|
||||
--- a/packages/bus/tests/grant-executor.test.mjs
|
||||
+++ b/packages/bus/tests/grant-executor.test.mjs
|
||||
@@ -1047,7 +1047,10 @@ test('sage-1908: once the agent of an applied grant is a creative role, host.run
|
||||
const f = await setup(t);
|
||||
assert.equal((await f.approve()).end.action, 'grant.applied');
|
||||
const r = await restart(t, f, creativeOps(f.business));
|
||||
- const cap = r.broker.bindLaunch({ business: 'demo', role: 'ops', run: 'ops-run', harness: 'pi', address: 'ops' });
|
||||
+ const human = r.broker.bindHuman({ business: 'demo', human: 'jason', via: 'cli', outsideAgent: true });
|
||||
+ const project = r.broker.request(human, { verb: 'project.create', args: { name: 'host grant check' } }).id;
|
||||
+ const thread = r.broker.request(human, { verb: 'thread.create', args: { project, name: 'ops', instance: 'ops' } }).id;
|
||||
+ const cap = r.broker.bindLaunch({ business: 'demo', role: 'ops', run: 'ops-run', harness: 'pi', address: 'ops', thread });
|
||||
r.broker.request(cap, { verb: 'role.claim' });
|
||||
const executor = hostExecutor({ credentials: r.credentials, root: join(f.dir, 'host-run') });
|
||||
const before = f.requests().length;
|
||||
diff --git a/packages/bus/tests/project-runtime.test.mjs b/packages/bus/tests/project-runtime.test.mjs
|
||||
index a6086e56c..7275ad902 100644
|
||||
--- a/packages/bus/tests/project-runtime.test.mjs
|
||||
+++ b/packages/bus/tests/project-runtime.test.mjs
|
||||
@@ -32,7 +32,8 @@ test('Broker keeps the sandbox client import closure: only the listed imports, n
|
||||
// (#1692, D2.4) reads unhireableAction, the hire veto's action name.
|
||||
// Row 236 (#1742, #436b) reads giteaName and parseGiteaUrl for the Gitea grant path.
|
||||
// FED R3 r5 (row 274, #414) reads covers, a user's grant check, from it.
|
||||
- "import { ID_PATTERN, THREAD_DEFINITION, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';",
|
||||
+ // Row 219 reads THREAD_DEFINITIONS from the same vocabulary for creative thread admission.
|
||||
+ "import { ID_PATTERN, THREAD_DEFINITIONS, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';",
|
||||
]);
|
||||
assert.doesNotMatch(source, /\bimport\s*\(/);
|
||||
assert.doesNotMatch(readFileSync(new URL('../src/landing.mjs', import.meta.url), 'utf8'), /\bimport\b/);
|
||||
diff --git a/packages/bus/tests/threads.test.mjs b/packages/bus/tests/threads.test.mjs
|
||||
index 27193a745..ae44fb66a 100644
|
||||
--- a/packages/bus/tests/threads.test.mjs
|
||||
+++ b/packages/bus/tests/threads.test.mjs
|
||||
@@ -601,3 +601,56 @@ test('project.create keeps unrelated names with and without a repository', t =>
|
||||
{ id: linked.id, name: 'work', repo: 'stack' },
|
||||
]);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: explicit creative instances bind independent threads, default sessions and holders', t => {
|
||||
+ const creative = ['companion', 'ideas', 'research', 'proofreader', 'fact-checker', 'continuity'];
|
||||
+ const extra = Object.fromEntries(creative.map((definition, i) => [`writer${i}`, { definition, authority: { withinRole: ['message.send'], crossRole: [] } }]));
|
||||
+ const ctx = setup(t, demo({ roles: { ...roles, ...extra }, definitions: {
|
||||
+ ...definitions, ...Object.fromEntries(creative.map(definition => [definition, { messaging: shipped(definition).messaging }])),
|
||||
+ } }));
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'Writing' }).id;
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: 'ambiguous' }), { code: 'thread-instance-ambiguous' });
|
||||
+ for (const [instance, role] of Object.entries(extra)) {
|
||||
+ const receipt = ctx.call('human', 'thread.create', { project, name: instance, instance });
|
||||
+ assert.equal(receipt.instance, instance);
|
||||
+ assert.equal(ctx.store.get('SELECT instance FROM threads WHERE id=?', receipt.id).instance, instance);
|
||||
+ assert.equal(ctx.store.get('SELECT instance FROM sessions WHERE thread=?', receipt.id).instance, instance);
|
||||
+ ctx.launch(instance, instance, { thread: receipt.id });
|
||||
+ assert.equal(ctx.claim(instance).thread, receipt.id);
|
||||
+ const sent = ctx.call('human', 'thread.send', { thread: receipt.id, body: `For ${instance}` });
|
||||
+ const read = ctx.call(instance, 'message.receive');
|
||||
+ assert.deepEqual(read.map(m => m.id), [sent.id], role.definition);
|
||||
+ assert.equal(ctx.threadOf(sent.id), receipt.id);
|
||||
+ assert.equal(ctx.store.get('SELECT count(*) n FROM role_claims WHERE role=?', instance).n, 0);
|
||||
+ assert.throws(() => ctx.call('human', 'message.send', { to: instance, body: 'No implicit thread' }),
|
||||
+ { code: 'thread-required-use-thread-send' });
|
||||
+ }
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), creative.length);
|
||||
+});
|
||||
+
|
||||
+test('C2-09a: explicit missing, non-thread and malformed selectors create no thread or session', t => {
|
||||
+ const ctx = setup(t);
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'Writing' }).id;
|
||||
+ for (const instance of ['not-declared', 'pm', 'coder'])
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: instance, instance }), { code: 'thread-instance-missing' });
|
||||
+ for (const instance of [null, 7, {}, [], '', 'bad name'])
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: 'bad', instance }), { code: 'invalid-request' });
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), 0);
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM sessions'), 0);
|
||||
+ const legacy = ctx.call('human', 'thread.create', { project, name: 'Default' });
|
||||
+ assert.equal(legacy.instance, 'assistant');
|
||||
+});
|
||||
+
|
||||
+
|
||||
+test('C2-09a: creative bindLaunch without a thread refuses thread-required', t => {
|
||||
+ const creative = ['companion', 'ideas', 'research', 'proofreader', 'fact-checker', 'continuity'];
|
||||
+ const extra = Object.fromEntries(creative.map((definition, i) => [`creative${i}`, { definition, authority: { withinRole: ['message.send'], crossRole: [] } }]));
|
||||
+ const ctx = setup(t, demo({ roles: { ...roles, ...extra }, definitions: {
|
||||
+ ...definitions, ...Object.fromEntries(creative.map(definition => [definition, {}])),
|
||||
+ } }));
|
||||
+ for (const instance of Object.keys(extra)) {
|
||||
+ assert.throws(() => ctx.launch(`unthreaded-${instance}`, instance), { code: 'thread-required' });
|
||||
+ }
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), 0);
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM role_claims'), 0);
|
||||
+});
|
||||
diff --git a/packages/bus/tests/user-principal.test.mjs b/packages/bus/tests/user-principal.test.mjs
|
||||
index 4dcd1ebeb..8471ddf85 100644
|
||||
--- a/packages/bus/tests/user-principal.test.mjs
|
||||
+++ b/packages/bus/tests/user-principal.test.mjs
|
||||
@@ -23,7 +23,7 @@ const grant = (over = {}) => ({
|
||||
});
|
||||
|
||||
// `processing` stands in for the halt switch, as lifecycle-verbs.test.mjs's T15 does.
|
||||
-function setup(t, { grants = [grant()], processing = null } = {}) {
|
||||
+function setup(t, { grants = [grant()], processing = null, threadRoles = {} } = {}) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'bus-user-principal-'));
|
||||
const store = new Store(root);
|
||||
t.after(() => {
|
||||
@@ -40,6 +40,7 @@ function setup(t, { grants = [grant()], processing = null } = {}) {
|
||||
roles: {
|
||||
chief: { definition: 'chief-of-staff', authority: { withinRole: ['message.send'], crossRole: [] } },
|
||||
assistant: { definition: 'assistant', authority: { withinRole: ['message.send'], crossRole: [] } },
|
||||
+ ...threadRoles,
|
||||
},
|
||||
definitions: { 'chief-of-staff': {}, assistant: { messaging: shipped('assistant').messaging } },
|
||||
},
|
||||
@@ -394,3 +395,21 @@ test('R3 r4: the chief\'s hire refuses an instance named user with the code it g
|
||||
test('R3 r4: a non-function access throws before the store is read', () => {
|
||||
assert.throws(() => new Broker({ store: null, businesses: { demo: {} }, access: 'access.json' }), /access must be a function/);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project', t => {
|
||||
+ const ctx = setup(t, { threadRoles: { bean: { definition: 'companion', authority: { withinRole: ['message.send'], crossRole: [] } } } });
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'shared' }).id;
|
||||
+ const privateProject = ctx.call('human', 'project.create', { name: 'private' }).id;
|
||||
+ ctx.access.doc.grants = [grant({ projects: [project] })];
|
||||
+ ctx.user('alice');
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project, name: 'blocked bean', instance: 'bean' }), 'access-refused');
|
||||
+ for (const id of [privateProject, '00000000-0000-4000-8000-000000000000'])
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project: id, name: 'blocked project', instance: 'assistant' }), 'access-refused');
|
||||
+ assert.equal(ctx.store.get('SELECT count(*) n FROM threads').n, 0);
|
||||
+ const allowed = ctx.call('alice', 'thread.create', { project, name: 'assistant work', instance: 'assistant' });
|
||||
+ assert.equal(allowed.instance, 'assistant');
|
||||
+ ctx.access.doc.grants = [grant({ projects: [project], instances: ['bean'] })];
|
||||
+ const bean = ctx.call('alice', 'thread.create', { project, name: 'bean work', instance: 'bean' });
|
||||
+ assert.equal(bean.instance, 'bean');
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project, name: 'old instance', instance: 'assistant' }), 'access-refused');
|
||||
+});
|
||||
diff --git a/packages/cli/src/launcher.mjs b/packages/cli/src/launcher.mjs
|
||||
index bfe55b61e..d8248284c 100644
|
||||
--- a/packages/cli/src/launcher.mjs
|
||||
+++ b/packages/cli/src/launcher.mjs
|
||||
@@ -53,7 +53,7 @@
|
||||
// session.json names it as gitSocket.
|
||||
//
|
||||
// Thread sessions (row 121, #1615). A thread instance (an instance whose
|
||||
-// role definition is the assistant) runs once per thread, never on its own:
|
||||
+// role definition is in THREAD_DEFINITIONS) runs once per thread, never on its own:
|
||||
// a launch from a session or --pm refuses thread-required. Every tick
|
||||
// (threadTickMs) the host asks the broker for the business's threads
|
||||
// (launch op threadsState) and:
|
||||
@@ -139,6 +139,7 @@ import { createServer } from "node:net";
|
||||
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync } from "node:fs";
|
||||
import { dirname, join, relative } from "node:path";
|
||||
import { configDir, loadBusiness, resolveInstance, systemVars } from "../../business/src/index.mjs";
|
||||
+import { THREAD_DEFINITIONS } from "../../business/src/vocabulary.mjs";
|
||||
import { limitHit } from "../../business/src/launch.mjs";
|
||||
import { BundleError, buildBundle, hasFallback, readSkills, sessionModel } from "../../harness/src/bundle.mjs";
|
||||
import { createLoader } from "../../plugins/src/loader.mjs";
|
||||
@@ -176,8 +177,6 @@ const STOP_TIMEOUT_MS = 30000;
|
||||
const LINE_MAX = 4096;
|
||||
// How often the host asks for the threads' state; a poll period, not a limit.
|
||||
const THREAD_TICK_MS = 2000;
|
||||
-// The broker's thread instance definition (packages/bus/src/broker.mjs).
|
||||
-const THREAD_DEFINITION = "assistant";
|
||||
// Row 194: the broker's LIFECYCLE_REQUEST_MS. A regenerate's old run must be gone by then.
|
||||
const LIFECYCLE_REQUEST_MS = 60000;
|
||||
|
||||
@@ -331,7 +330,7 @@ export function createLauncher({
|
||||
try { b=loadBusiness(host.business,{dir:configDir(env),rolesDir:rolesDir(env)}); } catch(e){throw new Refusal("organization-refused",e.message);}
|
||||
if (!b.launch) throw new Refusal("launch-not-configured", `business ${b.id} has no launch block`);
|
||||
if (!(pm ? instance === b.launch.by : b.launch.instances.includes(instance) || (human && Object.hasOwn(b.roles, instance)))) throw new Refusal("instance-not-listed");
|
||||
- const threaded = b.roles[instance]?.definition === THREAD_DEFINITION;
|
||||
+ const threaded = THREAD_DEFINITIONS.includes(b.roles[instance]?.definition);
|
||||
if (threaded && !thread) throw new Refusal("thread-required", `${instance} runs only for a thread`);
|
||||
if (!threaded && thread) throw new Refusal("thread-not-allowed", `${instance} isn't a thread instance`);
|
||||
if (threaded && !session) throw new Refusal("session-required", `${instance} runs for one session of a thread`);
|
||||
@@ -997,7 +996,7 @@ export function createLauncher({
|
||||
function ending(r) {
|
||||
const runs = r.runs ?? [];
|
||||
const at = Date.parse(r.at);
|
||||
- const threaded = b.roles[r.instance]?.definition === THREAD_DEFINITION;
|
||||
+ const threaded = THREAD_DEFINITIONS.includes(b.roles[r.instance]?.definition);
|
||||
return registry.sessions.filter((s) => s.business === b.id && (runs.includes(s.run) ||
|
||||
(!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..baabd843e 100644
|
||||
--- a/packages/cli/tests/launcher.test.mjs
|
||||
+++ b/packages/cli/tests/launcher.test.mjs
|
||||
@@ -773,21 +773,34 @@ 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 });
|
||||
- const { f, host, launcher } = await setup(t, undefined, given);
|
||||
- // The chief of staff holds role.launch; a test chief session bound to this process asks.
|
||||
- const chief = await host.bindLaunch({ business: "acme", role: "chief", run: "chief-test", harness: "pi", pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
- await new Client({ path: host.path, cap: chief.cap }).call("role.claim");
|
||||
- // The bundle's refusal comes back as launch-failed, as webPlan's does, with its reason in the log.
|
||||
- assert.deepEqual(await launcher.fromSession(chief.cap, "bean"), { ok: false, error: "launch-failed" });
|
||||
- const [e] = log(f);
|
||||
- assert.deepEqual([e.event, e.code, log(f).length], ["refused", "launch-failed", 1]);
|
||||
+ // 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, session: SESSION, instance: 'bean', holder: null, pending: 1 }])
|
||||
+ : host.op(message),
|
||||
+ }) });
|
||||
+ // The thread path records row 270's run-start count before the bundle's persona refusal.
|
||||
+ await launcher.tick();
|
||||
+ const runs = readdirSync(join(f.dataRoot, "launches", "acme"));
|
||||
+ const entries = log(f);
|
||||
+ assert.equal(entries.length, 2);
|
||||
+ const { at, ...compactions } = entries[0];
|
||||
+ assert.deepEqual(compactions, { event: 'compactions', instance: 'bean', thread, session: SESSION, run: runs[0], count: 0, known: true, reason: null });
|
||||
+ const e = entries[1];
|
||||
+ assert.deepEqual([e.event, e.code], ["refused", "launch-failed"]);
|
||||
+ assert.equal(e.thread, thread);
|
||||
assert.equal(e.why, `instance bean: persona file ${join(dir, "bean.md")} isn't the file persona.sha256 names`);
|
||||
assert.ok(!JSON.stringify(log(f)).includes("PERSONA-MARKER-d2"));
|
||||
assert.deepEqual(readSessions(f.dataRoot), []);
|
||||
// The run directory exists by then (BUILD.md residual); the persona is read before any bundle file.
|
||||
- const runs = readdirSync(join(f.dataRoot, "launches", "acme"));
|
||||
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, "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) => {
|
||||
diff --git a/packages/cli/tests/thread-launch.test.mjs b/packages/cli/tests/thread-launch.test.mjs
|
||||
index 0d207a0a0..fa3adb866 100644
|
||||
--- a/packages/cli/tests/thread-launch.test.mjs
|
||||
+++ b/packages/cli/tests/thread-launch.test.mjs
|
||||
@@ -396,6 +396,22 @@ test("REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a t
|
||||
assert.deepEqual(launchLog(f).map((e) => [e.event, e.instance, e.code]), [["refused", "assistant", "thread-required"]]);
|
||||
});
|
||||
|
||||
+// Admission refuses before bundle construction or a sandbox is needed.
|
||||
+test('C2-09a: fromSession refuses a creative instance outside a thread without a sandbox', { timeout: 30000 }, async t => {
|
||||
+ const prepared = prepare(t, { edit: doc => {
|
||||
+ doc.roles.bean = { ...doc.roles.assistant, definition: 'companion' };
|
||||
+ doc.launch.instances.push('bean');
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ const { f } = prepared;
|
||||
+ const host = await start(t, prepared);
|
||||
+ const chief = await host.host.bindLaunch({ business: 'acme', role: 'chief', run: 'chief-bean-refusal', harness: 'pi', pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
+ await new Client({ path: host.host.path, cap: chief.cap }).call('role.claim');
|
||||
+ assert.deepEqual(await host.launcher.fromSession(chief.cap, 'bean'), { ok: false, error: 'thread-required' });
|
||||
+ assert.deepEqual(readSessions(f.dataRoot), []);
|
||||
+ assert.deepEqual(launchLog(f).map(e => [e.event, e.instance, e.code]), [['refused', 'bean', 'thread-required']]);
|
||||
+});
|
||||
+
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the token-limit check switched on, with the
|
||||
// assistant's limit at 0, so it is at its limit before any turn. The real check runs through the
|
||||
// bus's plug-in loader.
|
||||
@@ -443,3 +459,73 @@ test("REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn:
|
||||
assert.deepEqual(threadRuns(f, A), []);
|
||||
assert.equal(host.runtime.threadsState("acme").find((x) => x.thread === A).holder, null);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: creative thread messages start distinct runs and keep each instance history separate', { skip, timeout: 90000 }, async t => {
|
||||
+ const prepared = prepare(t, { sonnet: 2, idle: 60, edit: doc => {
|
||||
+ const vars = { ...doc.roles.assistant.vars };
|
||||
+ delete doc.roles.assistant;
|
||||
+ doc.roles.bean = { definition: 'companion', vars: { ...vars } };
|
||||
+ doc.roles.chet = { definition: 'continuity', vars: { ...vars } };
|
||||
+ doc.launch.instances = ['coder', 'bean', 'chet'];
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ const host = await start(t, prepared), { f } = prepared;
|
||||
+ const project = host.call('project.create', { name: 'Writing' }).id;
|
||||
+ const bean = host.call('thread.create', { project, name: 'Bean', instance: 'bean' }).id;
|
||||
+ const chet = host.call('thread.create', { project, name: 'Chet', instance: 'chet' }).id;
|
||||
+ const send = async (thread, instance, body) => {
|
||||
+ const message = host.call('thread.send', { thread, body });
|
||||
+ const outcome = await until(() => host.call('thread.messages', { thread }).find(m => m.in_reply_to === message.id) ||
|
||||
+ launchLog(f).find(row => row.thread === thread && row.event === 'refused'));
|
||||
+ assert.notEqual(outcome.event, 'refused', `creative thread launch refused: ${outcome.code}`);
|
||||
+ const reply = outcome;
|
||||
+ assert.equal(reply.from_role, instance);
|
||||
+ assert.equal(reply.to_role, 'human');
|
||||
+ return JSON.parse(reply.body.match(/THREAD (\{.*\})/)[1]);
|
||||
+ };
|
||||
+ assert.deepEqual((await send(bean, 'bean', 'Bean input')).before, []);
|
||||
+ assert.deepEqual((await send(chet, 'chet', 'Chet input')).before, []);
|
||||
+ assert.deepEqual((await send(bean, 'bean', 'Bean again')).before, ['Bean input']);
|
||||
+ assert.equal(readFileSync(join(f.dataRoot, 'threads', 'acme', bean, 'sessions', host.runtime.threadsState('acme').find(x => x.thread === bean).session, 'session', 'history'), 'utf8'), 'Bean input\nBean again\n');
|
||||
+ assert.equal(readFileSync(join(f.dataRoot, 'threads', 'acme', chet, 'sessions', host.runtime.threadsState('acme').find(x => x.thread === chet).session, 'session', 'history'), 'utf8'), 'Chet input\n');
|
||||
+ assert.equal(existsSync(join(f.dataRoot, 'threads', 'acme', bean, 'session')), false);
|
||||
+ assert.equal(existsSync(join(f.dataRoot, 'threads', 'acme', chet, 'session')), false);
|
||||
+ const launches = launchLog(f).filter(row => row.event === 'launch');
|
||||
+ assert.ok(launches.some(row => row.instance === 'bean' && row.thread === bean));
|
||||
+ assert.ok(launches.some(row => row.instance === 'chet' && row.thread === chet));
|
||||
+ const chief = await host.host.bindLaunch({ business: 'acme', role: 'chief', run: 'chief-creative-test', harness: 'pi', pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
+ await new Client({ path: host.host.path, cap: chief.cap }).call('role.claim');
|
||||
+ assert.deepEqual(await host.launcher.fromSession(chief.cap, 'bean'), { ok: false, error: 'thread-required' });
|
||||
+});
|
||||
+
|
||||
+test('C2-09a: terminating one creative thread does not signal an unselected peer of the same instance', { skip, timeout: 90000 }, async t => {
|
||||
+ const prepared = prepare(t, { sonnet: 2, idle: 60, edit: doc => {
|
||||
+ doc.roles.bean = { ...doc.roles.assistant, definition: 'companion' };
|
||||
+ delete doc.roles.assistant;
|
||||
+ doc.launch.instances = ['coder', 'bean'];
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ let requests = [];
|
||||
+ const host = await start(t, prepared, { ops: () => ({
|
||||
+ lifecycleRequests: () => requests,
|
||||
+ lifecycleTake: () => ({ ...requests[0], go: true }),
|
||||
+ lifecycleDone: () => { requests = []; return {}; },
|
||||
+ }) });
|
||||
+ const { f } = prepared;
|
||||
+ const project = host.call('project.create', { name: 'Writing' }).id;
|
||||
+ const threads = ['one', 'two'].map(name => host.call('thread.create', { project, name, instance: 'bean' }).id);
|
||||
+ for (const thread of threads) {
|
||||
+ const message = host.call('thread.send', { thread, body: 'Stay in this thread' });
|
||||
+ const outcome = await until(() => host.call('thread.messages', { thread }).find(row => row.in_reply_to === message.id) ||
|
||||
+ launchLog(f).find(row => row.thread === thread && row.event === 'refused'));
|
||||
+ assert.notEqual(outcome.event, 'refused', `creative thread launch refused: ${outcome.code}`);
|
||||
+ }
|
||||
+ const runs = threads.map(thread => launchLog(f).find(row => row.thread === thread && row.event === 'launch').run);
|
||||
+ requests = [{ request: 'one-thread-end', state: 'open', business: 'acme', action: 'lifecycle.end',
|
||||
+ instance: 'bean', runs: [runs[0]], by: f.doc.human, at: new Date(Date.now() + 1000).toISOString() }];
|
||||
+ await host.launcher.tick();
|
||||
+ await until(() => launchLog(f).some(row => row.event === 'lifecycle-end' && row.run === runs[0]));
|
||||
+ assert.deepEqual(launchLog(f).filter(row => row.event === 'lifecycle-end').map(row => row.run), [runs[0]]);
|
||||
+ await until(() => !readSessions(f.dataRoot).some(row => row.run === runs[0]));
|
||||
+ assert.ok(readSessions(f.dataRoot).some(row => row.run === runs[1]));
|
||||
+});
|
||||
diff --git a/packages/webui/src/chat-http.mjs b/packages/webui/src/chat-http.mjs
|
||||
index 7980c1442..63d3ca974 100644
|
||||
--- a/packages/webui/src/chat-http.mjs
|
||||
+++ b/packages/webui/src/chat-http.mjs
|
||||
@@ -80,7 +80,8 @@ export async function chatHTTP(req, res, { path, search, chat, named, send, prev
|
||||
(Object.hasOwn(v, 'repo') && (typeof v.repo !== 'string' || !KEY.test(v.repo)))) throw Error();
|
||||
action = 'createProject'; args = v;
|
||||
} else if (path === '/api/chat/threads') {
|
||||
- if (!exact(v, ['project', 'name']) || !id(v.project) || !name(v.name)) throw Error();
|
||||
+ if (!exact(v, ['project', 'name', 'instance'], ['project', 'name']) || !id(v.project) || !name(v.name) ||
|
||||
+ (Object.hasOwn(v, 'instance') && (typeof v.instance !== 'string' || !KEY.test(v.instance)))) throw Error();
|
||||
action = 'createThread'; args = v;
|
||||
} else if (match?.[2] === 'messages') {
|
||||
if (!exact(v, ['body']) || typeof v.body !== 'string' || !v.body.trim() || v.body.length > 32768) throw Error();
|
||||
diff --git a/packages/webui/src/chat.mjs b/packages/webui/src/chat.mjs
|
||||
index 1b0a41dce..5a1ed8bf1 100644
|
||||
--- a/packages/webui/src/chat.mjs
|
||||
+++ b/packages/webui/src/chat.mjs
|
||||
@@ -25,7 +25,7 @@ export function createChat({ call, owner = null }) {
|
||||
projects: () => channel('project.list', {}),
|
||||
createProject: ({ name, repo }) => channel('project.create', { name, ...(repo === undefined ? {} : { repo }) }),
|
||||
threads: ({ project } = {}) => channel('thread.list', project === undefined ? {} : { project }),
|
||||
- createThread: ({ project, name }) => channel('thread.create', { project, name }),
|
||||
+ createThread: ({ project, name, instance }) => channel('thread.create', { project, name, ...(instance === undefined ? {} : { instance }) }),
|
||||
messages: ({ thread, after, limit }) => channel('thread.messages', { thread, ...(after ? { after } : {}), limit }),
|
||||
send: ({ thread, body }) => channel('thread.send', { thread, body, class: 'REQUEST' }),
|
||||
open: ({ thread }) => channel('thread.open', { thread }),
|
||||
diff --git a/packages/webui/src/public/chat.js b/packages/webui/src/public/chat.js
|
||||
index a6b805c1b..15066bdc6 100644
|
||||
--- a/packages/webui/src/public/chat.js
|
||||
+++ b/packages/webui/src/public/chat.js
|
||||
@@ -14,7 +14,7 @@
|
||||
return states.get(id);
|
||||
};
|
||||
const form = key => {
|
||||
- if (!forms.has(key)) forms.set(key, { name: '', repo: '', receipt: '', pending: false });
|
||||
+ if (!forms.has(key)) forms.set(key, { name: '', repo: '', instance: '', instanceChosen: false, receipt: '', pending: false });
|
||||
return forms.get(key);
|
||||
};
|
||||
class ChatError extends Error {
|
||||
@@ -58,7 +58,11 @@
|
||||
function creation(kind, key) {
|
||||
const f = form(key), project = kind === 'project';
|
||||
const repo = project && current.repos.length ? `<label>Repository (optional)<select id="chat-repo" data-chat-field="repo"><option value="">No repository link</option>${current.repos.map(r => `<option value="${esc(r)}"${r === f.repo ? ' selected' : ''}>${txt(r)}</option>`).join('')}</select></label>` : '';
|
||||
- return `<form id="chat-${kind}-form" class="chat-create" data-key="${esc(key)}"><h2>New ${kind}</h2><label>Name<input id="chat-${kind}-name" data-chat-field="name" value="${esc(f.name)}" maxlength="200" required${disabled(f.pending)}></label>${repo}<button class="btn" type="submit"${disabled(f.pending)}>${f.pending ? 'Creating…' : `Create ${kind}`}</button><p role="status">${txt(f.receipt)}</p></form>`;
|
||||
+ const choices = current.instances ?? [];
|
||||
+ const picker = project ? '' : `<label>Thread with<select id="chat-instance" data-chat-field="instance" required${disabled(f.pending || !!current.instanceError || !choices.length)}><option value="">Choose who this thread is with</option>${choices.map(row => `<option value="${esc(row.instance)}"${row.instance === f.instance ? ' selected' : ''}>${txt(row.name === row.instance ? row.instance : `${row.name} (${row.instance})`)}</option>`).join('')}</select></label>`;
|
||||
+ const unavailable = !project && (!!current.instanceError || !choices.some(row => row.instance === f.instance));
|
||||
+ const status = !project && current.instanceError ? current.instanceError : f.receipt || (!project && !choices.length ? 'No thread instances are configured.' : '');
|
||||
+ return `<form id="chat-${kind}-form" class="chat-create" data-key="${esc(key)}"><h2>New ${kind}</h2><label>Name<input id="chat-${kind}-name" data-chat-field="name" value="${esc(f.name)}" maxlength="200" required${disabled(f.pending)}></label>${repo}${picker}<button class="btn" type="submit"${disabled(f.pending || unavailable)}>${f.pending ? 'Creating…' : `Create ${kind}`}</button><p role="status">${txt(status)}</p></form>`;
|
||||
}
|
||||
function threads(rows) {
|
||||
return rows.length ? `<ul class="chat-thread-list">${rows.map(t => `<li>${link('threads', t.id, t.name)} <span class="muted">${txt(t.instance)}</span></li>`).join('')}</ul>` : '<p>No threads yet.</p>';
|
||||
@@ -106,7 +110,7 @@
|
||||
const f = document.getElementById(keep.field.id);
|
||||
if (f && !f.disabled) {
|
||||
f.focus({ preventScroll: true });
|
||||
- if (keep.field.start !== null) f.setSelectionRange(keep.field.start, keep.field.end);
|
||||
+ if (keep.field.start != null && typeof f.setSelectionRange === 'function') f.setSelectionRange(keep.field.start, keep.field.end);
|
||||
}
|
||||
} else if (navigated) c.container.querySelector('h1')?.focus({ preventScroll: true });
|
||||
}
|
||||
@@ -126,7 +130,7 @@
|
||||
paint(); return;
|
||||
}
|
||||
const old = current;
|
||||
- current = { container, kind, id, canSend, projects: old?.projects ?? [], threads: old?.threads ?? [], repos: old?.repos ?? [], error: '', refused: false };
|
||||
+ current = { container, kind, id, canSend, projects: old?.projects ?? [], threads: old?.threads ?? [], repos: old?.repos ?? [], instances: old?.instances ?? [], instanceError: kind === 'project' ? 'Reading thread instances…' : '', error: '', refused: false };
|
||||
if (navigated || !old) container.innerHTML = '<p class="chat-loading" role="status">Reading chat…</p>';
|
||||
try {
|
||||
const s = kind === 'thread' ? state(id) : null;
|
||||
@@ -147,6 +151,25 @@
|
||||
s.receipt = 'Message shown in this conversation.'; s.receiptId = null;
|
||||
}
|
||||
}
|
||||
+ if (kind === 'project') {
|
||||
+ try {
|
||||
+ const listed = await request('instances', undefined, signal);
|
||||
+ if (g !== generation || out()) return;
|
||||
+ if (!listed.rows.every(row => typeof row?.instance === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,159}$/.test(row.instance) && typeof row.name === 'string'))
|
||||
+ throw new ChatError('invalid-response');
|
||||
+ current.instances = listed.rows; current.instanceError = '';
|
||||
+ const f = form(id);
|
||||
+ if (f.instance && !listed.rows.some(row => row.instance === f.instance)) {
|
||||
+ f.instance = ''; f.instanceChosen = true;
|
||||
+ f.receipt = 'The selected instance is no longer available. Choose who this thread is with.';
|
||||
+ }
|
||||
+ if (!f.instanceChosen && !f.instance && listed.rows.length === 1) f.instance = listed.rows[0].instance;
|
||||
+ } catch (err) {
|
||||
+ if (err.name === 'AbortError' || out() || g !== generation) return;
|
||||
+ current.instances = [];
|
||||
+ current.instanceError = "Couldn't read the thread instances; reload to try again";
|
||||
+ }
|
||||
+ }
|
||||
// Repository choices are optional metadata; an unavailable read must not block unlinked chat.
|
||||
if (kind === 'list') {
|
||||
try {
|
||||
@@ -179,7 +202,11 @@
|
||||
if (!current || out()) return;
|
||||
if (event.target.id === 'chat-body') state(current.id).draft = event.target.value;
|
||||
const f = event.target.closest('.chat-create');
|
||||
- if (f && event.target.dataset.chatField) form(f.dataset.key)[event.target.dataset.chatField] = event.target.value;
|
||||
+ if (f && event.target.dataset.chatField) {
|
||||
+ const draft = form(f.dataset.key), field = event.target.dataset.chatField;
|
||||
+ draft[field] = event.target.value;
|
||||
+ if (field === 'instance') { draft.instanceChosen = true; draft.receipt = ''; paint(); }
|
||||
+ }
|
||||
});
|
||||
document.addEventListener('scroll', event => {
|
||||
if (event.target.matches?.('.chat-log') && current?.kind === 'thread') {
|
||||
@@ -232,7 +259,8 @@
|
||||
void write('send', id, { body: state(id).draft }, `threads/${id}/messages`);
|
||||
} else if (event.target.classList.contains('chat-create')) {
|
||||
const key = event.target.dataset.key, f = form(key), project = key === 'projects';
|
||||
- const value = project ? { name: f.name, ...(f.repo ? { repo: f.repo } : {}) } : { project: key, name: f.name };
|
||||
+ if (!project && (current.instanceError || !(current.instances ?? []).some(row => row.instance === f.instance))) return;
|
||||
+ const value = project ? { name: f.name, ...(f.repo ? { repo: f.repo } : {}) } : { project: key, name: f.name, instance: f.instance };
|
||||
void write(project ? 'createProject' : 'createThread', key, value, project ? 'projects' : 'threads');
|
||||
}
|
||||
});
|
||||
diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs
|
||||
index cd51a0b6e..56fcdd4e1 100644
|
||||
--- a/packages/webui/src/serve.mjs
|
||||
+++ b/packages/webui/src/serve.mjs
|
||||
@@ -8,6 +8,7 @@ import { BusReadError, busStatus as coreBusStatus, subjectOk, sendOutcome } from
|
||||
// Row 176, sage-1111: HTTP-only tester refusals; the row-164 transport pin stays untouched.
|
||||
const busStatus = code => ['tester-off', 'tester-required'].includes(code) ? 403 : coreBusStatus(code);
|
||||
import { ReadError, readStatus, fieldTable } from './reads.mjs';
|
||||
+import { THREAD_DEFINITIONS } from '../../business/src/vocabulary.mjs';
|
||||
import { chatHTTP } from './chat-http.mjs';
|
||||
import { processingHTTP } from './processing-http.mjs';
|
||||
|
||||
@@ -740,6 +741,25 @@ export async function startServer({ host = '127.0.0.1', port = 7330, board = DEF
|
||||
if (req.method !== 'POST') return json(res, 405, { error: 'method not allowed' });
|
||||
return busSend(req, res, { send, preview: signer, log });
|
||||
}
|
||||
+ // Row 219: labels only, from this listener's own human or tester bus, after auth above.
|
||||
+ if (path === '/api/chat/instances') {
|
||||
+ if (req.method !== 'GET') return json(res, 405, { error: 'method-not-allowed' });
|
||||
+ if (search) return json(res, 400, { error: 'invalid-request' });
|
||||
+ if (!bus?.instances) return json(res, 503, { error: 'not-configured' });
|
||||
+ try {
|
||||
+ const value = await bus.instances();
|
||||
+ if (!value || !value.instances || typeof value.instances !== 'object' || Array.isArray(value.instances))
|
||||
+ throw new BusReadError('invalid-response');
|
||||
+ const rows = Object.entries(value.instances)
|
||||
+ .filter(([, entry]) => THREAD_DEFINITIONS.includes(entry?.definition))
|
||||
+ .map(([instance, entry]) => ({ instance, name: entry.vars?.['persona.name'] || instance }));
|
||||
+ if (rows.some(row => typeof row.name !== 'string')) throw new BusReadError('invalid-response');
|
||||
+ return json(res, 200, { rows, at: new Date().toISOString() });
|
||||
+ } catch (err) {
|
||||
+ const code = err instanceof BusReadError ? err.code : 'invalid-response';
|
||||
+ return json(res, busStatus(code), { error: code });
|
||||
+ }
|
||||
+ }
|
||||
if (path === '/api/chat' || path.startsWith('/api/chat/')) {
|
||||
return chatHTTP(req, res, { path, search, chat, named, send, preview: writer, log });
|
||||
}
|
||||
diff --git a/packages/webui/tests/chat-browser.test.mjs b/packages/webui/tests/chat-browser.test.mjs
|
||||
index f3eeeca96..cc3ec093d 100644
|
||||
--- a/packages/webui/tests/chat-browser.test.mjs
|
||||
+++ b/packages/webui/tests/chat-browser.test.mjs
|
||||
@@ -12,6 +12,7 @@ const HOSTILE = '<img src=x onerror="window.injected=1">\u001b[31m\u202eevil';
|
||||
const stub = `(() => {
|
||||
const real = fetch.bind(window);
|
||||
window.__writes=[];window.__reads=[];window.__answers=[];window.__pages=[];
|
||||
+ window.__instances=[{instance:'assistant',name:'assistant'}];
|
||||
window.__projects=[{id:'${P}', name:${JSON.stringify(HOSTILE)}, repo:null},{id:'\"><img src=x>',name:'Invalid record'}];
|
||||
window.__threads=[{id:'${A}',project:'${P}',name:'alpha',instance:'assistant'}, {id:'${B}',project:'${P}',name:'beta',instance:'assistant'}];
|
||||
window.fetch=async (url,init={})=>{
|
||||
@@ -33,6 +34,7 @@ const stub = `(() => {
|
||||
window.__reads.push(path);
|
||||
if(window.__holdRead && path.includes(window.__holdRead)){window.__heldSignal=init.signal;await new Promise(r=>window.__releaseRead=r);}
|
||||
if(window.__readFailure)return new Response(JSON.stringify({error:window.__readFailure}),{status:window.__readFailure==='thread-not-owned'?403:503});
|
||||
+ if(path==='/api/chat/instances')return window.__instanceFailure ? new Response(JSON.stringify({error:'not-configured'}),{status:503}) : data({rows:window.__instances});
|
||||
if(path==='/api/chat/projects')return data({rows:window.__projects});
|
||||
if(path.startsWith('/api/chat/threads')&&!path.includes('/messages'))return data({rows:window.__threads});
|
||||
if(window.__pages.length)return data(window.__pages.shift());
|
||||
@@ -82,7 +84,7 @@ test('chat browser: list/create named projects and threads, hostile labels inert
|
||||
await b.evaluate(`window.__answers.push({body:{id:'${A}',instance:'assistant'}}),true`);
|
||||
await click('#chat-thread-form button[type=submit]');
|
||||
await wait('document.querySelector("#chat-send-form")');
|
||||
- assert.deepEqual(await b.evaluate('window.__writes[1].body'), { project: P, name: 'named thread' });
|
||||
+ assert.deepEqual(await b.evaluate('window.__writes[1].body'), { project: P, name: 'named thread', instance: 'assistant' });
|
||||
assert.equal(await b.evaluate('window.__writes[1].path'), '/api/chat/threads');
|
||||
assert.equal(await b.evaluate('window.__writes.length'), 2);
|
||||
});
|
||||
@@ -264,3 +266,65 @@ test('chat browser: a late project creation receipt cannot navigate away from an
|
||||
assert.equal(await b.evaluate('location.hash'), '#/chat/threads/' + A);
|
||||
assert.equal(await b.evaluate('document.querySelector("#chat-body").value'), 'stay in alpha');
|
||||
});
|
||||
+
|
||||
+test('C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST', async t => {
|
||||
+ const { b, wait, set, click, refresh } = await setup(t);
|
||||
+ await b.evaluate(`window.__instances=[{instance:'bean',name:${JSON.stringify(HOSTILE)}},{instance:'chet',name:${JSON.stringify(HOSTILE)}}];location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelectorAll("#chat-instance option").length===3');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").required'), true);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ const labels = await b.evaluate('[...document.querySelectorAll("#chat-instance option")].map(o=>o.textContent)');
|
||||
+ assert.match(labels[1], /\(bean\)/);
|
||||
+ assert.match(labels[2], /\(chet\)/);
|
||||
+ assert.doesNotMatch(labels.join(''), /[\u202a-\u202e\u2066-\u2069]/u);
|
||||
+ assert.equal(await b.evaluate('!!document.querySelector("#chat-thread-form img")'), false);
|
||||
+ assert.equal(await b.evaluate('window.injected'), undefined);
|
||||
+ await set('#chat-thread-name', 'Bean discussion');
|
||||
+ await click('#chat-thread-form button');
|
||||
+ assert.equal(await b.evaluate('window.__writes.length'), 0);
|
||||
+ await set('#chat-instance', 'bean');
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), 'bean');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-name").value'), 'Bean discussion');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), false);
|
||||
+ await b.evaluate(`window.__answers.push({body:{id:'${A}',instance:'bean'}});true`);
|
||||
+ await click('#chat-thread-form button');
|
||||
+ await wait('window.__writes.length===1');
|
||||
+ assert.deepEqual(await b.evaluate('window.__writes[0]'), { path: '/api/chat/threads', body: { project: P, name: 'Bean discussion', instance: 'bean' }, redirect: 'manual' });
|
||||
+});
|
||||
+
|
||||
+test('C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching', async t => {
|
||||
+ const { b, wait, set, refresh } = await setup(t);
|
||||
+ await b.evaluate(`window.__instanceFailure=true;location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelector("#chat-thread-form") && !document.querySelector(".chat-loading")');
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /read the thread instances/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await b.evaluate('window.__instanceFailure=false;window.__instances=[];true');
|
||||
+ await refresh();
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /No thread instances/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await b.evaluate("window.__instances=[{instance:'bean',name:'Bean'},{instance:'chet',name:'Chet'}];true");
|
||||
+ await refresh();
|
||||
+ await set('#chat-instance', 'bean');
|
||||
+ await b.evaluate("window.__instances=[{instance:'chet',name:'Chet'}];true");
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '');
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /no longer available/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '', 'another refresh must not silently select the one remaining instance');
|
||||
+ await set('#chat-instance', 'chet');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), false);
|
||||
+});
|
||||
+
|
||||
+test('C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread', async t => {
|
||||
+ const { b, wait } = await setup(t, '?readonly');
|
||||
+ await b.evaluate(`location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelectorAll("#chat-instance option").length===2');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), 'assistant');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").disabled'), true);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ assert.match(await b.evaluate('document.querySelector(".chat-area").textContent'), /only reads/);
|
||||
+ assert.equal(await b.evaluate('window.__writes.length'), 0);
|
||||
+});
|
||||
diff --git a/packages/webui/tests/chat-instances.test.mjs b/packages/webui/tests/chat-instances.test.mjs
|
||||
new file mode 100644
|
||||
index 000000000..893c38f80
|
||||
--- /dev/null
|
||||
+++ b/packages/webui/tests/chat-instances.test.mjs
|
||||
@@ -0,0 +1,87 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { request } from 'node:http';
|
||||
+import { mkdtempSync, rmSync } from 'node:fs';
|
||||
+import { join } from 'node:path';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { startServer } from '../src/serve.mjs';
|
||||
+import { startTesterSocket, TESTER_ORIGIN } from '../src/tester-socket.mjs';
|
||||
+import { close } from './fixture.mjs';
|
||||
+
|
||||
+const path = '/api/chat/instances';
|
||||
+const preview = { host: 'chat.example', header: 'x-user', user: 'jason' };
|
||||
+const snapshot = {
|
||||
+ revision: 'a'.repeat(64), plugins: { private: 'do-not-project' },
|
||||
+ instances: {
|
||||
+ assistant: { definition: 'assistant', vars: { model: 'private-model' } },
|
||||
+ bean: { definition: 'companion', vars: { 'persona.name': 'Bean', 'persona.sha256': 'private-hash' } },
|
||||
+ chet: { definition: 'continuity', vars: { 'persona.name': 'Bean', file: '/private/path' } },
|
||||
+ pm: { definition: 'pm', vars: { 'persona.name': 'Hidden PM' } },
|
||||
+ },
|
||||
+};
|
||||
+function get(server, { route = path, method = 'GET', headers = {} } = {}) {
|
||||
+ const address = server.address(), unix = typeof address === 'string';
|
||||
+ return new Promise((resolve, reject) => {
|
||||
+ const req = request({ ...(unix ? { socketPath: address } : { host: '127.0.0.1', port: address.port }),
|
||||
+ path: route, method, headers: { host: unix ? new URL(TESTER_ORIGIN).host : preview.host, ...headers } }, res => {
|
||||
+ let text = '';
|
||||
+ res.on('data', chunk => text += chunk);
|
||||
+ res.on('end', () => resolve({ status: res.statusCode, text, value: JSON.parse(text) }));
|
||||
+ });
|
||||
+ req.on('error', reject); req.end();
|
||||
+ });
|
||||
+}
|
||||
+test('C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads', async t => {
|
||||
+ let calls = 0;
|
||||
+ const server = await startServer({ port: 0, preview, bus: { instances: async () => { calls++; return snapshot; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const refused = await get(server);
|
||||
+ assert.equal(refused.status, 401);
|
||||
+ assert.equal(calls, 0);
|
||||
+ const answer = await get(server, { headers: { 'x-user': 'jason' } });
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(answer.value.rows, [{ instance: 'assistant', name: 'assistant' }, { instance: 'bean', name: 'Bean' }, { instance: 'chet', name: 'Bean' }]);
|
||||
+ for (const row of answer.value.rows) assert.deepEqual(Object.keys(row).sort(), ['instance', 'name']);
|
||||
+ assert.doesNotMatch(answer.text, /private|Hidden PM/);
|
||||
+ assert.equal(calls, 1);
|
||||
+ for (const options of [{ route: path + '?extra=1' }, { method: 'POST' }]) {
|
||||
+ const result = await get(server, { ...options, headers: { 'x-user': 'jason' } });
|
||||
+ assert.ok([400, 405].includes(result.status));
|
||||
+ }
|
||||
+ assert.equal(calls, 1, 'invalid metadata requests never call a bus');
|
||||
+});
|
||||
+test('C2-09a metadata uses the private tester listener own bus and no human transport', async t => {
|
||||
+ const root = mkdtempSync(join(tmpdir(), 'chat219-')); t.after(() => rmSync(root, { recursive: true, force: true }));
|
||||
+ let reads = 0;
|
||||
+ const server = await startTesterSocket({ dataRoot: root, board: 'http://127.0.0.1:9',
|
||||
+ bus: { instances: async () => { reads++; return { instances: { quill: { definition: 'proofreader', vars: { 'persona.name': 'Quill' } } } }; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const answer = await get(server);
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(answer.value.rows, [{ instance: 'quill', name: 'Quill' }]);
|
||||
+ assert.equal(reads, 1);
|
||||
+});
|
||||
+test('C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields', async t => {
|
||||
+ for (const bus of [null, { instances: async () => ({ instances: [] }) }, { instances: async () => { throw new Error('private-path'); } }]) {
|
||||
+ const server = await startServer({ port: 0, preview, bus }); t.after(() => close(server));
|
||||
+ const answer = await get(server, { headers: { 'x-user': 'jason' } });
|
||||
+ assert.ok(answer.status >= 400);
|
||||
+ assert.doesNotMatch(answer.text, /private-path/);
|
||||
+ }
|
||||
+});
|
||||
+
|
||||
+test('C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity', async t => {
|
||||
+ let session = null, reads = 0;
|
||||
+ const touches = [];
|
||||
+ const sso = { publicHost: 'sso-chat.example', publicOrigin: 'https://sso-chat.example', formTargets: () => [],
|
||||
+ session: (_req, { touch }) => { touches.push(touch); return session; } };
|
||||
+ const server = await startServer({ port: 0, sso, bus: { instances: async () => { reads++; return snapshot; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const headers = { host: sso.publicHost };
|
||||
+ assert.equal((await get(server, { headers })).status, 401);
|
||||
+ assert.equal(reads, 0);
|
||||
+ session = { name: 'jason' };
|
||||
+ assert.equal((await get(server, { headers })).status, 200);
|
||||
+ assert.equal(reads, 1);
|
||||
+ assert.deepEqual(touches, [false, false]);
|
||||
+});
|
||||
diff --git a/packages/webui/tests/chat.test.mjs b/packages/webui/tests/chat.test.mjs
|
||||
index 8c11611cf..b47ecf1a7 100644
|
||||
--- a/packages/webui/tests/chat.test.mjs
|
||||
+++ b/packages/webui/tests/chat.test.mjs
|
||||
@@ -335,3 +335,21 @@ test('the chat seam names the transport it is given: the human one and the teste
|
||||
assert.throws(() => createChat({}), { name: 'TypeError', message: 'chat needs a bus transport function' });
|
||||
assert.equal(typeof createChat({ call: async () => ({}) }).projects, 'function');
|
||||
});
|
||||
+
|
||||
+test('C2-09a createThread forwards an explicit instance through the existing channel', async t => {
|
||||
+ const c = await setup(t);
|
||||
+ c.state.answer = { id: T, instance: 'bean' };
|
||||
+ const answer = await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'Bean work', instance: 'bean' } });
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(c.calls, [['thread.create', { project: P, name: 'Bean work', instance: 'bean' }]]);
|
||||
+ assert.equal(answer.data.instance, 'bean');
|
||||
+});
|
||||
+test('C2-09a malformed instance and extra thread fields refuse before the channel write', async t => {
|
||||
+ const c = await setup(t);
|
||||
+ for (const value of [null, 7, {}, [], '', 'bad name', 'bean/../../other']) {
|
||||
+ const answer = await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'work', instance: value } });
|
||||
+ assert.equal(answer.status, 400, JSON.stringify(value));
|
||||
+ }
|
||||
+ assert.equal((await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'work', instance: 'bean', extra: true } })).status, 400);
|
||||
+ assert.deepEqual(c.calls, []);
|
||||
+});
|
||||
@@ -0,0 +1,16 @@
|
||||
f21daf94d057341f8f9f55ec65fcc16a7d6774311c1ca5b1ab336fc2a9e086e2 packages/bus/src/broker.mjs
|
||||
b0c66c8999b567896923f6c876911dba936c6eca1ccc7aaeada51369fd613594 packages/bus/tests/creative.test.mjs
|
||||
3efd0238da60e0bfcd3b25e5256b9c213085119a86a7b852b13e7a60340d3a24 packages/bus/tests/grant-executor.test.mjs
|
||||
b7ea857637947c7a9ca45c56cea47e37e06f0fd8446ea91316990d9fa7299a7a packages/bus/tests/project-runtime.test.mjs
|
||||
760c4a5dc2881a47be2a174f92c4fcb1b6e46abb299cb045a2e3dcbc485fb334 packages/bus/tests/threads.test.mjs
|
||||
8f7d6745fffb2a0898ac80c012084ac48964748da6439a8c56facc6529ffb19b packages/bus/tests/user-principal.test.mjs
|
||||
b74275ce43249bafc97edc87a6a3aa0431c62fe1a28cd9fa265246e6d6da219b packages/cli/src/launcher.mjs
|
||||
2c3f120dfdc0b52bf8ab38a88e86251be75d4b0d218e23df489dcaf815d6bc15 packages/cli/tests/launcher.test.mjs
|
||||
7f308fdf601e839194f026beb3fea279eba1e356ce2756aa4a42fa4873b79b30 packages/cli/tests/thread-launch.test.mjs
|
||||
39c6d207e026debb7db8aade5534503847d0f5c84d560ba28f3cd65490378363 packages/webui/src/chat-http.mjs
|
||||
77878dd33fd9e0381deb996969389dde21c109eaddf46a8a5c91907ec0dfe24e packages/webui/src/chat.mjs
|
||||
8e89df5fe8a9da35de41b5968afc6efcd92503e92ef28c6f557bb5371d10d1a4 packages/webui/src/public/chat.js
|
||||
443c83debe21559de2e4a6bcc07514bce9bebe209df58b8011827fcc1cabd905 packages/webui/src/serve.mjs
|
||||
d918e5b061ced9db28337a9b02c7042f9ddafaf09f32affce9f51190c0cba93f packages/webui/tests/chat-browser.test.mjs
|
||||
2bad14535372488de326b82b791b79a61e1a4ab839458535132958ef85b746eb packages/webui/tests/chat-instances.test.mjs
|
||||
7779d33d5b1dd3fe183722d0f91ff1f71e741e113cf2d5ee407f3d26428fc162 packages/webui/tests/chat.test.mjs
|
||||
@@ -0,0 +1,16 @@
|
||||
packages/bus/src/broker.mjs
|
||||
packages/bus/tests/creative.test.mjs
|
||||
packages/bus/tests/grant-executor.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/bus/tests/threads.test.mjs
|
||||
packages/bus/tests/user-principal.test.mjs
|
||||
packages/cli/src/launcher.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/thread-launch.test.mjs
|
||||
packages/webui/src/chat-http.mjs
|
||||
packages/webui/src/chat.mjs
|
||||
packages/webui/src/public/chat.js
|
||||
packages/webui/src/serve.mjs
|
||||
packages/webui/tests/chat-browser.test.mjs
|
||||
packages/webui/tests/chat-instances.test.mjs
|
||||
packages/webui/tests/chat.test.mjs
|
||||
@@ -0,0 +1,56 @@
|
||||
START single-bus-creative.test 2026-10-23T09:21:11.124448+00:00
|
||||
END {"label": "single-bus-creative.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T09:21:11.124448+00:00", "end": "2026-10-23T09:21:11.489626+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rE8UFj4"}
|
||||
START single-bus-grant-executor.test 2026-10-23T09:21:11.492089+00:00
|
||||
END {"label": "single-bus-grant-executor.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T09:21:11.492089+00:00", "end": "2026-10-23T09:21:33.052545+00:00", "seconds": 21.56, "exit": 0, "timeout": false, "counts": {"tests": 42, "pass": 42, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-grant-executor.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rgY53eZ"}
|
||||
START single-bus-project-runtime.test 2026-10-23T09:21:33.054938+00:00
|
||||
END {"label": "single-bus-project-runtime.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/project-runtime.test.mjs"], "start": "2026-10-23T09:21:33.054938+00:00", "end": "2026-10-23T09:21:33.469616+00:00", "seconds": 0.415, "exit": 0, "timeout": false, "counts": {"tests": 3, "pass": 3, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-project-runtime.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rlFp4K6"}
|
||||
START single-bus-threads.test 2026-10-23T09:21:33.471762+00:00
|
||||
END {"label": "single-bus-threads.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T09:21:33.471762+00:00", "end": "2026-10-23T09:21:34.838718+00:00", "seconds": 1.367, "exit": 0, "timeout": false, "counts": {"tests": 20, "pass": 20, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rshM4G7"}
|
||||
START single-bus-user-principal.test 2026-10-23T09:21:34.841038+00:00
|
||||
END {"label": "single-bus-user-principal.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T09:21:34.841038+00:00", "end": "2026-10-23T09:21:35.456433+00:00", "seconds": 0.615, "exit": 0, "timeout": false, "counts": {"tests": 23, "pass": 23, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYf1Xvx"}
|
||||
START single-cli-launcher.test 2026-10-23T09:21:35.458772+00:00
|
||||
END {"label": "single-cli-launcher.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T09:21:35.458772+00:00", "end": "2026-10-23T09:22:02.030225+00:00", "seconds": 26.571, "exit": 0, "timeout": false, "counts": {"tests": 34, "pass": 34, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/raf1e60"}
|
||||
START single-cli-thread-launch.test 2026-10-23T09:22:02.032690+00:00
|
||||
END {"label": "single-cli-thread-launch.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T09:22:02.032690+00:00", "end": "2026-10-23T09:22:20.094607+00:00", "seconds": 18.062, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-cli-thread-launch.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r1Bsuqs"}
|
||||
START single-webui-chat-browser.test 2026-10-23T09:22:20.097013+00:00
|
||||
END {"label": "single-webui-chat-browser.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T09:22:20.097013+00:00", "end": "2026-10-23T09:22:38.808507+00:00", "seconds": 18.711, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat-browser.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYKVUnz"}
|
||||
START single-webui-chat-instances.test 2026-10-23T09:22:38.810775+00:00
|
||||
END {"label": "single-webui-chat-instances.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T09:22:38.810775+00:00", "end": "2026-10-23T09:22:38.975118+00:00", "seconds": 0.164, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat-instances.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rRn9NQr"}
|
||||
START single-webui-chat.test 2026-10-23T09:22:38.977256+00:00
|
||||
END {"label": "single-webui-chat.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T09:22:38.977256+00:00", "end": "2026-10-23T09:22:39.442318+00:00", "seconds": 0.465, "exit": 0, "timeout": false, "counts": {"tests": 25, "pass": 25, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rZRH3FV"}
|
||||
START suite-bus 2026-10-23T09:22:39.445008+00:00
|
||||
END {"label": "suite-bus", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/account-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/approval-binding.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/broker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/business.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/channel-proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/chief-of-staff.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-cursors.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-claim.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-store.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/csuite-messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/daily-quota-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-close.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decisions.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/end-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/fire-revokes-grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant-docker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-enroll.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-executor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/hard-waits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-run.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/human.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/instances-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/interpreter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/land.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launch-notice.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launcher-released.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library-sync.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-stop.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-citation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-filter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/name-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peer-transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peercred.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/plugins-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/principal.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/process.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-timeout.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-web.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-await.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-files.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-runtime.test.mjs", "/Line truncated
|
||||
START suite-cli 2026-10-23T09:23:03.024737+00:00
|
||||
END {"label": "suite-cli", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/app.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/boot-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-accept.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-hostcheck.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-persona-import.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-unit.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-recovery.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/compactions-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/config.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/follow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/format.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-auth.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-fixtures.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-image.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-state.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/git-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/hosts.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/idle-stop-race.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-account.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launcher.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/lifecycle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits-tokens.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/mark-read.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/notifier.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/other-tree.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/processing-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/publish-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-clear.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release-external.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-upgrade.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-http.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-threads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/trackers-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/verbs.test.mjs"], "start": "2026-10-23T09:23:03.024737+00:00", "end": "2026-10-23T09:33:27.205598+00:00", "seconds": 624.181, "exit": 0, "timeout": false, "counts": {"tests": 921, "pass": 921, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/suite-cli.tap", "tmpdir": "/mnt/storage/scratch/tmp/rl2zH3q"}
|
||||
START suite-webui 2026-10-23T09:33:27.214222+00:00
|
||||
END {"label": "suite-webui", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/assistant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/board-held.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser-edge.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/channel-chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/conversation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/discord.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/docs-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-provenance.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/granted-user.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/history-return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/markdown-preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/pinned-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-ui.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-file.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/relaunch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/serve.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/service.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-form.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-write.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/shell.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-listener.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/views.test.mjs"], "start": "2026-10-23T09:33:27.214222+00:00", "end": "2026-10-23T09:34:24.087380+00:00", "seconds": 56.873, "exit": 0, "timeout": false, "counts": {"tests": 374, "pass": 373, "fail": 0, "cancelled": 0, "skipped": 1}, "skips": ["ok 107 - rebuilding from the source gives the same bytes (Line truncated
|
||||
START suite-harness 2026-10-23T09:34:24.092087+00:00
|
||||
END {"label": "suite-harness", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/bundle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/git-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/mcp-server.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/pi-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/raise-domain.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/runner.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/skills.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/spec-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/tools.test.mjs"], "start": "2026-10-23T09:34:24.092087+00:00", "end": "2026-10-23T09:34:36.185801+00:00", "seconds": 12.094, "exit": 0, "timeout": false, "counts": {"tests": 151, "pass": 151, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/suite-harness.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYOp9Yo"}
|
||||
START test-auth 2026-10-23T09:34:36.189152+00:00
|
||||
END {"label": "test-auth", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-auth.sh"], "start": "2026-10-23T09:34:36.189152+00:00", "end": "2026-10-23T09:34:37.005046+00:00", "seconds": 0.816, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-auth.tap", "tmpdir": "/mnt/storage/scratch/tmp/r7XakMj"}
|
||||
START test-conductor 2026-10-23T09:34:37.007148+00:00
|
||||
END {"label": "test-conductor", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-conductor.sh"], "start": "2026-10-23T09:34:37.007148+00:00", "end": "2026-10-23T09:34:43.835703+00:00", "seconds": 6.829, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-conductor.tap", "tmpdir": "/mnt/storage/scratch/tmp/rH7Fj9q"}
|
||||
START test-config 2026-10-23T09:34:43.837837+00:00
|
||||
END {"label": "test-config", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-config.sh"], "start": "2026-10-23T09:34:43.837837+00:00", "end": "2026-10-23T09:34:46.357228+00:00", "seconds": 2.519, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-config.tap", "tmpdir": "/mnt/storage/scratch/tmp/rXiHyiw"}
|
||||
START test-discord 2026-10-23T09:34:46.359375+00:00
|
||||
END {"label": "test-discord", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-discord.sh"], "start": "2026-10-23T09:34:46.359375+00:00", "end": "2026-10-23T09:34:53.590250+00:00", "seconds": 7.231, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-discord.tap", "tmpdir": "/mnt/storage/scratch/tmp/rcHYakY"}
|
||||
START test-extension-package 2026-10-23T09:34:53.592317+00:00
|
||||
END {"label": "test-extension-package", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-extension-package.sh"], "start": "2026-10-23T09:34:53.592317+00:00", "end": "2026-10-23T09:34:54.908860+00:00", "seconds": 1.317, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-extension-package.tap", "tmpdir": "/mnt/storage/scratch/tmp/rxrTT3R"}
|
||||
START test-foundation 2026-10-23T09:34:54.910888+00:00
|
||||
END {"label": "test-foundation", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-foundation.sh"], "start": "2026-10-23T09:34:54.910888+00:00", "end": "2026-10-23T09:35:33.605612+00:00", "seconds": 38.695, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-foundation.tap", "tmpdir": "/mnt/storage/scratch/tmp/rs2BwtK"}
|
||||
START test-land-work 2026-10-23T09:35:33.607688+00:00
|
||||
END {"label": "test-land-work", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-land-work.sh"], "start": "2026-10-23T09:35:33.607688+00:00", "end": "2026-10-23T09:35:45.646160+00:00", "seconds": 12.038, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-land-work.tap", "tmpdir": "/mnt/storage/scratch/tmp/rZFhfL5"}
|
||||
START test-queue 2026-10-23T09:35:45.648522+00:00
|
||||
END {"label": "test-queue", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-queue.sh"], "start": "2026-10-23T09:35:45.648522+00:00", "end": "2026-10-23T09:36:06.604342+00:00", "seconds": 20.956, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": ["skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-queue.tap", "tmpdir": "/mnt/storage/scratch/tmp/rAKp0eR"}
|
||||
START test-release 2026-10-23T09:36:06.606593+00:00
|
||||
END {"label": "test-release", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-release.sh"], "start": "2026-10-23T09:36:06.606593+00:00", "end": "2026-10-23T09:36:07.873175+00:00", "seconds": 1.267, "exit": 1, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-release.tap", "tmpdir": "/mnt/storage/scratch/tmp/rbunO3T"}
|
||||
Traceback (most recent call last):
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 96, in <module>
|
||||
try:stages()
|
||||
^^^^^^^^
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 65, in stages
|
||||
execute(path.stem,['timeout','-k','10','7200','bash',str(path)],deadline=7200,docker=True)
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 55, in execute
|
||||
if rc or timeout or re.search(r'^\s*not ok\b',text,re.M):raise RuntimeError('RED '+label+' '+str(log))
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
RuntimeError: RED test-release /mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-0780-mos1432/test-release.tap
|
||||
@@ -0,0 +1,38 @@
|
||||
START single-bus-creative.test 2026-10-23T08:55:46.514934+00:00
|
||||
END {"label": "single-bus-creative.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T08:55:46.514934+00:00", "end": "2026-10-23T08:55:46.880147+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rlmkrn532"}
|
||||
START single-bus-grant-executor.test 2026-10-23T08:55:46.881647+00:00
|
||||
END {"label": "single-bus-grant-executor.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T08:55:46.881647+00:00", "end": "2026-10-23T08:56:08.493753+00:00", "seconds": 21.612, "exit": 0, "timeout": false, "counts": {"tests": 42, "pass": 42, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-grant-executor.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rjpu1ic5m"}
|
||||
START single-bus-project-runtime.test 2026-10-23T08:56:08.495370+00:00
|
||||
END {"label": "single-bus-project-runtime.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/project-runtime.test.mjs"], "start": "2026-10-23T08:56:08.495370+00:00", "end": "2026-10-23T08:56:08.910312+00:00", "seconds": 0.415, "exit": 0, "timeout": false, "counts": {"tests": 3, "pass": 3, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-project-runtime.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r6j9zk1mz"}
|
||||
START single-bus-threads.test 2026-10-23T08:56:08.911614+00:00
|
||||
END {"label": "single-bus-threads.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T08:56:08.911614+00:00", "end": "2026-10-23T08:56:10.278831+00:00", "seconds": 1.367, "exit": 0, "timeout": false, "counts": {"tests": 20, "pass": 20, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/ridmpf8e9"}
|
||||
START single-bus-user-principal.test 2026-10-23T08:56:10.280242+00:00
|
||||
END {"label": "single-bus-user-principal.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T08:56:10.280242+00:00", "end": "2026-10-23T08:56:10.845658+00:00", "seconds": 0.565, "exit": 0, "timeout": false, "counts": {"tests": 23, "pass": 23, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rxak25z_4"}
|
||||
START single-cli-launcher.test 2026-10-23T08:56:10.847112+00:00
|
||||
END {"label": "single-cli-launcher.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T08:56:10.847112+00:00", "end": "2026-10-23T08:56:37.072632+00:00", "seconds": 26.226, "exit": 0, "timeout": false, "counts": {"tests": 34, "pass": 34, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r6tlrj8kb"}
|
||||
START single-cli-thread-launch.test 2026-10-23T08:56:37.074143+00:00
|
||||
END {"label": "single-cli-thread-launch.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T08:56:37.074143+00:00", "end": "2026-10-23T08:56:55.131362+00:00", "seconds": 18.057, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-cli-thread-launch.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r9k_bmlhv"}
|
||||
START single-webui-chat-browser.test 2026-10-23T08:56:55.132860+00:00
|
||||
END {"label": "single-webui-chat-browser.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T08:56:55.132860+00:00", "end": "2026-10-23T08:57:13.336278+00:00", "seconds": 18.203, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat-browser.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r3mqd7dfy"}
|
||||
START single-webui-chat-instances.test 2026-10-23T08:57:13.337687+00:00
|
||||
END {"label": "single-webui-chat-instances.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T08:57:13.337687+00:00", "end": "2026-10-23T08:57:13.502100+00:00", "seconds": 0.164, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat-instances.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/ri0d5cw9g"}
|
||||
START single-webui-chat.test 2026-10-23T08:57:13.503425+00:00
|
||||
END {"label": "single-webui-chat.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T08:57:13.503425+00:00", "end": "2026-10-23T08:57:14.018577+00:00", "seconds": 0.515, "exit": 0, "timeout": false, "counts": {"tests": 25, "pass": 25, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rf6pbt6z6"}
|
||||
START suite-bus 2026-10-23T08:57:14.020317+00:00
|
||||
END {"label": "suite-bus", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/account-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/approval-binding.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/broker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/business.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/channel-proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/chief-of-staff.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-cursors.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-claim.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-store.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/csuite-messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/daily-quota-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-close.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decisions.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/end-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/fire-revokes-grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant-docker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-enroll.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-executor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/hard-waits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-run.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/human.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/instances-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/interpreter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/land.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launch-notice.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launcher-released.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library-sync.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-stop.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-citation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-filter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/name-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peer-transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peercred.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/plugins-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/principal.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/process.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-timeout.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-web.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-await.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-files.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-runtime.test.mjs", "/Line truncated
|
||||
START suite-cli 2026-10-23T08:57:37.800853+00:00
|
||||
END {"label": "suite-cli", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/app.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/boot-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-accept.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-hostcheck.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-persona-import.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-unit.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-recovery.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/compactions-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/config.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/follow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/format.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-auth.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-fixtures.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-image.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-state.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/git-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/hosts.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/idle-stop-race.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-account.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launcher.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/lifecycle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits-tokens.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/mark-read.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/notifier.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/other-tree.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/processing-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/publish-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-clear.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release-external.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-upgrade.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-http.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-threads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/trackers-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/verbs.test.mjs"], "start": "2026-10-23T08:57:37.800853+00:00", "end": "2026-10-23T09:08:05.517184+00:00", "seconds": 627.716, "exit": 0, "timeout": false, "counts": {"tests": 921, "pass": 921, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/suite-cli.tap", "tmpdir": "/mnt/storage/scratch/tmp/r29043nvq"}
|
||||
START suite-webui 2026-10-23T09:08:05.524672+00:00
|
||||
END {"label": "suite-webui", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/assistant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/board-held.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser-edge.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/channel-chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/conversation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/discord.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/docs-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-provenance.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/granted-user.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/history-return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/markdown-preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/pinned-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-ui.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-file.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/relaunch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/serve.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/service.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-form.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-write.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/shell.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-listener.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/views.test.mjs"], "start": "2026-10-23T09:08:05.524672+00:00", "end": "2026-10-23T09:09:02.641939+00:00", "seconds": 57.117, "exit": 0, "timeout": false, "counts": {"tests": 374, "pass": 373, "fail": 0, "cancelled": 0, "skipped": 1}, "skips": ["ok 107 - rebuilding from the source gives the same bytes (Line truncated
|
||||
START suite-harness 2026-10-23T09:09:02.645756+00:00
|
||||
END {"label": "suite-harness", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/bundle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/git-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/mcp-server.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/pi-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/raise-domain.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/runner.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/skills.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/spec-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/tools.test.mjs"], "start": "2026-10-23T09:09:02.645756+00:00", "end": "2026-10-23T09:09:14.638654+00:00", "seconds": 11.993, "exit": 1, "timeout": false, "counts": {"tests": 151, "pass": 150, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/suite-harness.tap", "tmpdir": "/mnt/storage/scratch/tmp/rh85v_4j3"}
|
||||
Traceback (most recent call last):
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 95, in <module>
|
||||
try:stages()
|
||||
^^^^^^^^
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 61, in stages
|
||||
execute('suite-'+package,['node','--test',*files],cwd=ROOT/'packages'/package,deadline=1800)
|
||||
File "/mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-219.py", line 54, in execute
|
||||
if rc or timeout or re.search(r'^\s*not ok\b',text,re.M):raise RuntimeError('RED '+label+' '+str(log))
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
RuntimeError: RED suite-harness /mnt/storage/scratch/rocko-r219/agents/rocko/work/queue-219/run-0780-mos1429/suite-harness.tap
|
||||
@@ -0,0 +1,5 @@
|
||||
06d7cc2f0ffc544abfb2755f99dce76ca164212c
|
||||
07802dc57ad36337351da70af15c447bea38ab8b b899095e482cb2b68919efff1e332f272203e017
|
||||
817eda2289955e683213bab4659e537426e7d021
|
||||
merge: combine row 219 with landed row 302
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
from pathlib import Path
|
||||
import subprocess,json,re,hashlib
|
||||
ROOT=Path(__file__).resolve().parents[5];P=ROOT/'agents/rocko/work/queue-219';OUT=P/'r5'
|
||||
files=sorted(ROOT.glob('packages/*/tests/**/*'))+sorted(ROOT.glob('scripts/test-*.sh'))
|
||||
files=[f for f in files if f.is_file()]
|
||||
texts={f:f.read_text(errors='replace') for f in files}
|
||||
rows=[]
|
||||
for path in (P/'changed-paths.txt').read_text().splitlines()+['packages/webui/src/public/bus.js']:
|
||||
base=Path(path).name;hits=[]
|
||||
for f,text in texts.items():
|
||||
for n,line in enumerate(text.splitlines(),1):
|
||||
if path in line or base in line:hits.append(dict(file=str(f.relative_to(ROOT)),line=n,text=line))
|
||||
rows.append(dict(path=path,hits=hits))
|
||||
pins=[]
|
||||
for f,text in texts.items():
|
||||
for n,line in enumerate(text.splitlines(),1):
|
||||
if re.search(r'(?<![0-9a-f])[0-9a-f]{64}(?![0-9a-f])',line):pins.append(dict(file=str(f.relative_to(ROOT)),line=n,text=line))
|
||||
control=ROOT/'packages/bus/tests/channel-proof.test.mjs';t=control.read_text()
|
||||
m=re.search(r'"packages/webui/src/bus.mjs": "([0-9a-f]{64})"',t);assert m
|
||||
assert hashlib.sha256((ROOT/'packages/webui/src/bus.mjs').read_bytes()).hexdigest()==m[1]
|
||||
assert subprocess.check_output(['git','diff','07802dc57','HEAD','--','packages/webui/src/public/bus.js'],cwd=ROOT)==b''
|
||||
report=dict(head=subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip(),paths=rows,hexPins=pins,positiveControl=dict(file=str(control.relative_to(ROOT)),pin='packages/webui/src/bus.mjs',sha256=m[1],matches=True),busJsUnchanged=True)
|
||||
(OUT/'reader-audit.json').write_text(json.dumps(report,indent=2)+'\n')
|
||||
print(json.dumps(dict(paths=len(rows)-1,additionalBusJs=True,readerHits=sum(len(x['hits']) for x in rows),hexPinLines=len(pins),positiveControl=True,busJsUnchanged=True)))
|
||||
@@ -0,0 +1,50 @@
|
||||
# Full restart r6, sage-3345 / mos-1439
|
||||
|
||||
Merge 054da642f9b0680bd7743583e4c67266d7e14e2a, parents 2efd127ce617a9bff8dc3bee3a3b657b0c175c07 and b899095e4.
|
||||
Tree e86a84a852c9739f157033e3772243b293742983 matches Sage before any run.
|
||||
No conflicts or manual product/test edits. Same16 paths, new manifest
|
||||
4a2271ddbd4212324f39e608c3a35a4ae834c045cb0d13a619715017ded0ffef.
|
||||
Fresh worktree /mnt/storage/scratch/rocko-r219-g3345, node_modules linked immediately.
|
||||
Runner uses mktemp -d /mnt/storage/scratch/tmp/rXXXXXX and validates
|
||||
[A-Za-z0-9/.-] for each stage; no previous results carry.
|
||||
10 whole singles; bus,cli,webui,harness suites; all10 shell scripts
|
||||
including test-task with Docker;24 mutants;reader audit.
|
||||
Timeout -k10: singles300s,suites1800s,shells7200s,mutants180s;
|
||||
7200s exceeds3x the prior conservative25min shell baseline.
|
||||
Every child has a process group; any red stops, no retry/edit.
|
||||
Finally remove owned networks including rocko-r219-g3345_default,
|
||||
sweep, preserve packet evidence, remove node_modules link and this worktree.
|
||||
|
||||
## Completed gate, sage-3345
|
||||
|
||||
Full run 2026-10-23 10:12:57Z-10:29:22Z on merge054da642f9.
|
||||
Ten singles183/0/0; bus889/0/1; cli927/0/0; webui373/0/1;
|
||||
harness151/0/0. Node total2523pass/0fail/2skip,0cancelled.
|
||||
All10 shell files green,449pass/0fail.24 assertion kills,0timeout kills,
|
||||
0survivors,0invalid. T15 finished in66.9s with ERR_ASSERTION on the
|
||||
missing 'no longer available' status; T24 got decision-required instead
|
||||
of host-creative-role (same exact later-fence mismatch as r4).
|
||||
Both Bean pins and the sandbox-dependent native-history test ran, no skip.
|
||||
|
||||
Skips: X-G3 scratch Gitea1.27.1 unavailable (Node stage uses deadDocker);
|
||||
WebUI rebuild needs esbuild0.28.2 but host has0.28.1; queue verify/render
|
||||
requires canonical checkout; test-task live provider cases intentionally
|
||||
skipped twice (row244, no provider call). GATE-RESULTS.json quotes all5
|
||||
skip lines, including the duplicated live-provider line.
|
||||
|
||||
Reader audit: all16 changed paths plus unchanged public/bus.js,237 reader
|
||||
hits and22 64-hex lines. None of those pins freezes a changed file. Positive
|
||||
control channel-proof.test.mjs webui bus.mjs pin matches actual bytes;
|
||||
public/bus.js stays unchanged. Full audit in reader-audit.json.
|
||||
|
||||
16 candidate hashes restored. Driver cwd node/chromium sweep empty.
|
||||
Owned rocko-r219-gate_default removed; worktree-basename network
|
||||
rocko-r219-g3345_default already absent (rm attempted as instructed).
|
||||
No retries, unexpected reds or guard interventions in this run. Results
|
||||
from prior environmental failures were not carried.
|
||||
|
||||
Historical environmental failures remain in run-0780-mos1429/ (harness
|
||||
underscore TMPDIR) and run-0780-mos1432/ (Docker address pool exhaustion).
|
||||
Mos1432 required alphanumeric paths; Mos1437/Mos1439 and sage3339/3345
|
||||
resolved the network issue outside this candidate. No product/test fix
|
||||
for either. Tests and source remain byte-identical to the checked merge.
|
||||
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"head": "054da642f9b0680bd7743583e4c67266d7e14e2a",
|
||||
"manifest": "4a2271ddbd4212324f39e608c3a35a4ae834c045cb0d13a619715017ded0ffef",
|
||||
"start": "2026-10-23T10:12:57.651391+00:00",
|
||||
"end": "2026-10-23T10:29:22.193573+00:00",
|
||||
"node": {
|
||||
"tests": 2525,
|
||||
"pass": 2523,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 2
|
||||
},
|
||||
"nodeStages": [
|
||||
{
|
||||
"label": "single-bus-creative.test",
|
||||
"counts": {
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-bus-grant-executor.test",
|
||||
"counts": {
|
||||
"tests": 42,
|
||||
"pass": 42,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-bus-project-runtime.test",
|
||||
"counts": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-bus-threads.test",
|
||||
"counts": {
|
||||
"tests": 20,
|
||||
"pass": 20,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-bus-user-principal.test",
|
||||
"counts": {
|
||||
"tests": 23,
|
||||
"pass": 23,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-cli-launcher.test",
|
||||
"counts": {
|
||||
"tests": 34,
|
||||
"pass": 34,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-cli-thread-launch.test",
|
||||
"counts": {
|
||||
"tests": 14,
|
||||
"pass": 14,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-webui-chat-browser.test",
|
||||
"counts": {
|
||||
"tests": 14,
|
||||
"pass": 14,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-webui-chat-instances.test",
|
||||
"counts": {
|
||||
"tests": 4,
|
||||
"pass": 4,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "single-webui-chat.test",
|
||||
"counts": {
|
||||
"tests": 25,
|
||||
"pass": 25,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "suite-bus",
|
||||
"counts": {
|
||||
"tests": 890,
|
||||
"pass": 889,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "suite-cli",
|
||||
"counts": {
|
||||
"tests": 927,
|
||||
"pass": 927,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "suite-webui",
|
||||
"counts": {
|
||||
"tests": 374,
|
||||
"pass": 373,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "suite-harness",
|
||||
"counts": {
|
||||
"tests": 151,
|
||||
"pass": 151,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"shells": [
|
||||
{
|
||||
"label": "test-auth",
|
||||
"passCount": 15,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-conductor",
|
||||
"passCount": 17,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-config",
|
||||
"passCount": 55,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-discord",
|
||||
"passCount": 81,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-extension-package",
|
||||
"passCount": 18,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-foundation",
|
||||
"passCount": 44,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-land-work",
|
||||
"passCount": 86,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-queue",
|
||||
"passCount": 28,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": [
|
||||
"skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219-g3345) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "test-release",
|
||||
"passCount": 14,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-task",
|
||||
"passCount": 91,
|
||||
"failCount": 0,
|
||||
"exit": 0,
|
||||
"skips": [
|
||||
"skip live provider cases (row 244: no provider call in the gate)",
|
||||
"skip live provider cases (row 244: no provider call in the gate)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"shellPass": 449,
|
||||
"shellFail": 0,
|
||||
"mutants": {
|
||||
"assertionKills": 24,
|
||||
"timeoutKills": 0,
|
||||
"survived": 0,
|
||||
"invalid": 0
|
||||
},
|
||||
"skips": [
|
||||
{
|
||||
"stage": "suite-bus",
|
||||
"text": "ok 203 - X-G3: on scratch 1.27.1, a grant makes the user, mints, forks, checks reach, writes the file, and revoke deletes the token # SKIP no Docker or no local gitea/gitea:1.27.1; this test never pulls"
|
||||
},
|
||||
{
|
||||
"stage": "suite-webui",
|
||||
"text": "ok 107 - rebuilding from the source gives the same bytes (needs the pinned esbuild; MOSAIC_REQUIRE_EDITOR_BUILD=1 makes its absence a failure) # SKIP esbuild 0.28.1 is installed at /mnt/storage/src/mosaic-stack/node_modules/esbuild; the editor rebuild needs exactly 0.28.2 (npm ci --ignore-scripts in packages/webui) (set MOSAIC_REQUIRE_EDITOR_BUILD=1 to fail instead of skip)"
|
||||
},
|
||||
{
|
||||
"stage": "test-queue",
|
||||
"text": "skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219-g3345) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"
|
||||
},
|
||||
{
|
||||
"stage": "test-task",
|
||||
"text": "skip live provider cases (row 244: no provider call in the gate)"
|
||||
},
|
||||
{
|
||||
"stage": "test-task",
|
||||
"text": "skip live provider cases (row 244: no provider call in the gate)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
2efd127ce617a9bff8dc3bee3a3b657b0c175c07
|
||||
@@ -0,0 +1,832 @@
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index 7befba0c0..20da8b84c 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -4,7 +4,7 @@ import { initializeControl, processingStatus } from '../../processing-control/sr
|
||||
import { NAME as HARNESS_NAME } from '../../plugins/src/kinds.mjs';
|
||||
import { loadRequirements } from '../../tasks/src/requirements.mjs';
|
||||
import { MERGE, LandingRefusal, readLanding } from './landing.mjs';
|
||||
-import { ID_PATTERN, THREAD_DEFINITION, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';
|
||||
+import { ID_PATTERN, THREAD_DEFINITIONS, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';
|
||||
|
||||
// Kept closed while S1 lands; its vocabulary is the integration authority.
|
||||
export const ACTIONS = Object.freeze([
|
||||
@@ -314,7 +314,7 @@ const enrollBinding = (enroll) => ({
|
||||
});
|
||||
// r6 E3: the installer line's comment, then the tag's 32 hex digits.
|
||||
const INSTALLER_COMMENT = 'mosaic-installer-';
|
||||
-// Row 121 (#1615): an instance of THREAD_DEFINITION (vocabulary.mjs since row 155) talks with the
|
||||
+// Row 121 (#1615): an instance of THREAD_DEFINITIONS (vocabulary.mjs since row 213) talks with the
|
||||
// user in threads. Its runs claim a thread, not the role, and every message to or from it names its
|
||||
// thread (REQ-MSG-1).
|
||||
// Row 146 (#1640): the sender of the bus's notice to launch.by. A role instance name matches the
|
||||
@@ -610,7 +610,7 @@ export class Broker {
|
||||
);
|
||||
}
|
||||
#threaded(business, role) {
|
||||
- return this.#business(business).roles[role]?.definition === THREAD_DEFINITION;
|
||||
+ return THREAD_DEFINITIONS.includes(this.#business(business).roles[role]?.definition);
|
||||
}
|
||||
// Row 264a (#1769): a claim holds one session of a thread, and each session has its own holder.
|
||||
#sessionHolder(session) {
|
||||
@@ -6171,24 +6171,27 @@ export class Broker {
|
||||
.all('SELECT id,at,name,repo FROM projects WHERE business=? ORDER BY seq', s.business)
|
||||
.filter((p) => !s.user || this.#granted(s, 'project.list', p.id, null));
|
||||
}
|
||||
- // A thread belongs to the user who made it and to the business's one thread instance.
|
||||
+ // A thread belongs to the user who made it and to one declared thread instance.
|
||||
// Row 177 (#1675): a tester's thread is owned by `tester`, so neither reaches the other's.
|
||||
case 'thread.create': {
|
||||
if (!s.tester && !s.user) this.#human(s);
|
||||
- keys(a, ['project', 'name'], ['project', 'name']);
|
||||
+ keys(a, ['project', 'name', 'instance'], ['project', 'name']);
|
||||
if (!name(a.name)) fail('invalid-request');
|
||||
+ const instances = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
+ const instance = a.instance === undefined
|
||||
+ ? (instances.length === 1 ? instances[0] : null)
|
||||
+ : identifier(a.instance);
|
||||
// FED R3 (design 3.5): a user's grant must cover the project and the thread instance, checked
|
||||
// before the project is looked up, so an ungranted id reads the same whether it exists or not.
|
||||
if (s.user) {
|
||||
- const threaded = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
- if (threaded.length !== 1 || !this.#granted(s, 'thread.create', identifier(a.project), threaded[0])) fail('access-refused');
|
||||
+ if (!instance || !instances.includes(instance) || !this.#granted(s, 'thread.create', identifier(a.project), instance))
|
||||
+ fail('access-refused');
|
||||
}
|
||||
if (!this.#store.get('SELECT 1 FROM projects WHERE id=? AND business=?', identifier(a.project), s.business))
|
||||
fail('project-not-found');
|
||||
- // The bus never picks between instances; the business file declares exactly one.
|
||||
- const instances = Object.keys(b.roles).filter((r) => this.#threaded(s.business, r));
|
||||
- if (!instances.length) fail('thread-instance-missing');
|
||||
- if (instances.length > 1) fail('thread-instance-ambiguous');
|
||||
+ // The human selects an instance; omission is compatible only with one candidate.
|
||||
+ if (!instances.length || (a.instance !== undefined && !instances.includes(instance))) fail('thread-instance-missing');
|
||||
+ if (a.instance === undefined && instances.length > 1) fail('thread-instance-ambiguous');
|
||||
if (this.#store.get('SELECT 1 FROM threads WHERE project=? AND name=?', a.project, a.name)) fail('thread-exists');
|
||||
const tid = randomUUID();
|
||||
this.#store.run(
|
||||
@@ -6197,13 +6200,13 @@ export class Broker {
|
||||
this.#now(),
|
||||
s.business,
|
||||
a.project,
|
||||
- instances[0],
|
||||
+ instance,
|
||||
this.#owner(s),
|
||||
a.name,
|
||||
);
|
||||
// Row 264a (#1769, D3): every thread has a default session from the start.
|
||||
- this.#newSession(s, { id: tid, business: s.business, instance: instances[0], owner: this.#owner(s) }, 'default', 'default', true);
|
||||
- return { id: tid, instance: instances[0] };
|
||||
+ this.#newSession(s, { id: tid, business: s.business, instance, owner: this.#owner(s) }, 'default', 'default', true);
|
||||
+ return { id: tid, instance };
|
||||
}
|
||||
// Row 177 (#1675): each lists its own threads. The human's list leaves out the tester's,
|
||||
// and the tester's lists only its own (row 175 listed it the business human's).
|
||||
diff --git a/packages/bus/tests/creative.test.mjs b/packages/bus/tests/creative.test.mjs
|
||||
index 6cfbf1cd6..6d421ba19 100644
|
||||
--- a/packages/bus/tests/creative.test.mjs
|
||||
+++ b/packages/bus/tests/creative.test.mjs
|
||||
@@ -44,15 +44,18 @@ function setup(t) {
|
||||
const caps = {};
|
||||
caps.human = b.bindHuman({ business: 'demo', human: 'jason', via: 'cli', outsideAgent: true });
|
||||
const project = b.request(caps.human, { verb: 'project.create', args: { name: 'demo' } }).id;
|
||||
- const thread = b.request(caps.human, { verb: 'thread.create', args: { project, name: 'main' } }).id;
|
||||
+ const thread = b.request(caps.human, { verb: 'thread.create', args: { project, name: 'main', instance: 'assistant' } }).id;
|
||||
+ const threads = { assistant: thread };
|
||||
for (const role of Object.keys(roles)) {
|
||||
- caps[role] = b.bindLaunch({ business: 'demo', role, run: `${role}-run`, harness: 'pi', ...(role === 'assistant' ? { thread } : {}) });
|
||||
+ if (['bean', 'quill'].includes(role))
|
||||
+ threads[role] = b.request(caps.human, { verb: 'thread.create', args: { project, name: role, instance: role } }).id;
|
||||
+ caps[role] = b.bindLaunch({ business: 'demo', role, run: `${role}-run`, harness: 'pi', ...(threads[role] ? { thread: threads[role] } : {}) });
|
||||
b.request(caps[role], { verb: 'role.claim' });
|
||||
}
|
||||
caps.tester = b.bindTester({ business: 'demo' });
|
||||
const call = (who, verb, args = {}) => b.request(caps[who], { verb, args });
|
||||
const count = (sql) => store.get(sql).n;
|
||||
- return { call, count, store };
|
||||
+ return { call, count, store, threads };
|
||||
}
|
||||
|
||||
const raise = { action: 'policy.change', question: 'Change?', options: [{ key: 'yes', text: 'Yes' }, { key: 'no', text: 'No' }], recommendation: 'yes', blocking: false };
|
||||
@@ -72,7 +75,7 @@ test('M6: a creative raise refuses decision-not-allowed, cited or not, and no de
|
||||
});
|
||||
|
||||
test('a creative instance sends only to the user and hears only from the user', (t) => {
|
||||
- const { call, count } = setup(t);
|
||||
+ const { call, count, threads } = setup(t);
|
||||
for (const who of ['bean', 'quill']) {
|
||||
call(who, 'message.send', { to: 'human', body: 'hello' });
|
||||
for (const to of ['chief', 'assistant', 'pm', 'bean', 'quill'].filter((n) => n !== who)) {
|
||||
@@ -81,7 +84,7 @@ test('a creative instance sends only to the user and hears only from the user',
|
||||
for (const from of ['chief', 'pm']) {
|
||||
assert.throws(() => call(from, 'message.send', { to: who, body: 'hello' }), { code: 'message-sender-refused' }, `${from} to ${who}`);
|
||||
}
|
||||
- call('human', 'message.send', { to: who, body: 'hello' });
|
||||
+ call('human', 'thread.send', { thread: threads[who], body: 'hello' });
|
||||
}
|
||||
assert.equal(count("SELECT count(*) n FROM messages WHERE from_role IN ('bean','quill')"), 2);
|
||||
assert.equal(count("SELECT count(*) n FROM messages WHERE to_role IN ('bean','quill')"), 2);
|
||||
diff --git a/packages/bus/tests/grant-executor.test.mjs b/packages/bus/tests/grant-executor.test.mjs
|
||||
index e449b7d77..46235d16b 100644
|
||||
--- a/packages/bus/tests/grant-executor.test.mjs
|
||||
+++ b/packages/bus/tests/grant-executor.test.mjs
|
||||
@@ -1047,7 +1047,10 @@ test('sage-1908: once the agent of an applied grant is a creative role, host.run
|
||||
const f = await setup(t);
|
||||
assert.equal((await f.approve()).end.action, 'grant.applied');
|
||||
const r = await restart(t, f, creativeOps(f.business));
|
||||
- const cap = r.broker.bindLaunch({ business: 'demo', role: 'ops', run: 'ops-run', harness: 'pi', address: 'ops' });
|
||||
+ const human = r.broker.bindHuman({ business: 'demo', human: 'jason', via: 'cli', outsideAgent: true });
|
||||
+ const project = r.broker.request(human, { verb: 'project.create', args: { name: 'host grant check' } }).id;
|
||||
+ const thread = r.broker.request(human, { verb: 'thread.create', args: { project, name: 'ops', instance: 'ops' } }).id;
|
||||
+ const cap = r.broker.bindLaunch({ business: 'demo', role: 'ops', run: 'ops-run', harness: 'pi', address: 'ops', thread });
|
||||
r.broker.request(cap, { verb: 'role.claim' });
|
||||
const executor = hostExecutor({ credentials: r.credentials, root: join(f.dir, 'host-run') });
|
||||
const before = f.requests().length;
|
||||
diff --git a/packages/bus/tests/project-runtime.test.mjs b/packages/bus/tests/project-runtime.test.mjs
|
||||
index a6086e56c..7275ad902 100644
|
||||
--- a/packages/bus/tests/project-runtime.test.mjs
|
||||
+++ b/packages/bus/tests/project-runtime.test.mjs
|
||||
@@ -32,7 +32,8 @@ test('Broker keeps the sandbox client import closure: only the listed imports, n
|
||||
// (#1692, D2.4) reads unhireableAction, the hire veto's action name.
|
||||
// Row 236 (#1742, #436b) reads giteaName and parseGiteaUrl for the Gitea grant path.
|
||||
// FED R3 r5 (row 274, #414) reads covers, a user's grant check, from it.
|
||||
- "import { ID_PATTERN, THREAD_DEFINITION, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';",
|
||||
+ // Row 219 reads THREAD_DEFINITIONS from the same vocabulary for creative thread admission.
|
||||
+ "import { ID_PATTERN, THREAD_DEFINITIONS, END_PROTECTED, forkProblem, forkUrl, credentialKind, validArgv, commandAllowed, HOST_ID, CREATIVE_DEFINITIONS, unhireableAction, giteaName, parseGiteaUrl, covers } from '../../business/src/vocabulary.mjs';",
|
||||
]);
|
||||
assert.doesNotMatch(source, /\bimport\s*\(/);
|
||||
assert.doesNotMatch(readFileSync(new URL('../src/landing.mjs', import.meta.url), 'utf8'), /\bimport\b/);
|
||||
diff --git a/packages/bus/tests/threads.test.mjs b/packages/bus/tests/threads.test.mjs
|
||||
index 27193a745..ae44fb66a 100644
|
||||
--- a/packages/bus/tests/threads.test.mjs
|
||||
+++ b/packages/bus/tests/threads.test.mjs
|
||||
@@ -601,3 +601,56 @@ test('project.create keeps unrelated names with and without a repository', t =>
|
||||
{ id: linked.id, name: 'work', repo: 'stack' },
|
||||
]);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: explicit creative instances bind independent threads, default sessions and holders', t => {
|
||||
+ const creative = ['companion', 'ideas', 'research', 'proofreader', 'fact-checker', 'continuity'];
|
||||
+ const extra = Object.fromEntries(creative.map((definition, i) => [`writer${i}`, { definition, authority: { withinRole: ['message.send'], crossRole: [] } }]));
|
||||
+ const ctx = setup(t, demo({ roles: { ...roles, ...extra }, definitions: {
|
||||
+ ...definitions, ...Object.fromEntries(creative.map(definition => [definition, { messaging: shipped(definition).messaging }])),
|
||||
+ } }));
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'Writing' }).id;
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: 'ambiguous' }), { code: 'thread-instance-ambiguous' });
|
||||
+ for (const [instance, role] of Object.entries(extra)) {
|
||||
+ const receipt = ctx.call('human', 'thread.create', { project, name: instance, instance });
|
||||
+ assert.equal(receipt.instance, instance);
|
||||
+ assert.equal(ctx.store.get('SELECT instance FROM threads WHERE id=?', receipt.id).instance, instance);
|
||||
+ assert.equal(ctx.store.get('SELECT instance FROM sessions WHERE thread=?', receipt.id).instance, instance);
|
||||
+ ctx.launch(instance, instance, { thread: receipt.id });
|
||||
+ assert.equal(ctx.claim(instance).thread, receipt.id);
|
||||
+ const sent = ctx.call('human', 'thread.send', { thread: receipt.id, body: `For ${instance}` });
|
||||
+ const read = ctx.call(instance, 'message.receive');
|
||||
+ assert.deepEqual(read.map(m => m.id), [sent.id], role.definition);
|
||||
+ assert.equal(ctx.threadOf(sent.id), receipt.id);
|
||||
+ assert.equal(ctx.store.get('SELECT count(*) n FROM role_claims WHERE role=?', instance).n, 0);
|
||||
+ assert.throws(() => ctx.call('human', 'message.send', { to: instance, body: 'No implicit thread' }),
|
||||
+ { code: 'thread-required-use-thread-send' });
|
||||
+ }
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), creative.length);
|
||||
+});
|
||||
+
|
||||
+test('C2-09a: explicit missing, non-thread and malformed selectors create no thread or session', t => {
|
||||
+ const ctx = setup(t);
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'Writing' }).id;
|
||||
+ for (const instance of ['not-declared', 'pm', 'coder'])
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: instance, instance }), { code: 'thread-instance-missing' });
|
||||
+ for (const instance of [null, 7, {}, [], '', 'bad name'])
|
||||
+ assert.throws(() => ctx.call('human', 'thread.create', { project, name: 'bad', instance }), { code: 'invalid-request' });
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), 0);
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM sessions'), 0);
|
||||
+ const legacy = ctx.call('human', 'thread.create', { project, name: 'Default' });
|
||||
+ assert.equal(legacy.instance, 'assistant');
|
||||
+});
|
||||
+
|
||||
+
|
||||
+test('C2-09a: creative bindLaunch without a thread refuses thread-required', t => {
|
||||
+ const creative = ['companion', 'ideas', 'research', 'proofreader', 'fact-checker', 'continuity'];
|
||||
+ const extra = Object.fromEntries(creative.map((definition, i) => [`creative${i}`, { definition, authority: { withinRole: ['message.send'], crossRole: [] } }]));
|
||||
+ const ctx = setup(t, demo({ roles: { ...roles, ...extra }, definitions: {
|
||||
+ ...definitions, ...Object.fromEntries(creative.map(definition => [definition, {}])),
|
||||
+ } }));
|
||||
+ for (const instance of Object.keys(extra)) {
|
||||
+ assert.throws(() => ctx.launch(`unthreaded-${instance}`, instance), { code: 'thread-required' });
|
||||
+ }
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM threads'), 0);
|
||||
+ assert.equal(ctx.count('SELECT count(*) n FROM role_claims'), 0);
|
||||
+});
|
||||
diff --git a/packages/bus/tests/user-principal.test.mjs b/packages/bus/tests/user-principal.test.mjs
|
||||
index 4dcd1ebeb..8471ddf85 100644
|
||||
--- a/packages/bus/tests/user-principal.test.mjs
|
||||
+++ b/packages/bus/tests/user-principal.test.mjs
|
||||
@@ -23,7 +23,7 @@ const grant = (over = {}) => ({
|
||||
});
|
||||
|
||||
// `processing` stands in for the halt switch, as lifecycle-verbs.test.mjs's T15 does.
|
||||
-function setup(t, { grants = [grant()], processing = null } = {}) {
|
||||
+function setup(t, { grants = [grant()], processing = null, threadRoles = {} } = {}) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'bus-user-principal-'));
|
||||
const store = new Store(root);
|
||||
t.after(() => {
|
||||
@@ -40,6 +40,7 @@ function setup(t, { grants = [grant()], processing = null } = {}) {
|
||||
roles: {
|
||||
chief: { definition: 'chief-of-staff', authority: { withinRole: ['message.send'], crossRole: [] } },
|
||||
assistant: { definition: 'assistant', authority: { withinRole: ['message.send'], crossRole: [] } },
|
||||
+ ...threadRoles,
|
||||
},
|
||||
definitions: { 'chief-of-staff': {}, assistant: { messaging: shipped('assistant').messaging } },
|
||||
},
|
||||
@@ -394,3 +395,21 @@ test('R3 r4: the chief\'s hire refuses an instance named user with the code it g
|
||||
test('R3 r4: a non-function access throws before the store is read', () => {
|
||||
assert.throws(() => new Broker({ store: null, businesses: { demo: {} }, access: 'access.json' }), /access must be a function/);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project', t => {
|
||||
+ const ctx = setup(t, { threadRoles: { bean: { definition: 'companion', authority: { withinRole: ['message.send'], crossRole: [] } } } });
|
||||
+ const project = ctx.call('human', 'project.create', { name: 'shared' }).id;
|
||||
+ const privateProject = ctx.call('human', 'project.create', { name: 'private' }).id;
|
||||
+ ctx.access.doc.grants = [grant({ projects: [project] })];
|
||||
+ ctx.user('alice');
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project, name: 'blocked bean', instance: 'bean' }), 'access-refused');
|
||||
+ for (const id of [privateProject, '00000000-0000-4000-8000-000000000000'])
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project: id, name: 'blocked project', instance: 'assistant' }), 'access-refused');
|
||||
+ assert.equal(ctx.store.get('SELECT count(*) n FROM threads').n, 0);
|
||||
+ const allowed = ctx.call('alice', 'thread.create', { project, name: 'assistant work', instance: 'assistant' });
|
||||
+ assert.equal(allowed.instance, 'assistant');
|
||||
+ ctx.access.doc.grants = [grant({ projects: [project], instances: ['bean'] })];
|
||||
+ const bean = ctx.call('alice', 'thread.create', { project, name: 'bean work', instance: 'bean' });
|
||||
+ assert.equal(bean.instance, 'bean');
|
||||
+ assert.equal(ctx.code('alice', 'thread.create', { project, name: 'old instance', instance: 'assistant' }), 'access-refused');
|
||||
+});
|
||||
diff --git a/packages/cli/src/launcher.mjs b/packages/cli/src/launcher.mjs
|
||||
index f1ee4043e..cb9631ddf 100644
|
||||
--- a/packages/cli/src/launcher.mjs
|
||||
+++ b/packages/cli/src/launcher.mjs
|
||||
@@ -53,7 +53,7 @@
|
||||
// session.json names it as gitSocket.
|
||||
//
|
||||
// Thread sessions (row 121, #1615). A thread instance (an instance whose
|
||||
-// role definition is the assistant) runs once per thread, never on its own:
|
||||
+// role definition is in THREAD_DEFINITIONS) runs once per thread, never on its own:
|
||||
// a launch from a session or --pm refuses thread-required. Every tick
|
||||
// (threadTickMs) the host asks the broker for the business's threads
|
||||
// (launch op threadsState) and:
|
||||
@@ -142,6 +142,7 @@ import { createServer } from "node:net";
|
||||
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync } from "node:fs";
|
||||
import { dirname, join, relative } from "node:path";
|
||||
import { configDir, loadBusiness, resolveInstance, systemVars } from "../../business/src/index.mjs";
|
||||
+import { THREAD_DEFINITIONS } from "../../business/src/vocabulary.mjs";
|
||||
import { limitHit } from "../../business/src/launch.mjs";
|
||||
import { BundleError, buildBundle, hasFallback, readSkills, sessionModel } from "../../harness/src/bundle.mjs";
|
||||
import { createLoader } from "../../plugins/src/loader.mjs";
|
||||
@@ -179,8 +180,6 @@ const STOP_TIMEOUT_MS = 30000;
|
||||
const LINE_MAX = 4096;
|
||||
// How often the host asks for the threads' state; a poll period, not a limit.
|
||||
const THREAD_TICK_MS = 2000;
|
||||
-// The broker's thread instance definition (packages/bus/src/broker.mjs).
|
||||
-const THREAD_DEFINITION = "assistant";
|
||||
// Row 194: the broker's LIFECYCLE_REQUEST_MS. A regenerate's old run must be gone by then.
|
||||
const LIFECYCLE_REQUEST_MS = 60000;
|
||||
|
||||
@@ -334,7 +333,7 @@ export function createLauncher({
|
||||
try { b=loadBusiness(host.business,{dir:configDir(env),rolesDir:rolesDir(env)}); } catch(e){throw new Refusal("organization-refused",e.message);}
|
||||
if (!b.launch) throw new Refusal("launch-not-configured", `business ${b.id} has no launch block`);
|
||||
if (!(pm ? instance === b.launch.by : b.launch.instances.includes(instance) || (human && Object.hasOwn(b.roles, instance)))) throw new Refusal("instance-not-listed");
|
||||
- const threaded = b.roles[instance]?.definition === THREAD_DEFINITION;
|
||||
+ const threaded = THREAD_DEFINITIONS.includes(b.roles[instance]?.definition);
|
||||
if (threaded && !thread) throw new Refusal("thread-required", `${instance} runs only for a thread`);
|
||||
if (!threaded && thread) throw new Refusal("thread-not-allowed", `${instance} isn't a thread instance`);
|
||||
if (threaded && !session) throw new Refusal("session-required", `${instance} runs for one session of a thread`);
|
||||
@@ -1014,7 +1013,7 @@ export function createLauncher({
|
||||
function ending(r) {
|
||||
const runs = r.runs ?? [];
|
||||
const at = Date.parse(r.at);
|
||||
- const threaded = b.roles[r.instance]?.definition === THREAD_DEFINITION;
|
||||
+ const threaded = THREAD_DEFINITIONS.includes(b.roles[r.instance]?.definition);
|
||||
return registry.sessions.filter((s) => s.business === b.id && (runs.includes(s.run) ||
|
||||
(!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..baabd843e 100644
|
||||
--- a/packages/cli/tests/launcher.test.mjs
|
||||
+++ b/packages/cli/tests/launcher.test.mjs
|
||||
@@ -773,21 +773,34 @@ 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 });
|
||||
- const { f, host, launcher } = await setup(t, undefined, given);
|
||||
- // The chief of staff holds role.launch; a test chief session bound to this process asks.
|
||||
- const chief = await host.bindLaunch({ business: "acme", role: "chief", run: "chief-test", harness: "pi", pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
- await new Client({ path: host.path, cap: chief.cap }).call("role.claim");
|
||||
- // The bundle's refusal comes back as launch-failed, as webPlan's does, with its reason in the log.
|
||||
- assert.deepEqual(await launcher.fromSession(chief.cap, "bean"), { ok: false, error: "launch-failed" });
|
||||
- const [e] = log(f);
|
||||
- assert.deepEqual([e.event, e.code, log(f).length], ["refused", "launch-failed", 1]);
|
||||
+ // 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, session: SESSION, instance: 'bean', holder: null, pending: 1 }])
|
||||
+ : host.op(message),
|
||||
+ }) });
|
||||
+ // The thread path records row 270's run-start count before the bundle's persona refusal.
|
||||
+ await launcher.tick();
|
||||
+ const runs = readdirSync(join(f.dataRoot, "launches", "acme"));
|
||||
+ const entries = log(f);
|
||||
+ assert.equal(entries.length, 2);
|
||||
+ const { at, ...compactions } = entries[0];
|
||||
+ assert.deepEqual(compactions, { event: 'compactions', instance: 'bean', thread, session: SESSION, run: runs[0], count: 0, known: true, reason: null });
|
||||
+ const e = entries[1];
|
||||
+ assert.deepEqual([e.event, e.code], ["refused", "launch-failed"]);
|
||||
+ assert.equal(e.thread, thread);
|
||||
assert.equal(e.why, `instance bean: persona file ${join(dir, "bean.md")} isn't the file persona.sha256 names`);
|
||||
assert.ok(!JSON.stringify(log(f)).includes("PERSONA-MARKER-d2"));
|
||||
assert.deepEqual(readSessions(f.dataRoot), []);
|
||||
// The run directory exists by then (BUILD.md residual); the persona is read before any bundle file.
|
||||
- const runs = readdirSync(join(f.dataRoot, "launches", "acme"));
|
||||
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, "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) => {
|
||||
diff --git a/packages/cli/tests/thread-launch.test.mjs b/packages/cli/tests/thread-launch.test.mjs
|
||||
index 0d207a0a0..fa3adb866 100644
|
||||
--- a/packages/cli/tests/thread-launch.test.mjs
|
||||
+++ b/packages/cli/tests/thread-launch.test.mjs
|
||||
@@ -396,6 +396,22 @@ test("REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a t
|
||||
assert.deepEqual(launchLog(f).map((e) => [e.event, e.instance, e.code]), [["refused", "assistant", "thread-required"]]);
|
||||
});
|
||||
|
||||
+// Admission refuses before bundle construction or a sandbox is needed.
|
||||
+test('C2-09a: fromSession refuses a creative instance outside a thread without a sandbox', { timeout: 30000 }, async t => {
|
||||
+ const prepared = prepare(t, { edit: doc => {
|
||||
+ doc.roles.bean = { ...doc.roles.assistant, definition: 'companion' };
|
||||
+ doc.launch.instances.push('bean');
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ const { f } = prepared;
|
||||
+ const host = await start(t, prepared);
|
||||
+ const chief = await host.host.bindLaunch({ business: 'acme', role: 'chief', run: 'chief-bean-refusal', harness: 'pi', pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
+ await new Client({ path: host.host.path, cap: chief.cap }).call('role.claim');
|
||||
+ assert.deepEqual(await host.launcher.fromSession(chief.cap, 'bean'), { ok: false, error: 'thread-required' });
|
||||
+ assert.deepEqual(readSessions(f.dataRoot), []);
|
||||
+ assert.deepEqual(launchLog(f).map(e => [e.event, e.instance, e.code]), [['refused', 'bean', 'thread-required']]);
|
||||
+});
|
||||
+
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the token-limit check switched on, with the
|
||||
// assistant's limit at 0, so it is at its limit before any turn. The real check runs through the
|
||||
// bus's plug-in loader.
|
||||
@@ -443,3 +459,73 @@ test("REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn:
|
||||
assert.deepEqual(threadRuns(f, A), []);
|
||||
assert.equal(host.runtime.threadsState("acme").find((x) => x.thread === A).holder, null);
|
||||
});
|
||||
+
|
||||
+test('C2-09a: creative thread messages start distinct runs and keep each instance history separate', { skip, timeout: 90000 }, async t => {
|
||||
+ const prepared = prepare(t, { sonnet: 2, idle: 60, edit: doc => {
|
||||
+ const vars = { ...doc.roles.assistant.vars };
|
||||
+ delete doc.roles.assistant;
|
||||
+ doc.roles.bean = { definition: 'companion', vars: { ...vars } };
|
||||
+ doc.roles.chet = { definition: 'continuity', vars: { ...vars } };
|
||||
+ doc.launch.instances = ['coder', 'bean', 'chet'];
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ const host = await start(t, prepared), { f } = prepared;
|
||||
+ const project = host.call('project.create', { name: 'Writing' }).id;
|
||||
+ const bean = host.call('thread.create', { project, name: 'Bean', instance: 'bean' }).id;
|
||||
+ const chet = host.call('thread.create', { project, name: 'Chet', instance: 'chet' }).id;
|
||||
+ const send = async (thread, instance, body) => {
|
||||
+ const message = host.call('thread.send', { thread, body });
|
||||
+ const outcome = await until(() => host.call('thread.messages', { thread }).find(m => m.in_reply_to === message.id) ||
|
||||
+ launchLog(f).find(row => row.thread === thread && row.event === 'refused'));
|
||||
+ assert.notEqual(outcome.event, 'refused', `creative thread launch refused: ${outcome.code}`);
|
||||
+ const reply = outcome;
|
||||
+ assert.equal(reply.from_role, instance);
|
||||
+ assert.equal(reply.to_role, 'human');
|
||||
+ return JSON.parse(reply.body.match(/THREAD (\{.*\})/)[1]);
|
||||
+ };
|
||||
+ assert.deepEqual((await send(bean, 'bean', 'Bean input')).before, []);
|
||||
+ assert.deepEqual((await send(chet, 'chet', 'Chet input')).before, []);
|
||||
+ assert.deepEqual((await send(bean, 'bean', 'Bean again')).before, ['Bean input']);
|
||||
+ assert.equal(readFileSync(join(f.dataRoot, 'threads', 'acme', bean, 'sessions', host.runtime.threadsState('acme').find(x => x.thread === bean).session, 'session', 'history'), 'utf8'), 'Bean input\nBean again\n');
|
||||
+ assert.equal(readFileSync(join(f.dataRoot, 'threads', 'acme', chet, 'sessions', host.runtime.threadsState('acme').find(x => x.thread === chet).session, 'session', 'history'), 'utf8'), 'Chet input\n');
|
||||
+ assert.equal(existsSync(join(f.dataRoot, 'threads', 'acme', bean, 'session')), false);
|
||||
+ assert.equal(existsSync(join(f.dataRoot, 'threads', 'acme', chet, 'session')), false);
|
||||
+ const launches = launchLog(f).filter(row => row.event === 'launch');
|
||||
+ assert.ok(launches.some(row => row.instance === 'bean' && row.thread === bean));
|
||||
+ assert.ok(launches.some(row => row.instance === 'chet' && row.thread === chet));
|
||||
+ const chief = await host.host.bindLaunch({ business: 'acme', role: 'chief', run: 'chief-creative-test', harness: 'pi', pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
+ await new Client({ path: host.host.path, cap: chief.cap }).call('role.claim');
|
||||
+ assert.deepEqual(await host.launcher.fromSession(chief.cap, 'bean'), { ok: false, error: 'thread-required' });
|
||||
+});
|
||||
+
|
||||
+test('C2-09a: terminating one creative thread does not signal an unselected peer of the same instance', { skip, timeout: 90000 }, async t => {
|
||||
+ const prepared = prepare(t, { sonnet: 2, idle: 60, edit: doc => {
|
||||
+ doc.roles.bean = { ...doc.roles.assistant, definition: 'companion' };
|
||||
+ delete doc.roles.assistant;
|
||||
+ doc.launch.instances = ['coder', 'bean'];
|
||||
+ return doc;
|
||||
+ } });
|
||||
+ let requests = [];
|
||||
+ const host = await start(t, prepared, { ops: () => ({
|
||||
+ lifecycleRequests: () => requests,
|
||||
+ lifecycleTake: () => ({ ...requests[0], go: true }),
|
||||
+ lifecycleDone: () => { requests = []; return {}; },
|
||||
+ }) });
|
||||
+ const { f } = prepared;
|
||||
+ const project = host.call('project.create', { name: 'Writing' }).id;
|
||||
+ const threads = ['one', 'two'].map(name => host.call('thread.create', { project, name, instance: 'bean' }).id);
|
||||
+ for (const thread of threads) {
|
||||
+ const message = host.call('thread.send', { thread, body: 'Stay in this thread' });
|
||||
+ const outcome = await until(() => host.call('thread.messages', { thread }).find(row => row.in_reply_to === message.id) ||
|
||||
+ launchLog(f).find(row => row.thread === thread && row.event === 'refused'));
|
||||
+ assert.notEqual(outcome.event, 'refused', `creative thread launch refused: ${outcome.code}`);
|
||||
+ }
|
||||
+ const runs = threads.map(thread => launchLog(f).find(row => row.thread === thread && row.event === 'launch').run);
|
||||
+ requests = [{ request: 'one-thread-end', state: 'open', business: 'acme', action: 'lifecycle.end',
|
||||
+ instance: 'bean', runs: [runs[0]], by: f.doc.human, at: new Date(Date.now() + 1000).toISOString() }];
|
||||
+ await host.launcher.tick();
|
||||
+ await until(() => launchLog(f).some(row => row.event === 'lifecycle-end' && row.run === runs[0]));
|
||||
+ assert.deepEqual(launchLog(f).filter(row => row.event === 'lifecycle-end').map(row => row.run), [runs[0]]);
|
||||
+ await until(() => !readSessions(f.dataRoot).some(row => row.run === runs[0]));
|
||||
+ assert.ok(readSessions(f.dataRoot).some(row => row.run === runs[1]));
|
||||
+});
|
||||
diff --git a/packages/webui/src/chat-http.mjs b/packages/webui/src/chat-http.mjs
|
||||
index 7980c1442..63d3ca974 100644
|
||||
--- a/packages/webui/src/chat-http.mjs
|
||||
+++ b/packages/webui/src/chat-http.mjs
|
||||
@@ -80,7 +80,8 @@ export async function chatHTTP(req, res, { path, search, chat, named, send, prev
|
||||
(Object.hasOwn(v, 'repo') && (typeof v.repo !== 'string' || !KEY.test(v.repo)))) throw Error();
|
||||
action = 'createProject'; args = v;
|
||||
} else if (path === '/api/chat/threads') {
|
||||
- if (!exact(v, ['project', 'name']) || !id(v.project) || !name(v.name)) throw Error();
|
||||
+ if (!exact(v, ['project', 'name', 'instance'], ['project', 'name']) || !id(v.project) || !name(v.name) ||
|
||||
+ (Object.hasOwn(v, 'instance') && (typeof v.instance !== 'string' || !KEY.test(v.instance)))) throw Error();
|
||||
action = 'createThread'; args = v;
|
||||
} else if (match?.[2] === 'messages') {
|
||||
if (!exact(v, ['body']) || typeof v.body !== 'string' || !v.body.trim() || v.body.length > 32768) throw Error();
|
||||
diff --git a/packages/webui/src/chat.mjs b/packages/webui/src/chat.mjs
|
||||
index 1b0a41dce..5a1ed8bf1 100644
|
||||
--- a/packages/webui/src/chat.mjs
|
||||
+++ b/packages/webui/src/chat.mjs
|
||||
@@ -25,7 +25,7 @@ export function createChat({ call, owner = null }) {
|
||||
projects: () => channel('project.list', {}),
|
||||
createProject: ({ name, repo }) => channel('project.create', { name, ...(repo === undefined ? {} : { repo }) }),
|
||||
threads: ({ project } = {}) => channel('thread.list', project === undefined ? {} : { project }),
|
||||
- createThread: ({ project, name }) => channel('thread.create', { project, name }),
|
||||
+ createThread: ({ project, name, instance }) => channel('thread.create', { project, name, ...(instance === undefined ? {} : { instance }) }),
|
||||
messages: ({ thread, after, limit }) => channel('thread.messages', { thread, ...(after ? { after } : {}), limit }),
|
||||
send: ({ thread, body }) => channel('thread.send', { thread, body, class: 'REQUEST' }),
|
||||
open: ({ thread }) => channel('thread.open', { thread }),
|
||||
diff --git a/packages/webui/src/public/chat.js b/packages/webui/src/public/chat.js
|
||||
index a6b805c1b..15066bdc6 100644
|
||||
--- a/packages/webui/src/public/chat.js
|
||||
+++ b/packages/webui/src/public/chat.js
|
||||
@@ -14,7 +14,7 @@
|
||||
return states.get(id);
|
||||
};
|
||||
const form = key => {
|
||||
- if (!forms.has(key)) forms.set(key, { name: '', repo: '', receipt: '', pending: false });
|
||||
+ if (!forms.has(key)) forms.set(key, { name: '', repo: '', instance: '', instanceChosen: false, receipt: '', pending: false });
|
||||
return forms.get(key);
|
||||
};
|
||||
class ChatError extends Error {
|
||||
@@ -58,7 +58,11 @@
|
||||
function creation(kind, key) {
|
||||
const f = form(key), project = kind === 'project';
|
||||
const repo = project && current.repos.length ? `<label>Repository (optional)<select id="chat-repo" data-chat-field="repo"><option value="">No repository link</option>${current.repos.map(r => `<option value="${esc(r)}"${r === f.repo ? ' selected' : ''}>${txt(r)}</option>`).join('')}</select></label>` : '';
|
||||
- return `<form id="chat-${kind}-form" class="chat-create" data-key="${esc(key)}"><h2>New ${kind}</h2><label>Name<input id="chat-${kind}-name" data-chat-field="name" value="${esc(f.name)}" maxlength="200" required${disabled(f.pending)}></label>${repo}<button class="btn" type="submit"${disabled(f.pending)}>${f.pending ? 'Creating…' : `Create ${kind}`}</button><p role="status">${txt(f.receipt)}</p></form>`;
|
||||
+ const choices = current.instances ?? [];
|
||||
+ const picker = project ? '' : `<label>Thread with<select id="chat-instance" data-chat-field="instance" required${disabled(f.pending || !!current.instanceError || !choices.length)}><option value="">Choose who this thread is with</option>${choices.map(row => `<option value="${esc(row.instance)}"${row.instance === f.instance ? ' selected' : ''}>${txt(row.name === row.instance ? row.instance : `${row.name} (${row.instance})`)}</option>`).join('')}</select></label>`;
|
||||
+ const unavailable = !project && (!!current.instanceError || !choices.some(row => row.instance === f.instance));
|
||||
+ const status = !project && current.instanceError ? current.instanceError : f.receipt || (!project && !choices.length ? 'No thread instances are configured.' : '');
|
||||
+ return `<form id="chat-${kind}-form" class="chat-create" data-key="${esc(key)}"><h2>New ${kind}</h2><label>Name<input id="chat-${kind}-name" data-chat-field="name" value="${esc(f.name)}" maxlength="200" required${disabled(f.pending)}></label>${repo}${picker}<button class="btn" type="submit"${disabled(f.pending || unavailable)}>${f.pending ? 'Creating…' : `Create ${kind}`}</button><p role="status">${txt(status)}</p></form>`;
|
||||
}
|
||||
function threads(rows) {
|
||||
return rows.length ? `<ul class="chat-thread-list">${rows.map(t => `<li>${link('threads', t.id, t.name)} <span class="muted">${txt(t.instance)}</span></li>`).join('')}</ul>` : '<p>No threads yet.</p>';
|
||||
@@ -106,7 +110,7 @@
|
||||
const f = document.getElementById(keep.field.id);
|
||||
if (f && !f.disabled) {
|
||||
f.focus({ preventScroll: true });
|
||||
- if (keep.field.start !== null) f.setSelectionRange(keep.field.start, keep.field.end);
|
||||
+ if (keep.field.start != null && typeof f.setSelectionRange === 'function') f.setSelectionRange(keep.field.start, keep.field.end);
|
||||
}
|
||||
} else if (navigated) c.container.querySelector('h1')?.focus({ preventScroll: true });
|
||||
}
|
||||
@@ -126,7 +130,7 @@
|
||||
paint(); return;
|
||||
}
|
||||
const old = current;
|
||||
- current = { container, kind, id, canSend, projects: old?.projects ?? [], threads: old?.threads ?? [], repos: old?.repos ?? [], error: '', refused: false };
|
||||
+ current = { container, kind, id, canSend, projects: old?.projects ?? [], threads: old?.threads ?? [], repos: old?.repos ?? [], instances: old?.instances ?? [], instanceError: kind === 'project' ? 'Reading thread instances…' : '', error: '', refused: false };
|
||||
if (navigated || !old) container.innerHTML = '<p class="chat-loading" role="status">Reading chat…</p>';
|
||||
try {
|
||||
const s = kind === 'thread' ? state(id) : null;
|
||||
@@ -147,6 +151,25 @@
|
||||
s.receipt = 'Message shown in this conversation.'; s.receiptId = null;
|
||||
}
|
||||
}
|
||||
+ if (kind === 'project') {
|
||||
+ try {
|
||||
+ const listed = await request('instances', undefined, signal);
|
||||
+ if (g !== generation || out()) return;
|
||||
+ if (!listed.rows.every(row => typeof row?.instance === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,159}$/.test(row.instance) && typeof row.name === 'string'))
|
||||
+ throw new ChatError('invalid-response');
|
||||
+ current.instances = listed.rows; current.instanceError = '';
|
||||
+ const f = form(id);
|
||||
+ if (f.instance && !listed.rows.some(row => row.instance === f.instance)) {
|
||||
+ f.instance = ''; f.instanceChosen = true;
|
||||
+ f.receipt = 'The selected instance is no longer available. Choose who this thread is with.';
|
||||
+ }
|
||||
+ if (!f.instanceChosen && !f.instance && listed.rows.length === 1) f.instance = listed.rows[0].instance;
|
||||
+ } catch (err) {
|
||||
+ if (err.name === 'AbortError' || out() || g !== generation) return;
|
||||
+ current.instances = [];
|
||||
+ current.instanceError = "Couldn't read the thread instances; reload to try again";
|
||||
+ }
|
||||
+ }
|
||||
// Repository choices are optional metadata; an unavailable read must not block unlinked chat.
|
||||
if (kind === 'list') {
|
||||
try {
|
||||
@@ -179,7 +202,11 @@
|
||||
if (!current || out()) return;
|
||||
if (event.target.id === 'chat-body') state(current.id).draft = event.target.value;
|
||||
const f = event.target.closest('.chat-create');
|
||||
- if (f && event.target.dataset.chatField) form(f.dataset.key)[event.target.dataset.chatField] = event.target.value;
|
||||
+ if (f && event.target.dataset.chatField) {
|
||||
+ const draft = form(f.dataset.key), field = event.target.dataset.chatField;
|
||||
+ draft[field] = event.target.value;
|
||||
+ if (field === 'instance') { draft.instanceChosen = true; draft.receipt = ''; paint(); }
|
||||
+ }
|
||||
});
|
||||
document.addEventListener('scroll', event => {
|
||||
if (event.target.matches?.('.chat-log') && current?.kind === 'thread') {
|
||||
@@ -232,7 +259,8 @@
|
||||
void write('send', id, { body: state(id).draft }, `threads/${id}/messages`);
|
||||
} else if (event.target.classList.contains('chat-create')) {
|
||||
const key = event.target.dataset.key, f = form(key), project = key === 'projects';
|
||||
- const value = project ? { name: f.name, ...(f.repo ? { repo: f.repo } : {}) } : { project: key, name: f.name };
|
||||
+ if (!project && (current.instanceError || !(current.instances ?? []).some(row => row.instance === f.instance))) return;
|
||||
+ const value = project ? { name: f.name, ...(f.repo ? { repo: f.repo } : {}) } : { project: key, name: f.name, instance: f.instance };
|
||||
void write(project ? 'createProject' : 'createThread', key, value, project ? 'projects' : 'threads');
|
||||
}
|
||||
});
|
||||
diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs
|
||||
index cd51a0b6e..56fcdd4e1 100644
|
||||
--- a/packages/webui/src/serve.mjs
|
||||
+++ b/packages/webui/src/serve.mjs
|
||||
@@ -8,6 +8,7 @@ import { BusReadError, busStatus as coreBusStatus, subjectOk, sendOutcome } from
|
||||
// Row 176, sage-1111: HTTP-only tester refusals; the row-164 transport pin stays untouched.
|
||||
const busStatus = code => ['tester-off', 'tester-required'].includes(code) ? 403 : coreBusStatus(code);
|
||||
import { ReadError, readStatus, fieldTable } from './reads.mjs';
|
||||
+import { THREAD_DEFINITIONS } from '../../business/src/vocabulary.mjs';
|
||||
import { chatHTTP } from './chat-http.mjs';
|
||||
import { processingHTTP } from './processing-http.mjs';
|
||||
|
||||
@@ -740,6 +741,25 @@ export async function startServer({ host = '127.0.0.1', port = 7330, board = DEF
|
||||
if (req.method !== 'POST') return json(res, 405, { error: 'method not allowed' });
|
||||
return busSend(req, res, { send, preview: signer, log });
|
||||
}
|
||||
+ // Row 219: labels only, from this listener's own human or tester bus, after auth above.
|
||||
+ if (path === '/api/chat/instances') {
|
||||
+ if (req.method !== 'GET') return json(res, 405, { error: 'method-not-allowed' });
|
||||
+ if (search) return json(res, 400, { error: 'invalid-request' });
|
||||
+ if (!bus?.instances) return json(res, 503, { error: 'not-configured' });
|
||||
+ try {
|
||||
+ const value = await bus.instances();
|
||||
+ if (!value || !value.instances || typeof value.instances !== 'object' || Array.isArray(value.instances))
|
||||
+ throw new BusReadError('invalid-response');
|
||||
+ const rows = Object.entries(value.instances)
|
||||
+ .filter(([, entry]) => THREAD_DEFINITIONS.includes(entry?.definition))
|
||||
+ .map(([instance, entry]) => ({ instance, name: entry.vars?.['persona.name'] || instance }));
|
||||
+ if (rows.some(row => typeof row.name !== 'string')) throw new BusReadError('invalid-response');
|
||||
+ return json(res, 200, { rows, at: new Date().toISOString() });
|
||||
+ } catch (err) {
|
||||
+ const code = err instanceof BusReadError ? err.code : 'invalid-response';
|
||||
+ return json(res, busStatus(code), { error: code });
|
||||
+ }
|
||||
+ }
|
||||
if (path === '/api/chat' || path.startsWith('/api/chat/')) {
|
||||
return chatHTTP(req, res, { path, search, chat, named, send, preview: writer, log });
|
||||
}
|
||||
diff --git a/packages/webui/tests/chat-browser.test.mjs b/packages/webui/tests/chat-browser.test.mjs
|
||||
index f3eeeca96..cc3ec093d 100644
|
||||
--- a/packages/webui/tests/chat-browser.test.mjs
|
||||
+++ b/packages/webui/tests/chat-browser.test.mjs
|
||||
@@ -12,6 +12,7 @@ const HOSTILE = '<img src=x onerror="window.injected=1">\u001b[31m\u202eevil';
|
||||
const stub = `(() => {
|
||||
const real = fetch.bind(window);
|
||||
window.__writes=[];window.__reads=[];window.__answers=[];window.__pages=[];
|
||||
+ window.__instances=[{instance:'assistant',name:'assistant'}];
|
||||
window.__projects=[{id:'${P}', name:${JSON.stringify(HOSTILE)}, repo:null},{id:'\"><img src=x>',name:'Invalid record'}];
|
||||
window.__threads=[{id:'${A}',project:'${P}',name:'alpha',instance:'assistant'}, {id:'${B}',project:'${P}',name:'beta',instance:'assistant'}];
|
||||
window.fetch=async (url,init={})=>{
|
||||
@@ -33,6 +34,7 @@ const stub = `(() => {
|
||||
window.__reads.push(path);
|
||||
if(window.__holdRead && path.includes(window.__holdRead)){window.__heldSignal=init.signal;await new Promise(r=>window.__releaseRead=r);}
|
||||
if(window.__readFailure)return new Response(JSON.stringify({error:window.__readFailure}),{status:window.__readFailure==='thread-not-owned'?403:503});
|
||||
+ if(path==='/api/chat/instances')return window.__instanceFailure ? new Response(JSON.stringify({error:'not-configured'}),{status:503}) : data({rows:window.__instances});
|
||||
if(path==='/api/chat/projects')return data({rows:window.__projects});
|
||||
if(path.startsWith('/api/chat/threads')&&!path.includes('/messages'))return data({rows:window.__threads});
|
||||
if(window.__pages.length)return data(window.__pages.shift());
|
||||
@@ -82,7 +84,7 @@ test('chat browser: list/create named projects and threads, hostile labels inert
|
||||
await b.evaluate(`window.__answers.push({body:{id:'${A}',instance:'assistant'}}),true`);
|
||||
await click('#chat-thread-form button[type=submit]');
|
||||
await wait('document.querySelector("#chat-send-form")');
|
||||
- assert.deepEqual(await b.evaluate('window.__writes[1].body'), { project: P, name: 'named thread' });
|
||||
+ assert.deepEqual(await b.evaluate('window.__writes[1].body'), { project: P, name: 'named thread', instance: 'assistant' });
|
||||
assert.equal(await b.evaluate('window.__writes[1].path'), '/api/chat/threads');
|
||||
assert.equal(await b.evaluate('window.__writes.length'), 2);
|
||||
});
|
||||
@@ -264,3 +266,65 @@ test('chat browser: a late project creation receipt cannot navigate away from an
|
||||
assert.equal(await b.evaluate('location.hash'), '#/chat/threads/' + A);
|
||||
assert.equal(await b.evaluate('document.querySelector("#chat-body").value'), 'stay in alpha');
|
||||
});
|
||||
+
|
||||
+test('C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST', async t => {
|
||||
+ const { b, wait, set, click, refresh } = await setup(t);
|
||||
+ await b.evaluate(`window.__instances=[{instance:'bean',name:${JSON.stringify(HOSTILE)}},{instance:'chet',name:${JSON.stringify(HOSTILE)}}];location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelectorAll("#chat-instance option").length===3');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").required'), true);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ const labels = await b.evaluate('[...document.querySelectorAll("#chat-instance option")].map(o=>o.textContent)');
|
||||
+ assert.match(labels[1], /\(bean\)/);
|
||||
+ assert.match(labels[2], /\(chet\)/);
|
||||
+ assert.doesNotMatch(labels.join(''), /[\u202a-\u202e\u2066-\u2069]/u);
|
||||
+ assert.equal(await b.evaluate('!!document.querySelector("#chat-thread-form img")'), false);
|
||||
+ assert.equal(await b.evaluate('window.injected'), undefined);
|
||||
+ await set('#chat-thread-name', 'Bean discussion');
|
||||
+ await click('#chat-thread-form button');
|
||||
+ assert.equal(await b.evaluate('window.__writes.length'), 0);
|
||||
+ await set('#chat-instance', 'bean');
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), 'bean');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-name").value'), 'Bean discussion');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), false);
|
||||
+ await b.evaluate(`window.__answers.push({body:{id:'${A}',instance:'bean'}});true`);
|
||||
+ await click('#chat-thread-form button');
|
||||
+ await wait('window.__writes.length===1');
|
||||
+ assert.deepEqual(await b.evaluate('window.__writes[0]'), { path: '/api/chat/threads', body: { project: P, name: 'Bean discussion', instance: 'bean' }, redirect: 'manual' });
|
||||
+});
|
||||
+
|
||||
+test('C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching', async t => {
|
||||
+ const { b, wait, set, refresh } = await setup(t);
|
||||
+ await b.evaluate(`window.__instanceFailure=true;location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelector("#chat-thread-form") && !document.querySelector(".chat-loading")');
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /read the thread instances/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await b.evaluate('window.__instanceFailure=false;window.__instances=[];true');
|
||||
+ await refresh();
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /No thread instances/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await b.evaluate("window.__instances=[{instance:'bean',name:'Bean'},{instance:'chet',name:'Chet'}];true");
|
||||
+ await refresh();
|
||||
+ await set('#chat-instance', 'bean');
|
||||
+ await b.evaluate("window.__instances=[{instance:'chet',name:'Chet'}];true");
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '');
|
||||
+ assert.match(await b.evaluate('document.querySelector("#chat-thread-form [role=status]").textContent'), /no longer available/);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ await refresh();
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), '', 'another refresh must not silently select the one remaining instance');
|
||||
+ await set('#chat-instance', 'chet');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), false);
|
||||
+});
|
||||
+
|
||||
+test('C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread', async t => {
|
||||
+ const { b, wait } = await setup(t, '?readonly');
|
||||
+ await b.evaluate(`location.hash='#/chat/projects/${P}';true`);
|
||||
+ await wait('document.querySelectorAll("#chat-instance option").length===2');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").value'), 'assistant');
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-instance").disabled'), true);
|
||||
+ assert.equal(await b.evaluate('document.querySelector("#chat-thread-form button").disabled'), true);
|
||||
+ assert.match(await b.evaluate('document.querySelector(".chat-area").textContent'), /only reads/);
|
||||
+ assert.equal(await b.evaluate('window.__writes.length'), 0);
|
||||
+});
|
||||
diff --git a/packages/webui/tests/chat-instances.test.mjs b/packages/webui/tests/chat-instances.test.mjs
|
||||
new file mode 100644
|
||||
index 000000000..893c38f80
|
||||
--- /dev/null
|
||||
+++ b/packages/webui/tests/chat-instances.test.mjs
|
||||
@@ -0,0 +1,87 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { request } from 'node:http';
|
||||
+import { mkdtempSync, rmSync } from 'node:fs';
|
||||
+import { join } from 'node:path';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { startServer } from '../src/serve.mjs';
|
||||
+import { startTesterSocket, TESTER_ORIGIN } from '../src/tester-socket.mjs';
|
||||
+import { close } from './fixture.mjs';
|
||||
+
|
||||
+const path = '/api/chat/instances';
|
||||
+const preview = { host: 'chat.example', header: 'x-user', user: 'jason' };
|
||||
+const snapshot = {
|
||||
+ revision: 'a'.repeat(64), plugins: { private: 'do-not-project' },
|
||||
+ instances: {
|
||||
+ assistant: { definition: 'assistant', vars: { model: 'private-model' } },
|
||||
+ bean: { definition: 'companion', vars: { 'persona.name': 'Bean', 'persona.sha256': 'private-hash' } },
|
||||
+ chet: { definition: 'continuity', vars: { 'persona.name': 'Bean', file: '/private/path' } },
|
||||
+ pm: { definition: 'pm', vars: { 'persona.name': 'Hidden PM' } },
|
||||
+ },
|
||||
+};
|
||||
+function get(server, { route = path, method = 'GET', headers = {} } = {}) {
|
||||
+ const address = server.address(), unix = typeof address === 'string';
|
||||
+ return new Promise((resolve, reject) => {
|
||||
+ const req = request({ ...(unix ? { socketPath: address } : { host: '127.0.0.1', port: address.port }),
|
||||
+ path: route, method, headers: { host: unix ? new URL(TESTER_ORIGIN).host : preview.host, ...headers } }, res => {
|
||||
+ let text = '';
|
||||
+ res.on('data', chunk => text += chunk);
|
||||
+ res.on('end', () => resolve({ status: res.statusCode, text, value: JSON.parse(text) }));
|
||||
+ });
|
||||
+ req.on('error', reject); req.end();
|
||||
+ });
|
||||
+}
|
||||
+test('C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads', async t => {
|
||||
+ let calls = 0;
|
||||
+ const server = await startServer({ port: 0, preview, bus: { instances: async () => { calls++; return snapshot; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const refused = await get(server);
|
||||
+ assert.equal(refused.status, 401);
|
||||
+ assert.equal(calls, 0);
|
||||
+ const answer = await get(server, { headers: { 'x-user': 'jason' } });
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(answer.value.rows, [{ instance: 'assistant', name: 'assistant' }, { instance: 'bean', name: 'Bean' }, { instance: 'chet', name: 'Bean' }]);
|
||||
+ for (const row of answer.value.rows) assert.deepEqual(Object.keys(row).sort(), ['instance', 'name']);
|
||||
+ assert.doesNotMatch(answer.text, /private|Hidden PM/);
|
||||
+ assert.equal(calls, 1);
|
||||
+ for (const options of [{ route: path + '?extra=1' }, { method: 'POST' }]) {
|
||||
+ const result = await get(server, { ...options, headers: { 'x-user': 'jason' } });
|
||||
+ assert.ok([400, 405].includes(result.status));
|
||||
+ }
|
||||
+ assert.equal(calls, 1, 'invalid metadata requests never call a bus');
|
||||
+});
|
||||
+test('C2-09a metadata uses the private tester listener own bus and no human transport', async t => {
|
||||
+ const root = mkdtempSync(join(tmpdir(), 'chat219-')); t.after(() => rmSync(root, { recursive: true, force: true }));
|
||||
+ let reads = 0;
|
||||
+ const server = await startTesterSocket({ dataRoot: root, board: 'http://127.0.0.1:9',
|
||||
+ bus: { instances: async () => { reads++; return { instances: { quill: { definition: 'proofreader', vars: { 'persona.name': 'Quill' } } } }; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const answer = await get(server);
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(answer.value.rows, [{ instance: 'quill', name: 'Quill' }]);
|
||||
+ assert.equal(reads, 1);
|
||||
+});
|
||||
+test('C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields', async t => {
|
||||
+ for (const bus of [null, { instances: async () => ({ instances: [] }) }, { instances: async () => { throw new Error('private-path'); } }]) {
|
||||
+ const server = await startServer({ port: 0, preview, bus }); t.after(() => close(server));
|
||||
+ const answer = await get(server, { headers: { 'x-user': 'jason' } });
|
||||
+ assert.ok(answer.status >= 400);
|
||||
+ assert.doesNotMatch(answer.text, /private-path/);
|
||||
+ }
|
||||
+});
|
||||
+
|
||||
+test('C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity', async t => {
|
||||
+ let session = null, reads = 0;
|
||||
+ const touches = [];
|
||||
+ const sso = { publicHost: 'sso-chat.example', publicOrigin: 'https://sso-chat.example', formTargets: () => [],
|
||||
+ session: (_req, { touch }) => { touches.push(touch); return session; } };
|
||||
+ const server = await startServer({ port: 0, sso, bus: { instances: async () => { reads++; return snapshot; } } });
|
||||
+ t.after(() => close(server));
|
||||
+ const headers = { host: sso.publicHost };
|
||||
+ assert.equal((await get(server, { headers })).status, 401);
|
||||
+ assert.equal(reads, 0);
|
||||
+ session = { name: 'jason' };
|
||||
+ assert.equal((await get(server, { headers })).status, 200);
|
||||
+ assert.equal(reads, 1);
|
||||
+ assert.deepEqual(touches, [false, false]);
|
||||
+});
|
||||
diff --git a/packages/webui/tests/chat.test.mjs b/packages/webui/tests/chat.test.mjs
|
||||
index 8c11611cf..b47ecf1a7 100644
|
||||
--- a/packages/webui/tests/chat.test.mjs
|
||||
+++ b/packages/webui/tests/chat.test.mjs
|
||||
@@ -335,3 +335,21 @@ test('the chat seam names the transport it is given: the human one and the teste
|
||||
assert.throws(() => createChat({}), { name: 'TypeError', message: 'chat needs a bus transport function' });
|
||||
assert.equal(typeof createChat({ call: async () => ({}) }).projects, 'function');
|
||||
});
|
||||
+
|
||||
+test('C2-09a createThread forwards an explicit instance through the existing channel', async t => {
|
||||
+ const c = await setup(t);
|
||||
+ c.state.answer = { id: T, instance: 'bean' };
|
||||
+ const answer = await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'Bean work', instance: 'bean' } });
|
||||
+ assert.equal(answer.status, 200);
|
||||
+ assert.deepEqual(c.calls, [['thread.create', { project: P, name: 'Bean work', instance: 'bean' }]]);
|
||||
+ assert.equal(answer.data.instance, 'bean');
|
||||
+});
|
||||
+test('C2-09a malformed instance and extra thread fields refuse before the channel write', async t => {
|
||||
+ const c = await setup(t);
|
||||
+ for (const value of [null, 7, {}, [], '', 'bad name', 'bean/../../other']) {
|
||||
+ const answer = await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'work', instance: value } });
|
||||
+ assert.equal(answer.status, 400, JSON.stringify(value));
|
||||
+ }
|
||||
+ assert.equal((await c.get('/api/chat/threads', { method: 'POST', value: { project: P, name: 'work', instance: 'bean', extra: true } })).status, 400);
|
||||
+ assert.deepEqual(c.calls, []);
|
||||
+});
|
||||
@@ -0,0 +1,16 @@
|
||||
09569596eba8d129d0aa78c52dbf92d2a26a8f2b1960d54898eb90a810398465 packages/bus/src/broker.mjs
|
||||
b0c66c8999b567896923f6c876911dba936c6eca1ccc7aaeada51369fd613594 packages/bus/tests/creative.test.mjs
|
||||
3efd0238da60e0bfcd3b25e5256b9c213085119a86a7b852b13e7a60340d3a24 packages/bus/tests/grant-executor.test.mjs
|
||||
b7ea857637947c7a9ca45c56cea47e37e06f0fd8446ea91316990d9fa7299a7a packages/bus/tests/project-runtime.test.mjs
|
||||
760c4a5dc2881a47be2a174f92c4fcb1b6e46abb299cb045a2e3dcbc485fb334 packages/bus/tests/threads.test.mjs
|
||||
8f7d6745fffb2a0898ac80c012084ac48964748da6439a8c56facc6529ffb19b packages/bus/tests/user-principal.test.mjs
|
||||
20423a8614ada8f2d1156ab2b041e93582986a1277e86520b0909e66892e4aec packages/cli/src/launcher.mjs
|
||||
2c3f120dfdc0b52bf8ab38a88e86251be75d4b0d218e23df489dcaf815d6bc15 packages/cli/tests/launcher.test.mjs
|
||||
7f308fdf601e839194f026beb3fea279eba1e356ce2756aa4a42fa4873b79b30 packages/cli/tests/thread-launch.test.mjs
|
||||
39c6d207e026debb7db8aade5534503847d0f5c84d560ba28f3cd65490378363 packages/webui/src/chat-http.mjs
|
||||
77878dd33fd9e0381deb996969389dde21c109eaddf46a8a5c91907ec0dfe24e packages/webui/src/chat.mjs
|
||||
8e89df5fe8a9da35de41b5968afc6efcd92503e92ef28c6f557bb5371d10d1a4 packages/webui/src/public/chat.js
|
||||
443c83debe21559de2e4a6bcc07514bce9bebe209df58b8011827fcc1cabd905 packages/webui/src/serve.mjs
|
||||
d918e5b061ced9db28337a9b02c7042f9ddafaf09f32affce9f51190c0cba93f packages/webui/tests/chat-browser.test.mjs
|
||||
2bad14535372488de326b82b791b79a61e1a4ab839458535132958ef85b746eb packages/webui/tests/chat-instances.test.mjs
|
||||
7779d33d5b1dd3fe183722d0f91ff1f71e741e113cf2d5ee407f3d26428fc162 packages/webui/tests/chat.test.mjs
|
||||
@@ -0,0 +1,16 @@
|
||||
packages/bus/src/broker.mjs
|
||||
packages/bus/tests/creative.test.mjs
|
||||
packages/bus/tests/grant-executor.test.mjs
|
||||
packages/bus/tests/project-runtime.test.mjs
|
||||
packages/bus/tests/threads.test.mjs
|
||||
packages/bus/tests/user-principal.test.mjs
|
||||
packages/cli/src/launcher.mjs
|
||||
packages/cli/tests/launcher.test.mjs
|
||||
packages/cli/tests/thread-launch.test.mjs
|
||||
packages/webui/src/chat-http.mjs
|
||||
packages/webui/src/chat.mjs
|
||||
packages/webui/src/public/chat.js
|
||||
packages/webui/src/serve.mjs
|
||||
packages/webui/tests/chat-browser.test.mjs
|
||||
packages/webui/tests/chat-instances.test.mjs
|
||||
packages/webui/tests/chat.test.mjs
|
||||
@@ -0,0 +1,96 @@
|
||||
START single-bus-creative.test 2026-10-23T10:12:57.651391+00:00
|
||||
END {"label": "single-bus-creative.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T10:12:57.651391+00:00", "end": "2026-10-23T10:12:58.016551+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rAhIikO"}
|
||||
START single-bus-grant-executor.test 2026-10-23T10:12:58.018990+00:00
|
||||
END {"label": "single-bus-grant-executor.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T10:12:58.018990+00:00", "end": "2026-10-23T10:13:19.628786+00:00", "seconds": 21.61, "exit": 0, "timeout": false, "counts": {"tests": 42, "pass": 42, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-bus-grant-executor.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rB5qFSr"}
|
||||
START single-bus-project-runtime.test 2026-10-23T10:13:19.631298+00:00
|
||||
END {"label": "single-bus-project-runtime.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/project-runtime.test.mjs"], "start": "2026-10-23T10:13:19.631298+00:00", "end": "2026-10-23T10:13:20.046077+00:00", "seconds": 0.415, "exit": 0, "timeout": false, "counts": {"tests": 3, "pass": 3, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-bus-project-runtime.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rFHRKBT"}
|
||||
START single-bus-threads.test 2026-10-23T10:13:20.048159+00:00
|
||||
END {"label": "single-bus-threads.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T10:13:20.048159+00:00", "end": "2026-10-23T10:13:21.364784+00:00", "seconds": 1.317, "exit": 0, "timeout": false, "counts": {"tests": 20, "pass": 20, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r2Ck4U7"}
|
||||
START single-bus-user-principal.test 2026-10-23T10:13:21.367024+00:00
|
||||
END {"label": "single-bus-user-principal.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T10:13:21.367024+00:00", "end": "2026-10-23T10:13:21.982332+00:00", "seconds": 0.615, "exit": 0, "timeout": false, "counts": {"tests": 23, "pass": 23, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rC2Lkzs"}
|
||||
START single-cli-launcher.test 2026-10-23T10:13:21.984639+00:00
|
||||
END {"label": "single-cli-launcher.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T10:13:21.984639+00:00", "end": "2026-10-23T10:13:48.153430+00:00", "seconds": 26.169, "exit": 0, "timeout": false, "counts": {"tests": 34, "pass": 34, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rJvKWvQ"}
|
||||
START single-cli-thread-launch.test 2026-10-23T10:13:48.155987+00:00
|
||||
END {"label": "single-cli-thread-launch.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T10:13:48.155987+00:00", "end": "2026-10-23T10:14:06.157369+00:00", "seconds": 18.001, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-cli-thread-launch.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r7AlG4T"}
|
||||
START single-webui-chat-browser.test 2026-10-23T10:14:06.159688+00:00
|
||||
END {"label": "single-webui-chat-browser.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:14:06.159688+00:00", "end": "2026-10-23T10:14:24.163642+00:00", "seconds": 18.004, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-webui-chat-browser.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rWPdp6l"}
|
||||
START single-webui-chat-instances.test 2026-10-23T10:14:24.165883+00:00
|
||||
END {"label": "single-webui-chat-instances.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:14:24.165883+00:00", "end": "2026-10-23T10:14:24.330166+00:00", "seconds": 0.164, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-webui-chat-instances.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rb7PUSc"}
|
||||
START single-webui-chat.test 2026-10-23T10:14:24.332301+00:00
|
||||
END {"label": "single-webui-chat.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T10:14:24.332301+00:00", "end": "2026-10-23T10:14:24.797185+00:00", "seconds": 0.465, "exit": 0, "timeout": false, "counts": {"tests": 25, "pass": 25, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/single-webui-chat.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rlIKT2J"}
|
||||
START suite-bus 2026-10-23T10:14:24.799798+00:00
|
||||
END {"label": "suite-bus", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/access-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/account-migration.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/approval-binding.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/broker.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/business.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/channel-proof.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/chief-of-staff.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/comment-cursors.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/comment-migration.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/credential-claim.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/credential-status.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/credential-store.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/credential-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/csuite-messaging.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/daily-quota-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/decision-close.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/decision-route.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/decisions.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/end-launch.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/fire-revokes-grants.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/gitea-grant-docker.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/gitea-grant.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/gitea-migration.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/grant-enroll.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/grant-executor.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/grant-host.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/grant-migration.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/hard-waits.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/host-run.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/host-tools.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/human.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/instances-verb.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/interpreter.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/land.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/launch-notice.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/launcher-released.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/library-sync.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/library.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/lifecycle-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/lifecycle-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/limit-stop.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/limits-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/message-citation.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/message-filter.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/messaging.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/name-migration.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/peer-transport.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/peercred.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/plugins-verb.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/principal.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/process.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/processing-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345Line truncated
|
||||
START suite-cli 2026-10-23T10:14:48.226535+00:00
|
||||
END {"label": "suite-cli", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/access-boot.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/access.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/app.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/boot-status.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/case1-accept.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/case1-hostcheck.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/case2-persona-import.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/case2-unit.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/channel-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/channel-recovery.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/compactions-launch.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/config.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/follow.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/format.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/gate-lane-auth.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/gate-lane-fixtures.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/gate-lane-image.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/gate-lane-state.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/gate-lane.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/git-socket.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/grants.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/host.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/hosts.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/idle-stop-race.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/launch-account.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/launch-limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/launch-limits.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/launch-routes.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/launcher.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/lifecycle.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/limits-tokens.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/mark-read.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/notifier.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/other-tree.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/processing-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/project.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/publish-socket.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/session-clear.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/session-launch.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/stack-copy.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/stack-instances.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/stack-release-external.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/stack-release.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/stack-upgrade.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/tester-http.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/tester-reads.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/tester-threads.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/tester.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-launch.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/trackers-boot.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/transport.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/usage.test.mjs", "/mnt/storage/scratch/Line truncated
|
||||
START suite-webui 2026-10-23T10:25:17.264441+00:00
|
||||
END {"label": "suite-webui", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/agents-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/assistant.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/board-held.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/browser-edge.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/bus-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/bus.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/channel-chat.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/conversation.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/discord.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/docs-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/editor-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/editor-provenance.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/editor.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/granted-user.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/history-return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/instances-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/library-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/library-status.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/limits-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/limits-route.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/markdown-preview.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/pinned-copy.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/preview.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/processing-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/processing-ui.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/project-file.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/proof-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/proof.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/reads.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/relaunch.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/routes-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/routes.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/send-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/send.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/serve.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/service.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/settings-form.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/settings-write.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/shell.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/sso-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/sso.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/tester-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/tester-cli.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/tester-listener.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/tester-socket.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/thread-claims-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/thread-claims.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/usage-browser.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/usage.test.mjs", "/mLine truncated
|
||||
START suite-harness 2026-10-23T10:26:05.118318+00:00
|
||||
END {"label": "suite-harness", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/bundle.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/claude-gate.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/claude-session.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/gate.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/git-tools.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/mcp-server.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/pi-session.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/raise-domain.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/runner.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/skills.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/spec-tools.test.mjs", "/mnt/storage/scratch/rocko-r219-g3345/packages/harness/tests/tools.test.mjs"], "start": "2026-10-23T10:26:05.118318+00:00", "end": "2026-10-23T10:26:17.260234+00:00", "seconds": 12.142, "exit": 0, "timeout": false, "counts": {"tests": 151, "pass": 151, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/suite-harness.tap", "tmpdir": "/mnt/storage/scratch/tmp/rdlbuJf"}
|
||||
START test-auth 2026-10-23T10:26:17.263654+00:00
|
||||
END {"label": "test-auth", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-auth.sh"], "start": "2026-10-23T10:26:17.263654+00:00", "end": "2026-10-23T10:26:18.079311+00:00", "seconds": 0.816, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-auth.tap", "tmpdir": "/mnt/storage/scratch/tmp/r1JtWXh"}
|
||||
START test-conductor 2026-10-23T10:26:18.081520+00:00
|
||||
END {"label": "test-conductor", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-conductor.sh"], "start": "2026-10-23T10:26:18.081520+00:00", "end": "2026-10-23T10:26:24.911181+00:00", "seconds": 6.83, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-conductor.tap", "tmpdir": "/mnt/storage/scratch/tmp/rTbT7Gz"}
|
||||
START test-config 2026-10-23T10:26:24.913377+00:00
|
||||
END {"label": "test-config", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-config.sh"], "start": "2026-10-23T10:26:24.913377+00:00", "end": "2026-10-23T10:26:27.432721+00:00", "seconds": 2.519, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-config.tap", "tmpdir": "/mnt/storage/scratch/tmp/rXeHjrT"}
|
||||
START test-discord 2026-10-23T10:26:27.434929+00:00
|
||||
END {"label": "test-discord", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-discord.sh"], "start": "2026-10-23T10:26:27.434929+00:00", "end": "2026-10-23T10:26:34.864671+00:00", "seconds": 7.43, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-discord.tap", "tmpdir": "/mnt/storage/scratch/tmp/rB9JAZm"}
|
||||
START test-extension-package 2026-10-23T10:26:34.866931+00:00
|
||||
END {"label": "test-extension-package", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-extension-package.sh"], "start": "2026-10-23T10:26:34.866931+00:00", "end": "2026-10-23T10:26:36.233555+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-2efd-mos1439/test-extension-package.tap", "tmpdir": "/mnt/storage/scratch/tmp/rnDXVhr"}
|
||||
START test-foundation 2026-10-23T10:26:36.235644+00:00
|
||||
END {"label": "test-foundation", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-foundation.sh"], "start": "2026-10-23T10:26:36.235644+00:00", "end": "2026-10-23T10:27:13.879988+00:00", "seconds": 37.644, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-foundation.tap", "tmpdir": "/mnt/storage/scratch/tmp/ryCvPGQ"}
|
||||
START test-land-work 2026-10-23T10:27:13.882219+00:00
|
||||
END {"label": "test-land-work", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-land-work.sh"], "start": "2026-10-23T10:27:13.882219+00:00", "end": "2026-10-23T10:27:25.920760+00:00", "seconds": 12.039, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-land-work.tap", "tmpdir": "/mnt/storage/scratch/tmp/rr7Aj6K"}
|
||||
START test-queue 2026-10-23T10:27:25.922966+00:00
|
||||
END {"label": "test-queue", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-queue.sh"], "start": "2026-10-23T10:27:25.922966+00:00", "end": "2026-10-23T10:27:47.680652+00:00", "seconds": 21.758, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": ["skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219-g3345) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-queue.tap", "tmpdir": "/mnt/storage/scratch/tmp/rf7eQ8K"}
|
||||
START test-release 2026-10-23T10:27:47.682835+00:00
|
||||
END {"label": "test-release", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-release.sh"], "start": "2026-10-23T10:27:47.682835+00:00", "end": "2026-10-23T10:27:50.502936+00:00", "seconds": 2.82, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-release.tap", "tmpdir": "/mnt/storage/scratch/tmp/rZg7ntV"}
|
||||
START test-task 2026-10-23T10:27:50.505059+00:00
|
||||
END {"label": "test-task", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219-g3345/scripts/test-task.sh"], "start": "2026-10-23T10:27:50.505059+00:00", "end": "2026-10-23T10:28:05.901435+00:00", "seconds": 15.396, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": ["skip live provider cases (row 244: no provider call in the gate)", "skip live provider cases (row 244: no provider call in the gate)"], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/test-task.tap", "tmpdir": "/mnt/storage/scratch/tmp/rdZhOdC"}
|
||||
START mutant-T01 2026-10-23T10:28:05.904390+00:00
|
||||
END {"label": "mutant-T01", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: creative bindLaunch without a thread", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T10:28:05.904390+00:00", "end": "2026-10-23T10:28:06.068776+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T01.tap", "tmpdir": "/mnt/storage/scratch/tmp/ra0u5Cv"}
|
||||
START mutant-T02 2026-10-23T10:28:06.073278+00:00
|
||||
END {"label": "mutant-T02", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: explicit creative", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T10:28:06.073278+00:00", "end": "2026-10-23T10:28:06.237700+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T02.tap", "tmpdir": "/mnt/storage/scratch/tmp/raxjDbw"}
|
||||
START mutant-T03 2026-10-23T10:28:06.241790+00:00
|
||||
END {"label": "mutant-T03", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: explicit missing", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T10:28:06.241790+00:00", "end": "2026-10-23T10:28:06.406036+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T03.tap", "tmpdir": "/mnt/storage/scratch/tmp/r8U6xIi"}
|
||||
START mutant-T04 2026-10-23T10:28:06.410053+00:00
|
||||
END {"label": "mutant-T04", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: explicit creative", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T10:28:06.410053+00:00", "end": "2026-10-23T10:28:06.574472+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T04.tap", "tmpdir": "/mnt/storage/scratch/tmp/r40J2sE"}
|
||||
START mutant-T05 2026-10-23T10:28:06.578716+00:00
|
||||
END {"label": "mutant-T05", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: naming an instance", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T10:28:06.578716+00:00", "end": "2026-10-23T10:28:06.743075+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T05.tap", "tmpdir": "/mnt/storage/scratch/tmp/rzYiKuH"}
|
||||
START mutant-T06 2026-10-23T10:28:06.746526+00:00
|
||||
END {"label": "mutant-T06", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: creative thread messages", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T10:28:06.746526+00:00", "end": "2026-10-23T10:28:07.111231+00:00", "seconds": 0.365, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T06.tap", "tmpdir": "/mnt/storage/scratch/tmp/rDcILeY"}
|
||||
START mutant-T07 2026-10-23T10:28:07.114611+00:00
|
||||
END {"label": "mutant-T07", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a metadata uses the human", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:28:07.114611+00:00", "end": "2026-10-23T10:28:07.278880+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T07.tap", "tmpdir": "/mnt/storage/scratch/tmp/rSC2VpK"}
|
||||
START mutant-T08 2026-10-23T10:28:07.282442+00:00
|
||||
END {"label": "mutant-T08", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a metadata uses the human", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:28:07.282442+00:00", "end": "2026-10-23T10:28:07.446897+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T08.tap", "tmpdir": "/mnt/storage/scratch/tmp/rtkz48N"}
|
||||
START mutant-T09 2026-10-23T10:28:07.450307+00:00
|
||||
END {"label": "mutant-T09", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a malformed instance", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T10:28:07.450307+00:00", "end": "2026-10-23T10:28:07.614703+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T09.tap", "tmpdir": "/mnt/storage/scratch/tmp/rgoWDjy"}
|
||||
START mutant-T10 2026-10-23T10:28:07.618001+00:00
|
||||
END {"label": "mutant-T10", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a createThread forwards", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T10:28:07.618001+00:00", "end": "2026-10-23T10:28:07.782438+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T10.tap", "tmpdir": "/mnt/storage/scratch/tmp/reW9fHz"}
|
||||
START mutant-T11 2026-10-23T10:28:07.785854+00:00
|
||||
END {"label": "mutant-T11", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: no silent choice", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:28:07.785854+00:00", "end": "2026-10-23T10:28:08.501474+00:00", "seconds": 0.716, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T11.tap", "tmpdir": "/mnt/storage/scratch/tmp/rUbDgih"}
|
||||
START mutant-T12 2026-10-23T10:28:08.504841+00:00
|
||||
END {"label": "mutant-T12", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: no silent choice", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:28:08.504841+00:00", "end": "2026-10-23T10:28:09.270344+00:00", "seconds": 0.766, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T12.tap", "tmpdir": "/mnt/storage/scratch/tmp/rHk3Ste"}
|
||||
START mutant-T13 2026-10-23T10:28:09.273653+00:00
|
||||
END {"label": "mutant-T13", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: metadata failure", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:28:09.273653+00:00", "end": "2026-10-23T10:28:09.989159+00:00", "seconds": 0.716, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T13.tap", "tmpdir": "/mnt/storage/scratch/tmp/rsuzhDJ"}
|
||||
START mutant-T14 2026-10-23T10:28:09.992670+00:00
|
||||
END {"label": "mutant-T14", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: no silent choice", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:28:09.992670+00:00", "end": "2026-10-23T10:28:10.708154+00:00", "seconds": 0.715, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T14.tap", "tmpdir": "/mnt/storage/scratch/tmp/rp1LF4L"}
|
||||
START mutant-T15 2026-10-23T10:28:10.711476+00:00
|
||||
END {"label": "mutant-T15", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: metadata failure", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:28:10.711476+00:00", "end": "2026-10-23T10:29:17.627180+00:00", "seconds": 66.916, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T15.tap", "tmpdir": "/mnt/storage/scratch/tmp/rexq2Om"}
|
||||
START mutant-T16 2026-10-23T10:29:17.630507+00:00
|
||||
END {"label": "mutant-T16", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: metadata failure", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:29:17.630507+00:00", "end": "2026-10-23T10:29:18.396002+00:00", "seconds": 0.765, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T16.tap", "tmpdir": "/mnt/storage/scratch/tmp/rR8WkiV"}
|
||||
START mutant-T17 2026-10-23T10:29:18.399281+00:00
|
||||
END {"label": "mutant-T17", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: no silent choice", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:29:18.399281+00:00", "end": "2026-10-23T10:29:19.164854+00:00", "seconds": 0.766, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T17.tap", "tmpdir": "/mnt/storage/scratch/tmp/rKsTwMQ"}
|
||||
START mutant-T18 2026-10-23T10:29:19.168373+00:00
|
||||
END {"label": "mutant-T18", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a metadata uses the human", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:29:19.168373+00:00", "end": "2026-10-23T10:29:19.332774+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T18.tap", "tmpdir": "/mnt/storage/scratch/tmp/r0SU7Da"}
|
||||
START mutant-T19 2026-10-23T10:29:19.336197+00:00
|
||||
END {"label": "mutant-T19", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a metadata uses the human", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:29:19.336197+00:00", "end": "2026-10-23T10:29:19.500560+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T19.tap", "tmpdir": "/mnt/storage/scratch/tmp/rIuZFB1"}
|
||||
START mutant-T20 2026-10-23T10:29:19.503894+00:00
|
||||
END {"label": "mutant-T20", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a picker: metadata failure", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T10:29:19.503894+00:00", "end": "2026-10-23T10:29:20.169220+00:00", "seconds": 0.665, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T20.tap", "tmpdir": "/mnt/storage/scratch/tmp/rhbRFSs"}
|
||||
START mutant-T21 2026-10-23T10:29:20.172733+00:00
|
||||
END {"label": "mutant-T21", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a metadata uses the human", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T10:29:20.172733+00:00", "end": "2026-10-23T10:29:20.337140+00:00", "seconds": 0.164, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T21.tap", "tmpdir": "/mnt/storage/scratch/tmp/rakV3xD"}
|
||||
START mutant-T22 2026-10-23T10:29:20.340611+00:00
|
||||
END {"label": "mutant-T22", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: terminating one creative thread", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T10:29:20.340611+00:00", "end": "2026-10-23T10:29:21.156329+00:00", "seconds": 0.816, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T22.tap", "tmpdir": "/mnt/storage/scratch/tmp/riZhpGU"}
|
||||
START mutant-T23 2026-10-23T10:29:21.159751+00:00
|
||||
END {"label": "mutant-T23", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "C2-09a: fromSession refuses a creative instance outside a thread without a sandbox", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T10:29:21.159751+00:00", "end": "2026-10-23T10:29:21.524453+00:00", "seconds": 0.365, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T23.tap", "tmpdir": "/mnt/storage/scratch/tmp/rbmcPB7"}
|
||||
START mutant-T24 2026-10-23T10:29:21.528207+00:00
|
||||
END {"label": "mutant-T24", "args": ["timeout", "-k", "10", "180", "node", "--test-reporter=tap", "--test", "--test-name-pattern", "sage-1908: once the agent of an applied grant is a creative role", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T10:29:21.528207+00:00", "end": "2026-10-23T10:29:22.193573+00:00", "seconds": 0.665, "exit": 1, "timeout": false, "counts": {"tests": 1, "pass": 0, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-2efd-mos1439/mutant-T24.tap", "tmpdir": "/mnt/storage/scratch/tmp/reo5pMQ"}
|
||||
@@ -0,0 +1,5 @@
|
||||
054da642f9b0680bd7743583e4c67266d7e14e2a
|
||||
2efd127ce617a9bff8dc3bee3a3b657b0c175c07 b899095e482cb2b68919efff1e332f272203e017
|
||||
e86a84a852c9739f157033e3772243b293742983
|
||||
merge: combine row 219 with landed row 295
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
| Mutant | Result | Killing test pattern |
|
||||
|---|---|---|
|
||||
| T01 | assertion-killed | C2-09a: creative bindLaunch without a thread |
|
||||
| T02 | assertion-killed | C2-09a: explicit creative |
|
||||
| T03 | assertion-killed | C2-09a: explicit missing |
|
||||
| T04 | assertion-killed | C2-09a: explicit creative |
|
||||
| T05 | assertion-killed | C2-09a: naming an instance |
|
||||
| T06 | assertion-killed | C2-09a: creative thread messages |
|
||||
| T07 | assertion-killed | C2-09a metadata uses the human |
|
||||
| T08 | assertion-killed | C2-09a metadata uses the human |
|
||||
| T09 | assertion-killed | C2-09a malformed instance |
|
||||
| T10 | assertion-killed | C2-09a createThread forwards |
|
||||
| T11 | assertion-killed | C2-09a picker: no silent choice |
|
||||
| T12 | assertion-killed | C2-09a picker: no silent choice |
|
||||
| T13 | assertion-killed | C2-09a picker: metadata failure |
|
||||
| T14 | assertion-killed | C2-09a picker: no silent choice |
|
||||
| T15 | assertion-killed | C2-09a picker: metadata failure |
|
||||
| T16 | assertion-killed | C2-09a picker: metadata failure |
|
||||
| T17 | assertion-killed | C2-09a picker: no silent choice |
|
||||
| T18 | assertion-killed | C2-09a metadata uses the human |
|
||||
| T19 | assertion-killed | C2-09a metadata uses the human |
|
||||
| T20 | assertion-killed | C2-09a picker: metadata failure |
|
||||
| T21 | assertion-killed | C2-09a metadata uses the human |
|
||||
| T22 | assertion-killed | C2-09a: terminating one creative thread |
|
||||
| T23 | assertion-killed | C2-09a: fromSession refuses a creative instance outside a thread without a sandbox |
|
||||
| T24 | assertion-killed | sage-1908: once the agent of an applied grant is a creative role |
|
||||
@@ -0,0 +1,13 @@
|
||||
8de616a220a1330c7f05d7688040f008c821ec772a4116886cb077d9dfbd6247 BUILD.md
|
||||
128003fca0dc7d99c3368f26a89833bc0182473e9fb8b7abe2b61023936b9c55 GATE-RESULTS.json
|
||||
b889f3836dd736bf61f61eabd9abfdeb0375e982cdf4ffa7d0c19b99b90df4d5 base.txt
|
||||
5d29d2bd6f52fa45aab75521f9cd8c79b679d47f817ef448b63ec33186c3da7e build.patch
|
||||
4a2271ddbd4212324f39e608c3a35a4ae834c045cb0d13a619715017ded0ffef candidate-manifest.sha256
|
||||
5222c9f6d7c1da26f5b9447626ba8e005a7ab36006183ed36df40190b9133fb4 changed-paths.txt
|
||||
8231c2b54a60426f4ac469811aba53ba35cca9701294796f8826a59c88a0ec55 driver.log
|
||||
42e1acb53d2cf213b62012950ab2bfd66a45f51372302657eee1f669c902fe82 merge.txt
|
||||
c868213b522a241659d588d8beda2e0529abc4d20eb5210b554d80141351d3ca mutant-kill-table.md
|
||||
acf6860b5195c8a740070a400f256d0a827f6a3db84bf3b617f27213a222cdf8 reader-audit.json
|
||||
8f1b6e867ed645834a56d82fe156cabb13083e22ba59bf600bb16c50204bd8a8 reader-audit.py
|
||||
f60af3ef6e8f458ccc53975ef8c117bc30c7715842d08ff2eed61228cc0f84d9 run-inventory.sha256
|
||||
1d0547a54c9225f341ecf22f29da5302e9b8fb37fcacd11685c4e682f1c12975 runner.py
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,24 @@
|
||||
from pathlib import Path
|
||||
import subprocess,json,re,hashlib
|
||||
ROOT=Path(__file__).resolve().parents[5];P=ROOT/'agents/rocko/work/queue-219';OUT=P/'r6'
|
||||
files=sorted(ROOT.glob('packages/*/tests/**/*'))+sorted(ROOT.glob('scripts/test-*.sh'))
|
||||
files=[f for f in files if f.is_file()]
|
||||
texts={f:f.read_text(errors='replace') for f in files}
|
||||
rows=[]
|
||||
for path in (P/'changed-paths.txt').read_text().splitlines()+['packages/webui/src/public/bus.js']:
|
||||
base=Path(path).name;hits=[]
|
||||
for f,text in texts.items():
|
||||
for n,line in enumerate(text.splitlines(),1):
|
||||
if path in line or base in line:hits.append(dict(file=str(f.relative_to(ROOT)),line=n,text=line))
|
||||
rows.append(dict(path=path,hits=hits))
|
||||
pins=[]
|
||||
for f,text in texts.items():
|
||||
for n,line in enumerate(text.splitlines(),1):
|
||||
if re.search(r'(?<![0-9a-f])[0-9a-f]{64}(?![0-9a-f])',line):pins.append(dict(file=str(f.relative_to(ROOT)),line=n,text=line))
|
||||
control=ROOT/'packages/bus/tests/channel-proof.test.mjs';t=control.read_text()
|
||||
m=re.search(r'"packages/webui/src/bus.mjs": "([0-9a-f]{64})"',t);assert m
|
||||
assert hashlib.sha256((ROOT/'packages/webui/src/bus.mjs').read_bytes()).hexdigest()==m[1]
|
||||
assert subprocess.check_output(['git','diff','2efd127ce','HEAD','--','packages/webui/src/public/bus.js'],cwd=ROOT)==b''
|
||||
report=dict(head=subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip(),paths=rows,hexPins=pins,positiveControl=dict(file=str(control.relative_to(ROOT)),pin='packages/webui/src/bus.mjs',sha256=m[1],matches=True),busJsUnchanged=True)
|
||||
(OUT/'reader-audit.json').write_text(json.dumps(report,indent=2)+'\n')
|
||||
print(json.dumps(dict(paths=len(rows)-1,additionalBusJs=True,readerHits=sum(len(x['hits']) for x in rows),hexPinLines=len(pins),positiveControl=True,busJsUnchanged=True)))
|
||||
@@ -0,0 +1,54 @@
|
||||
4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945 run-2efd-mos1439/cwd-sweep-final.json
|
||||
4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945 run-2efd-mos1439/cwd-sweep.json
|
||||
a244ba4bcf1802bfec56b8b7722c269842c9d8bdf4e7171cb20ec70351380b8c run-2efd-mos1439/head.json
|
||||
9bbd1a6c433db7010b6c24b8eb80214475d561ab13f6d769daf50c497209cf90 run-2efd-mos1439/mutant-T01.tap
|
||||
f519161bed3de19178f5b1d1c9555d281b269802b621f759e49025bd85ed1bf8 run-2efd-mos1439/mutant-T02.tap
|
||||
ecd31fcf6652f3f2751538d750edd5eb4076a4072db17a07df78e0e9a9cf377a run-2efd-mos1439/mutant-T03.tap
|
||||
955fd31df9aaa5c50dbf5c38c4a51c31a2a215675689ced750f825bb8843eeed run-2efd-mos1439/mutant-T04.tap
|
||||
acc11e6db75f510e1c54c77fc787620bfd5ff78b6e86a650a9c5d7e04a3dccea run-2efd-mos1439/mutant-T05.tap
|
||||
02a790c3c05466963c3eba3d3c1624e7a87af9a4e19b2499db69502442d2cf57 run-2efd-mos1439/mutant-T06.tap
|
||||
46daf5a77b5fe1e89dbce6b271be2982a9a4e1fa6580fcfbc55251706e1ff358 run-2efd-mos1439/mutant-T07.tap
|
||||
17ab0e2e583ae2f054966a283a782ac259fc88d20c8a61d4bc1e3d9bdf9946ec run-2efd-mos1439/mutant-T08.tap
|
||||
f4afe3d142c965365c97330772e84c49a4a0de5b82eb234455de16772de40288 run-2efd-mos1439/mutant-T09.tap
|
||||
6c90bddb31a61964d6fb1d934aadcf9d113dd61b5c74f1212c82eac402ee32e6 run-2efd-mos1439/mutant-T10.tap
|
||||
c45649004ee5a91ff668c747a5cd4b01df77796836873e17e81b44dfb1630617 run-2efd-mos1439/mutant-T11.tap
|
||||
11cc0d3df8413711e2ad7ad81ec55c931c3ea39e063b17af5ec2a0d54b9840cd run-2efd-mos1439/mutant-T12.tap
|
||||
c9cea400fcff6d75f1dc8bb837f901477702eaf9a52ac4d33e9a34290033cf87 run-2efd-mos1439/mutant-T13.tap
|
||||
e79b0b05bbe075d686cabfb344c0ec4b986284d574422c8a9817083d485af0d8 run-2efd-mos1439/mutant-T14.tap
|
||||
af325623360037967309834bf5e9c57f099ffa26c15c60a82da7f6c0a8bfd781 run-2efd-mos1439/mutant-T15.tap
|
||||
4ffbe980197969e73e4dfc30fcb38edfdccd2b685f6600363ae9d611521c47df run-2efd-mos1439/mutant-T16.tap
|
||||
c3c6d33bb30fa3bdf60b1cac616bb6e5128efcc3a6d0a312a0a9f9032ef28b6b run-2efd-mos1439/mutant-T17.tap
|
||||
b93aa79e8b22c3bf297cee696aa03ee73f2eda0e0b3bcedd74fb6398506ba99f run-2efd-mos1439/mutant-T18.tap
|
||||
20a798dfa91be1fd19fc43f3ca2c4f8b4fff74efd8fb9719230aa6455cadfff8 run-2efd-mos1439/mutant-T19.tap
|
||||
0fd4bcb6d08fb00a22612bc456a2146a0679089e524f8b8553f47a1a45f23c4c run-2efd-mos1439/mutant-T20.tap
|
||||
47900e7314dd7cbebb70d593c36bdb61033e21af0bba9e021aa29a534002e821 run-2efd-mos1439/mutant-T21.tap
|
||||
e5eed94633e5328b7f1025385bfe398ce0953f4e024c6b6dd48f1812b52a721e run-2efd-mos1439/mutant-T22.tap
|
||||
d8e7b7566be3d988f073a5278bdb63e6228477b94c52a8a2dcee74ba8b96cb57 run-2efd-mos1439/mutant-T23.tap
|
||||
95c96a08e2236484ac7e9888525b0e17b65d3d939e5e6a442ad3eedf51fcc743 run-2efd-mos1439/mutant-T24.tap
|
||||
134fe70aef2b14b480167dc0d3e30e4ac50cad2152e6e944b0c209f3dead318f run-2efd-mos1439/mutants.jsonl
|
||||
48cac5f443a55beb7b9ad9b12617bc02e67c2dc995db54c596e6a0ff9722c794 run-2efd-mos1439/network-cleanup.log
|
||||
ff56abff5c017baac632cd41989b2cd1da7f70ef89814183780022f1a812a663 run-2efd-mos1439/results.jsonl
|
||||
090b4e9a4058ee5cbc6cf69d9e39976186bb3e711390f09ce4be7dc95e653dfb run-2efd-mos1439/single-bus-creative.test.tap
|
||||
df93c6986ee970e44c2e36f1ba20cb402219fc8d580e6b971074d961b3863b41 run-2efd-mos1439/single-bus-grant-executor.test.tap
|
||||
1fbe54cd9f1ce2d06db5499d970ef7052eaf852b33973102baaea5342fccd7bc run-2efd-mos1439/single-bus-project-runtime.test.tap
|
||||
1e6832c9e81e1b60700e1668b287276ca1009e41378d84c4808d35e248e97058 run-2efd-mos1439/single-bus-threads.test.tap
|
||||
23da9b118299bcbb8deaa5ea2b525355dbf08aaee69f16c94741342c1c299762 run-2efd-mos1439/single-bus-user-principal.test.tap
|
||||
076095678c2e075f15df795a3d9731dffb07df334bd2488105872da96f2d89eb run-2efd-mos1439/single-cli-launcher.test.tap
|
||||
0966a01d8a4d459d42be3cf7c36f82decfa8c8e62dac25e94b5cab1a6427d365 run-2efd-mos1439/single-cli-thread-launch.test.tap
|
||||
ea6efe8ceccf27ded164a9c8c14dc39f1d62e12fcc4eb3a8d31806e9de85bf03 run-2efd-mos1439/single-webui-chat-browser.test.tap
|
||||
384004d2ec9c0a1e30a683630331927dbd6a01c6f1c7d82a0e1ff14fda84b2ec run-2efd-mos1439/single-webui-chat-instances.test.tap
|
||||
fcf510a59af4e6b86a00200c7f3e39d83d7020e5bdb096e0c04de5e5a392f341 run-2efd-mos1439/single-webui-chat.test.tap
|
||||
32c9f244675a5a6cb93555008e11646c849b4c64330743faeef70c380969bf6d run-2efd-mos1439/suite-bus.tap
|
||||
ebd80f7b179db829eb319f741d8893ffafbabdbc92fe4a2a5f9fe9034b02cd8e run-2efd-mos1439/suite-cli.tap
|
||||
809534666dc439d35408f289986391ca66e2b65c13195b7bf8a6cea11ee11827 run-2efd-mos1439/suite-harness.tap
|
||||
0d59c1ced0045746db28792f9229f5ff11da8f1628208d9b95a122fa05d9e346 run-2efd-mos1439/suite-webui.tap
|
||||
f91fc95a173339137f981e24fbf630acfde957e32c3cd71e28304532083c6a77 run-2efd-mos1439/test-auth.tap
|
||||
dc02b870340f0078121ca4abe87bcbcccc2c751498a4a4b95c77957cc351e114 run-2efd-mos1439/test-conductor.tap
|
||||
92ea8ce5e66d892fefacc76b87d140bcfb8c5a51dc77bdf4a47a6213ac5d2898 run-2efd-mos1439/test-config.tap
|
||||
c558883538ad963b264d429c58ea9310bb32930bd1d6dfc828920ecb14f0e7ea run-2efd-mos1439/test-discord.tap
|
||||
2f068af0a46414328be11034faad14211bef616a8e7ba64a68c52d6a29f7c13e run-2efd-mos1439/test-extension-package.tap
|
||||
83dfaa21c4e4ad941088efab3f69e87ebd2f6bd3cc72ede938e21dc06da8a34f run-2efd-mos1439/test-foundation.tap
|
||||
3e2f8024027592e77790db2bbe039803060915ebf37c7b67f04071a7e83d20dc run-2efd-mos1439/test-land-work.tap
|
||||
f1d0aef960a36787e61fbe8f75c52c73fbbd32be7a3928d70ed6833af6f5afc9 run-2efd-mos1439/test-queue.tap
|
||||
fa832794ee35025fb4559d58d01a270f6bff2eb65e863e9075b797f47fa68545 run-2efd-mos1439/test-release.tap
|
||||
8cd9a6c8131b17964e135f3e26bce56aaf053d42d6749f3c30813dd454102cef run-2efd-mos1439/test-task.tap
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Row219 serial gate. Requires Sage CLEAR; all children use a process group."""
|
||||
import os,sys,time,json,signal,subprocess,tempfile,hashlib,re,glob
|
||||
from pathlib import Path
|
||||
from datetime import datetime,timezone
|
||||
ROOT=Path(__file__).resolve().parents[4]
|
||||
PACKET=Path(__file__).resolve().parent
|
||||
OUT=PACKET/'run-2efd-mos1439';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():
|
||||
sha,path=line.split(' ',1)
|
||||
if hashlib.sha256((ROOT/path).read_bytes()).hexdigest()!=sha:raise RuntimeError('candidate drift: '+path)
|
||||
def sweep():
|
||||
found=[]
|
||||
for proc in Path('/proc').glob('[0-9]*'):
|
||||
try:
|
||||
cwd=(proc/'cwd').resolve();name=(proc/'comm').read_text().strip()
|
||||
if (str(cwd).startswith(str(ROOT)) or str(cwd).startswith('/mnt/storage/scratch/tmp/')) and ('node' in name or 'chrom' in name):found.append(dict(pid=int(proc.name),name=name,cwd=str(cwd)))
|
||||
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:]]
|
||||
if args[0]!='timeout':args=['timeout','-k','10',str(deadline),*args]
|
||||
verify();short=subprocess.check_output(['mktemp','-d','/mnt/storage/scratch/tmp/rXXXXXX'],text=True).strip()
|
||||
if not re.fullmatch(r'[A-Za-z0-9/.-]+',short):raise RuntimeError('unsafe TMPDIR charset')
|
||||
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)
|
||||
if docker:env.pop('DOCKER_HOST',None)
|
||||
else:env['DOCKER_HOST']='unix:///mnt/storage/scratch/rocko-r219-dead.sock'
|
||||
log=OUT/(label+'.tap');begin=stamp();t=time.monotonic();timeout=False
|
||||
print('START',label,begin,flush=True)
|
||||
with log.open('wb') as f:
|
||||
child=subprocess.Popen(args,cwd=cwd,env=env,stdout=f,stderr=subprocess.STDOUT,start_new_session=True)
|
||||
try:rc=child.wait(timeout=deadline+15)
|
||||
except subprocess.TimeoutExpired:
|
||||
timeout=True
|
||||
try:os.killpg(child.pid,signal.SIGTERM)
|
||||
except ProcessLookupError:pass
|
||||
try:child.wait(timeout=10)
|
||||
except subprocess.TimeoutExpired:
|
||||
try:os.killpg(child.pid,signal.SIGKILL)
|
||||
except ProcessLookupError:pass
|
||||
child.wait()
|
||||
rc=child.returncode
|
||||
finally:
|
||||
try:os.killpg(child.pid,signal.SIGTERM)
|
||||
except ProcessLookupError:pass
|
||||
timeout = timeout or rc in (124,137,-9)
|
||||
text=log.read_text(errors='replace')
|
||||
counts={k:int(m[-1]) if (m:=re.findall(r'^# '+k+r' (\d+)\s*$',text,re.M)) else None for k in ['tests','pass','fail','cancelled','skipped']}
|
||||
row=dict(label=label,args=args,start=begin,end=stamp(),seconds=round(time.monotonic()-t,3),exit=rc,timeout=timeout,counts=counts,skips=[l for l in text.splitlines() if re.search(r'^skip\b|# SKIP\b',l,re.I)],log=str(log.relative_to(ROOT)),tmpdir=short)
|
||||
with (OUT/'results.jsonl').open('a') as f:f.write(json.dumps(row)+'\n')
|
||||
print('END',json.dumps(row),flush=True)
|
||||
if rc or timeout or re.search(r'^\s*not ok\b',text,re.M):raise RuntimeError('RED '+label+' '+str(log))
|
||||
return row
|
||||
singles=[line for line in (PACKET/'changed-paths.txt').read_text().splitlines() if '/tests/' in line]
|
||||
def stages():
|
||||
for path in singles:execute('single-'+Path(path).parent.parent.name+'-'+Path(path).stem,['node','--test',path],deadline=300)
|
||||
for package in ['bus','cli','webui','harness']:
|
||||
files=sorted(glob.glob(str(ROOT/'packages'/package/'tests'/'*.test.mjs')))
|
||||
execute('suite-'+package,['node','--test',*files],cwd=ROOT/'packages'/package,deadline=1800)
|
||||
for path in sorted(ROOT.glob('scripts/test-*.sh')):
|
||||
# timeout itself implements TERM then KILL, inside the dedicated child group.
|
||||
execute(path.stem,['timeout','-k','10','7200','bash',str(path)],deadline=7200,docker=True)
|
||||
# Every mutant starts from verified candidate bytes and restores in finally.
|
||||
for spec in json.loads((PACKET/'mutants.json').read_text()):
|
||||
verify();edits=[spec]+spec.get('additional_edits',[]);saved={}
|
||||
try:
|
||||
for e in edits:
|
||||
path=ROOT/e['file'];saved.setdefault(path,path.read_bytes());text=path.read_text()
|
||||
if text.count(e['old'])!=1:raise RuntimeError('anchor '+spec['id'])
|
||||
path.write_text(text.replace(e['old'],e['new'],1))
|
||||
# Mutation intentionally changes candidate bytes; execute has its own verify.
|
||||
oldverify=globals()['verify'];globals()['verify']=lambda:None
|
||||
try:
|
||||
execute('mutant-'+spec['id'],['node','--test','--test-name-pattern',spec['pattern'],spec['test']],deadline=180)
|
||||
status='survived'
|
||||
except RuntimeError:
|
||||
record=json.loads((OUT/'results.jsonl').read_text().splitlines()[-1]);text=(ROOT/record['log']).read_text(errors='replace')
|
||||
failing=re.findall(r'^\s*not ok \d+ - (.*)$',text,re.M)
|
||||
status='killed' if record['exit'] and not record['timeout'] and any(re.search(spec['pattern'],name) for name in failing) and 'SyntaxError:' not in text else 'invalid-failure'
|
||||
finally:globals()['verify']=oldverify
|
||||
finally:
|
||||
for path,data in saved.items():path.write_bytes(data)
|
||||
verify()
|
||||
with (OUT/'mutants.jsonl').open('a') as f:f.write(json.dumps(dict(id=spec['id'],status=status,test=spec['test'],pattern=spec['pattern']))+'\n')
|
||||
if status!='killed':raise RuntimeError(spec['id']+' '+status)
|
||||
if __name__=='__main__':
|
||||
if Path.cwd()!=ROOT:raise SystemExit('wrong cwd')
|
||||
head=subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip()
|
||||
expected=(PACKET/'run-head.txt').read_text().strip()
|
||||
if head!=expected:raise SystemExit('wrong HEAD')
|
||||
(OUT/'head.json').write_text(json.dumps(dict(head=head,manifest=hashlib.sha256((PACKET/'candidate-manifest.sha256').read_bytes()).hexdigest(),start=stamp())))
|
||||
verify()
|
||||
try:stages()
|
||||
finally:
|
||||
verify();(OUT/'cwd-sweep.json').write_text(json.dumps(sweep(),indent=2))
|
||||
# Remove only the owned fixture compose network, if any; never daemon/volumes.
|
||||
|
||||
with (OUT/'network-cleanup.log').open('w') as f:
|
||||
for network in ['rocko-r219-gate_default', ROOT.name+'_default']:
|
||||
subprocess.run(['docker','network','rm',network],stdout=f,stderr=subprocess.STDOUT)
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
{"head": "06d7cc2f0ffc544abfb2755f99dce76ca164212c", "manifest": "420befed0aa8291736d34187ac7e745b7660efed15348ece045a7dd8957c9124", "start": "2026-10-23T08:55:46.512736+00:00"}
|
||||
@@ -0,0 +1,2 @@
|
||||
Error response from daemon: network rocko-r219-gate_default not found
|
||||
exit status 1
|
||||
@@ -0,0 +1,14 @@
|
||||
{"label": "single-bus-creative.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T08:55:46.514934+00:00", "end": "2026-10-23T08:55:46.880147+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rlmkrn532"}
|
||||
{"label": "single-bus-grant-executor.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T08:55:46.881647+00:00", "end": "2026-10-23T08:56:08.493753+00:00", "seconds": 21.612, "exit": 0, "timeout": false, "counts": {"tests": 42, "pass": 42, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-grant-executor.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rjpu1ic5m"}
|
||||
{"label": "single-bus-project-runtime.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/project-runtime.test.mjs"], "start": "2026-10-23T08:56:08.495370+00:00", "end": "2026-10-23T08:56:08.910312+00:00", "seconds": 0.415, "exit": 0, "timeout": false, "counts": {"tests": 3, "pass": 3, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-project-runtime.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r6j9zk1mz"}
|
||||
{"label": "single-bus-threads.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T08:56:08.911614+00:00", "end": "2026-10-23T08:56:10.278831+00:00", "seconds": 1.367, "exit": 0, "timeout": false, "counts": {"tests": 20, "pass": 20, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/ridmpf8e9"}
|
||||
{"label": "single-bus-user-principal.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T08:56:10.280242+00:00", "end": "2026-10-23T08:56:10.845658+00:00", "seconds": 0.565, "exit": 0, "timeout": false, "counts": {"tests": 23, "pass": 23, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rxak25z_4"}
|
||||
{"label": "single-cli-launcher.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T08:56:10.847112+00:00", "end": "2026-10-23T08:56:37.072632+00:00", "seconds": 26.226, "exit": 0, "timeout": false, "counts": {"tests": 34, "pass": 34, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r6tlrj8kb"}
|
||||
{"label": "single-cli-thread-launch.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T08:56:37.074143+00:00", "end": "2026-10-23T08:56:55.131362+00:00", "seconds": 18.057, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-cli-thread-launch.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r9k_bmlhv"}
|
||||
{"label": "single-webui-chat-browser.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T08:56:55.132860+00:00", "end": "2026-10-23T08:57:13.336278+00:00", "seconds": 18.203, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat-browser.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r3mqd7dfy"}
|
||||
{"label": "single-webui-chat-instances.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T08:57:13.337687+00:00", "end": "2026-10-23T08:57:13.502100+00:00", "seconds": 0.164, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat-instances.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/ri0d5cw9g"}
|
||||
{"label": "single-webui-chat.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T08:57:13.503425+00:00", "end": "2026-10-23T08:57:14.018577+00:00", "seconds": 0.515, "exit": 0, "timeout": false, "counts": {"tests": 25, "pass": 25, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/single-webui-chat.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rf6pbt6z6"}
|
||||
{"label": "suite-bus", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/account-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/approval-binding.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/broker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/business.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/channel-proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/chief-of-staff.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-cursors.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-claim.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-store.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/csuite-messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/daily-quota-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-close.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decisions.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/end-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/fire-revokes-grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant-docker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-enroll.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-executor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/hard-waits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-run.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/human.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/instances-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/interpreter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/land.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launch-notice.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launcher-released.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library-sync.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-stop.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-citation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-filter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/name-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peer-transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peercred.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/plugins-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/principal.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/process.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-timeout.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-web.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-await.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-files.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-runtime.test.mjs", "/mnt/Line truncated
|
||||
{"label": "suite-cli", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/app.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/boot-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-accept.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-hostcheck.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-persona-import.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-unit.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-recovery.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/compactions-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/config.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/follow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/format.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-auth.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-fixtures.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-image.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-state.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/git-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/hosts.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/idle-stop-race.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-account.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launcher.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/lifecycle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits-tokens.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/mark-read.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/notifier.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/other-tree.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/processing-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/publish-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-clear.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release-external.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-upgrade.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-http.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-threads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/trackers-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/verbs.test.mjs"], "start": "2026-10-23T08:57:37.800853+00:00", "end": "2026-10-23T09:08:05.517184+00:00", "seconds": 627.716, "exit": 0, "timeout": false, "counts": {"tests": 921, "pass": 921, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/suite-cli.tap", "tmpdir": "/mnt/storage/scratch/tmp/r29043nvq"}
|
||||
{"label": "suite-webui", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/assistant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/board-held.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser-edge.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/channel-chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/conversation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/discord.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/docs-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-provenance.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/granted-user.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/history-return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/markdown-preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/pinned-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-ui.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-file.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/relaunch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/serve.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/service.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-form.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-write.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/shell.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-listener.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/views.test.mjs"], "start": "2026-10-23T09:08:05.524672+00:00", "end": "2026-10-23T09:09:02.641939+00:00", "seconds": 57.117, "exit": 0, "timeout": false, "counts": {"tests": 374, "pass": 373, "fail": 0, "cancelled": 0, "skipped": 1}, "skips": ["ok 107 - rebuilding from the source gives the same bytes (needLine truncated
|
||||
{"label": "suite-harness", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/bundle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/git-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/mcp-server.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/pi-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/raise-domain.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/runner.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/skills.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/spec-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/tools.test.mjs"], "start": "2026-10-23T09:09:02.645756+00:00", "end": "2026-10-23T09:09:14.638654+00:00", "seconds": 11.993, "exit": 1, "timeout": false, "counts": {"tests": 151, "pass": 150, "fail": 1, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1429/suite-harness.tap", "tmpdir": "/mnt/storage/scratch/tmp/rh85v_4j3"}
|
||||
@@ -0,0 +1,36 @@
|
||||
TAP version 13
|
||||
# organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
# organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
# Subtest: M6: a creative raise refuses decision-not-allowed, cited or not, and no decision row appears; the assistant still raises
|
||||
ok 1 - M6: a creative raise refuses decision-not-allowed, cited or not, and no decision row appears; the assistant still raises
|
||||
---
|
||||
duration_ms: 37.351559
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a creative instance sends only to the user and hears only from the user
|
||||
ok 2 - a creative instance sends only to the user and hears only from the user
|
||||
---
|
||||
duration_ms: 44.084602
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M10 through the broker: the chief and the tester are refused on bean, the human's limits.set of its models key works
|
||||
ok 3 - M10 through the broker: the chief and the tester are refused on bean, the human's limits.set of its models key works
|
||||
---
|
||||
duration_ms: 78.575531
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 256 T6 the human deletes a creative instance through the broker; the chief and the tester are refused at the verb
|
||||
ok 4 - row 256 T6 the human deletes a creative instance through the broker; the chief and the tester are refused at the verb
|
||||
---
|
||||
duration_ms: 65.006343
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
# tests 4
|
||||
# suites 0
|
||||
# pass 4
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 335.111631
|
||||
@@ -0,0 +1,262 @@
|
||||
TAP version 13
|
||||
# Subtest: row 280: an occupied TCP port is attempted, refused, and retried with our sshd
|
||||
ok 1 - row 280: an occupied TCP port is attempted, refused, and retried with our sshd
|
||||
---
|
||||
duration_ms: 85.854841
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 280: every injected picker sample is unprivileged and outside the ephemeral range
|
||||
ok 2 - row 280: every injected picker sample is unprivileged and outside the ephemeral range
|
||||
---
|
||||
duration_ms: 0.458132
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G7: an Approve installs the tagged line, logs in with the new key, and writes the key file, record and grant.applied
|
||||
ok 3 - G7: an Approve installs the tagged line, logs in with the new key, and writes the key file, record and grant.applied
|
||||
---
|
||||
duration_ms: 682.514738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G7: a commands change on a live grant updates the record in one transaction and keeps the key and line
|
||||
ok 4 - G7: a commands change on a live grant updates the record in one transaction and keeps the key and line
|
||||
---
|
||||
duration_ms: 516.713046
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failure at install or verify removes the line and leaves no record, key file or reference
|
||||
ok 5 - G8: a failure at install or verify removes the line and leaves no record, key file or reference
|
||||
---
|
||||
duration_ms: 1517.563204
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failed remove adds hostLineLeft and tells the human to sweep
|
||||
ok 6 - G8: a failed remove adds hostLineLeft and tells the human to sweep
|
||||
---
|
||||
duration_ms: 647.910884
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failure in step 5 before commit unlinks the key file, drops the reference and removes the line
|
||||
ok 7 - G8: a failure in step 5 before commit unlinks the key file, drops the reference and removes the line
|
||||
---
|
||||
duration_ms: 630.485061
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a store fault in the commit transaction ends host-failed with no record, key file, reference or line
|
||||
ok 8 - G8: a store fault in the commit transaction ends host-failed with no record, key file, reference or line
|
||||
---
|
||||
duration_ms: 630.630309
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failed step 1 check spends the decision and runs nothing remote
|
||||
ok 9 - G8: a failed step 1 check spends the decision and runs nothing remote
|
||||
---
|
||||
duration_ms: 81.046373
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G9: a registry, definition or commands change between raise and Approve ends decision-mismatch before any remote step
|
||||
ok 10 - G9: a registry, definition or commands change between raise and Approve ends decision-mismatch before any remote step
|
||||
---
|
||||
duration_ms: 521.712377
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G9: an agent no longer a role or no longer declaring host ends with its code, spent
|
||||
ok 11 - G9: an agent no longer a role or no longer declaring host ends with its code, spent
|
||||
---
|
||||
duration_ms: 70.08876
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G10: a second start refuses decision-consumed, and an unresolved or agent-resolved decision not-authorized, writing nothing
|
||||
ok 12 - G10: a second start refuses decision-consumed, and an unresolved or agent-resolved decision not-authorized, writing nothing
|
||||
---
|
||||
duration_ms: 514.836044
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G15: no event, message or decision holds the private key
|
||||
ok 13 - G15: no event, message or decision holds the private key
|
||||
---
|
||||
duration_ms: 508.872296
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23: a revoke during install ends grant.failed revoked with no key file, no grant and no line
|
||||
ok 14 - G23: a revoke during install ends grant.failed revoked with no key file, no grant and no line
|
||||
---
|
||||
duration_ms: 529.060942
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (row 249): an add that writes after an abort's remove leaves hostLineLeft until the sweep
|
||||
ok 15 - G23 (row 249): an add that writes after an abort's remove leaves hostLineLeft until the sweep
|
||||
---
|
||||
duration_ms: 862.980682
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (row 249): an add that writes after a timed-out install's remove leaves hostLineLeft until the sweep
|
||||
ok 16 - G23 (row 249): an add that writes after a timed-out install's remove leaves hostLineLeft until the sweep
|
||||
---
|
||||
duration_ms: 858.582377
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23: a revoke recorded after the raise and before the start ends step 1 revoked, and a held slot ends host-busy
|
||||
ok 17 - G23: a revoke recorded after the raise and before the start ends step 1 revoked, and a held slot ends host-busy
|
||||
---
|
||||
duration_ms: 519.682325
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G24: names at 64 characters with . and _ give distinct tags of the fixed length
|
||||
ok 18 - G24: names at 64 characters with . and _ give distinct tags of the fixed length
|
||||
---
|
||||
duration_ms: 0.396492
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after install removes the line, then ends interrupted with the tag, holding the slot until then
|
||||
ok 19 - G11: a restart after install removes the line, then ends interrupted with the tag, holding the slot until then
|
||||
---
|
||||
duration_ms: 217.46658
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after a new key's commit, with the key file written, ends with no key file, record, reference or line
|
||||
ok 20 - G11: a restart after a new key's commit, with the key file written, ends with no key file, record, reference or line
|
||||
---
|
||||
duration_ms: 222.032907
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after a commands change's commit leaves the record as it was and asks nothing of the host
|
||||
ok 21 - G11: a restart after a commands change's commit leaves the record as it was and asks nothing of the host
|
||||
---
|
||||
duration_ms: 518.824945
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11 (B2): a restart before step 1, spent or not yet spent, ends interrupted and nothing runs later
|
||||
ok 22 - G11 (B2): a restart before step 1, spent or not yet spent, ends interrupted and nothing runs later
|
||||
---
|
||||
duration_ms: 69.832285
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a remote undo that fails ends interrupted with hostLineLeft and the sweep hint
|
||||
ok 23 - G11: a remote undo that fails ends interrupted with hostLineLeft and the sweep hint
|
||||
---
|
||||
duration_ms: 280.805045
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart leaves a finished grant alone, and the reconcile adds nothing for it
|
||||
ok 24 - G11: a restart leaves a finished grant alone, and the reconcile adds nothing for it
|
||||
---
|
||||
duration_ms: 510.059757
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: N1 (G27): the start sweep unlinks host.<id> files with no record in loaded businesses only, and refuses a store dir that is not private
|
||||
ok 25 - N1 (G27): the start sweep unlinks host.<id> files with no record in loaded businesses only, and refuses a store dir that is not private
|
||||
---
|
||||
duration_ms: 6.320299
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12: the human's hosts.revoke deletes the record, the key file, the reference and the line, with a closed marker
|
||||
ok 26 - G12: the human's hosts.revoke deletes the record, the key file, the reference and the line, with a closed marker
|
||||
---
|
||||
duration_ms: 654.552501
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12 (N4): a revoke with no record still removes the computed tag's line, with granted false; bad args refuse
|
||||
ok 27 - G12 (N4): a revoke with no record still removes the computed tag's line, with granted false; bad args refuse
|
||||
---
|
||||
duration_ms: 217.275867
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G13: a revoke during install aborts the executor, which ends revoked, and the line goes
|
||||
ok 28 - G13: a revoke during install aborts the executor, which ends revoked, and the line goes
|
||||
---
|
||||
duration_ms: 538.809236
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G26: the human, the assistant and the tester revoke; the chief and a pm refuse; sweep is the human's or the tester's
|
||||
ok 29 - G26: the human, the assistant and the tester revoke; the chief and a pm refuse; sweep is the human's or the tester's
|
||||
---
|
||||
duration_ms: 500.126327
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 281 T8: a tester hosts.revoke refuses tester-dev-only once bus.tester is off, and a human revoke writes no job records
|
||||
ok 30 - row 281 T8: a tester hosts.revoke refuses tester-dev-only once bus.tester is off, and a human revoke writes no job records
|
||||
---
|
||||
duration_ms: 660.584288
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: a restart after step 1 sweeps the key file and runs step 3 once the bus is up; status shows the revoke until then
|
||||
ok 31 - G27: a restart after step 1 sweeps the key file and runs step 3 once the bus is up; status shows the revoke until then
|
||||
---
|
||||
duration_ms: 666.103534
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: after step 2 with the host down, the restart closes the marker with hostLineLeft; a marker without a revoke id is not reopened
|
||||
ok 32 - G27: after step 2 with the host down, the restart closes the marker with hostLineLeft; a marker without a revoke id is not reopened
|
||||
---
|
||||
duration_ms: 942.572259
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: a key file a revoke could not unlink is reported left and goes at the next start
|
||||
ok 33 - G27: a key file a revoke could not unlink is reported left and goes at the next start
|
||||
---
|
||||
duration_ms: 655.234738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G28: a commands change, then a revoke, then a restart leave no record, key, reference or line
|
||||
ok 34 - G28: a commands change, then a revoke, then a restart leave no record, key, reference or line
|
||||
---
|
||||
duration_ms: 681.058457
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G24 (B4): hosts.sweep removes only this business's recorded tags no live grant holds, and records what it left
|
||||
ok 35 - G24 (B4): hosts.sweep removes only this business's recorded tags no live grant holds, and records what it left
|
||||
---
|
||||
duration_ms: 989.811098
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12: the local steps finish before the host step, so a host that hangs leaves the agent no access
|
||||
ok 36 - G12: the local steps finish before the host step, so a host that hangs leaves the agent no access
|
||||
---
|
||||
duration_ms: 711.940669
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (X5): a revoke right after the spend reaches the executor's claim, so the grant ends revoked
|
||||
ok 37 - G23 (X5): a revoke right after the spend reaches the executor's claim, so the grant ends revoked
|
||||
---
|
||||
duration_ms: 209.337803
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (X5): a revoke that lands as verify returns ends revoked with no record, key file or line
|
||||
ok 38 - G23 (X5): a revoke that lands as verify returns ends revoked with no record, key file or line
|
||||
---
|
||||
duration_ms: 650.317732
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G13: a revoke whose host remove fails still drops the record and key, and reports the line left for a sweep
|
||||
ok 39 - G13: a revoke whose host remove fails still drops the record and key, and reports the line left for a sweep
|
||||
---
|
||||
duration_ms: 649.752917
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G22: enroll, check, grant, host.run, a commands change the next host.run uses, and a revoke that kills a run in flight
|
||||
ok 40 - G22: enroll, check, grant, host.run, a commands change the next host.run uses, and a revoke that kills a run in flight
|
||||
---
|
||||
duration_ms: 1161.391549
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: mos-1163: a grant whose agent became a creative role after the raise ends host-creative-role at step 1, spent, with nothing remote
|
||||
ok 41 - mos-1163: a grant whose agent became a creative role after the raise ends host-creative-role at step 1, spent, with nothing remote
|
||||
---
|
||||
duration_ms: 64.590353
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: sage-1908: once the agent of an applied grant is a creative role, host.run refuses host-creative-role, runs nothing remote and keeps the record
|
||||
ok 42 - sage-1908: once the agent of an applied grant is a creative role, host.run refuses host-creative-role, runs nothing remote and keeps the record
|
||||
---
|
||||
duration_ms: 494.590559
|
||||
type: 'test'
|
||||
...
|
||||
1..42
|
||||
# tests 42
|
||||
# suites 0
|
||||
# pass 42
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 21536.413692
|
||||
@@ -0,0 +1,28 @@
|
||||
TAP version 13
|
||||
# Subtest: Broker keeps the sandbox client import closure: only the listed imports, no lazy project import
|
||||
ok 1 - Broker keeps the sandbox client import closure: only the listed imports, no lazy project import
|
||||
---
|
||||
duration_ms: 1.878382
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: without a trusted project adapter all three async paths refuse project-not-configured
|
||||
ok 2 - without a trusted project adapter all three async paths refuse project-not-configured
|
||||
---
|
||||
duration_ms: 39.792991
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: real startBroker injects the project adapter for socket reads and bound-author record writes
|
||||
ok 3 - real startBroker injects the project adapter for socket reads and bound-author record writes
|
||||
---
|
||||
duration_ms: 197.452786
|
||||
type: 'test'
|
||||
...
|
||||
1..3
|
||||
# tests 3
|
||||
# suites 0
|
||||
# pass 3
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 346.195541
|
||||
@@ -0,0 +1,130 @@
|
||||
TAP version 13
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger
|
||||
ok 1 - REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger
|
||||
---
|
||||
duration_ms: 39.935415
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker
|
||||
ok 2 - REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker
|
||||
---
|
||||
duration_ms: 68.167379
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: a message to or from the assistant names its thread, or is refused
|
||||
ok 3 - REQ-MSG-1: a message to or from the assistant names its thread, or is refused
|
||||
---
|
||||
duration_ms: 33.042545
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work
|
||||
ok 4 - REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work
|
||||
---
|
||||
duration_ms: 589.697235
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance
|
||||
ok 5 - REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance
|
||||
---
|
||||
duration_ms: 25.439145
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder
|
||||
ok 6 - REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder
|
||||
---
|
||||
duration_ms: 32.810336
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it
|
||||
ok 7 - REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it
|
||||
---
|
||||
duration_ms: 30.930747
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder
|
||||
ok 8 - REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder
|
||||
---
|
||||
duration_ms: 33.583742
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder
|
||||
ok 9 - REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder
|
||||
---
|
||||
duration_ms: 29.506668
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1 Q169: a role.revoke the human approved ends every thread run of the assistant
|
||||
ok 10 - REQ-ROLE-2 REQ-THREAD-1 Q169: a role.revoke the human approved ends every thread run of the assistant
|
||||
---
|
||||
duration_ms: 27.727681
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: Q169 REQ-USER-2: assistant.stop ends the human's own assistant thread runs, and only the human's
|
||||
ok 11 - Q169 REQ-USER-2: assistant.stop ends the human's own assistant thread runs, and only the human's
|
||||
---
|
||||
duration_ms: 41.315113
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-USER-2: the human verbs refuse another owner's thread
|
||||
ok 12 - REQ-USER-2: the human verbs refuse another owner's thread
|
||||
---
|
||||
duration_ms: 28.275757
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one
|
||||
ok 13 - REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one
|
||||
---
|
||||
duration_ms: 23.795562
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ORG-2: projects and threads are named once, and the repo names a business project
|
||||
ok 14 - REQ-ORG-2: projects and threads are named once, and the repo names a business project
|
||||
---
|
||||
duration_ms: 24.710376
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing
|
||||
ok 15 - REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing
|
||||
---
|
||||
duration_ms: 85.400186
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: project.create refuses a repository name without its matching repo before any write
|
||||
ok 16 - project.create refuses a repository name without its matching repo before any write
|
||||
---
|
||||
duration_ms: 15.391876
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: project.create keeps unrelated names with and without a repository
|
||||
ok 17 - project.create keeps unrelated names with and without a repository
|
||||
---
|
||||
duration_ms: 10.08154
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
ok 18 - C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
---
|
||||
duration_ms: 46.325924
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
ok 19 - C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
---
|
||||
duration_ms: 20.515175
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
ok 20 - C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
---
|
||||
duration_ms: 9.391139
|
||||
type: 'test'
|
||||
...
|
||||
1..20
|
||||
# tests 20
|
||||
# suites 0
|
||||
# pass 20
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 1297.818732
|
||||
@@ -0,0 +1,148 @@
|
||||
TAP version 13
|
||||
# Subtest: R3: bindUser binds a granted user and refuses one with no live grant
|
||||
ok 1 - R3: bindUser binds a granted user and refuses one with no live grant
|
||||
---
|
||||
duration_ms: 13.944093
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user named like the business human, the tester or a principal word is refused, whatever the grants say
|
||||
ok 2 - R3: a user named like the business human, the tester or a principal word is refused, whatever the grants say
|
||||
---
|
||||
duration_ms: 9.742292
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: each collaborator verb is allowed to a granted user
|
||||
ok 3 - R3: each collaborator verb is allowed to a granted user
|
||||
---
|
||||
duration_ms: 18.679921
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: every verb off the collaborator list refuses a user access-refused before its own checks
|
||||
ok 4 - R3: every verb off the collaborator list refuses a user access-refused before its own checks
|
||||
---
|
||||
duration_ms: 99.486855
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: task, web and host verbs refuse a user access-refused
|
||||
ok 5 - R3: task, web and host verbs refuse a user access-refused
|
||||
---
|
||||
duration_ms: 24.025805
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: project.list shows granted projects only
|
||||
ok 6 - R3 leak: project.list shows granted projects only
|
||||
---
|
||||
duration_ms: 13.165462
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: thread.create needs the project and the thread instance granted, and an ungranted id reads as one that does not exist
|
||||
ok 7 - R3 leak: thread.create needs the project and the thread instance granted, and an ungranted id reads as one that does not exist
|
||||
---
|
||||
duration_ms: 15.661272
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: thread.list shows the user its own threads that are still granted, never others
|
||||
ok 8 - R3 leak: thread.list shows the user its own threads that are still granted, never others
|
||||
---
|
||||
duration_ms: 32.621553
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: names shows granted instances only
|
||||
ok 9 - R3 leak: names shows granted instances only
|
||||
---
|
||||
duration_ms: 14.594611
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: thread.send is from user:<id> and writes no human.input
|
||||
ok 10 - R3: thread.send is from user:<id> and writes no human.input
|
||||
---
|
||||
duration_ms: 12.108779
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a reply-chain message.send into another user thread is refused
|
||||
ok 11 - R3: a reply-chain message.send into another user thread is refused
|
||||
---
|
||||
duration_ms: 15.050058
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: the run reply to a user message reaches that user thread.messages, with no waiting and no notice
|
||||
ok 12 - R3: the run reply to a user message reaches that user thread.messages, with no waiting and no notice
|
||||
---
|
||||
duration_ms: 19.068793
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a reply to: user without a matching in_reply_to is refused user-reply-required
|
||||
ok 13 - R3: a reply to: user without a matching in_reply_to is refused user-reply-required
|
||||
---
|
||||
duration_ms: 26.350152
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a non-thread run, the human and the tester cannot send to: user
|
||||
ok 14 - R3: a non-thread run, the human and the tester cannot send to: user
|
||||
---
|
||||
duration_ms: 17.161103
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user thread run cannot message the owner, while its uncited gated raise reaches only the owner inbox, B9
|
||||
ok 15 - R3: a user thread run cannot message the owner, while its uncited gated raise reaches only the owner inbox, B9
|
||||
---
|
||||
duration_ms: 19.180463
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a removed or expired grant refuses the next request access-revoked, and the file is read per request
|
||||
ok 16 - R3: a removed or expired grant refuses the next request access-revoked, and the file is read per request
|
||||
---
|
||||
duration_ms: 16.523551
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user refusal is recorded as action.refused by user:<id>
|
||||
ok 17 - R3: a user refusal is recorded as action.refused by user:<id>
|
||||
---
|
||||
duration_ms: 13.680695
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a business with a role keyed user refuses invalid-business
|
||||
ok 18 - R3: a business with a role keyed user refuses invalid-business
|
||||
---
|
||||
duration_ms: 10.04229
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: name.set refuses the name user
|
||||
ok 19 - R3: name.set refuses the name user
|
||||
---
|
||||
duration_ms: 10.604386
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: while halted, a granted user's thread.send refuses processing-halted and thread.messages still answers
|
||||
ok 20 - R3 r4: while halted, a granted user's thread.send refuses processing-halted and thread.messages still answers
|
||||
---
|
||||
duration_ms: 14.542729
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: the chief's hire refuses an instance named user with the code it gives human and tester
|
||||
ok 21 - R3 r4: the chief's hire refuses an instance named user with the code it gives human and tester
|
||||
---
|
||||
duration_ms: 15.860218
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: a non-function access throws before the store is read
|
||||
ok 22 - R3 r4: a non-function access throws before the store is read
|
||||
---
|
||||
duration_ms: 0.137097
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
ok 23 - C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
---
|
||||
duration_ms: 16.969684
|
||||
type: 'test'
|
||||
...
|
||||
1..23
|
||||
# tests 23
|
||||
# suites 0
|
||||
# pass 23
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 526.916212
|
||||
@@ -0,0 +1,229 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-04: launcher workspace clones code but never the library
|
||||
ok 1 - C2-04: launcher workspace clones code but never the library
|
||||
---
|
||||
duration_ms: 1386.185829
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest
|
||||
ok 2 - bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest
|
||||
---
|
||||
duration_ms: 1313.619586
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r199f875ccb7f","instance":"chief","turn":"37b28923-c276-4eeb-82e7-2f04edfc63b0","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"raee3d01ce9da","instance":"coder","turn":"e790f5a0-c0ac-4401-9351-30233ea05022","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code
|
||||
ok 3 - the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code
|
||||
---
|
||||
duration_ms: 733.864246
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd8d7c7627ba8","instance":"chief","turn":"a2a42660-2726-4c63-99cb-bd35899ba5fa","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra8bf65ecb11d","instance":"pm","turn":"b2e16af9-d95b-4b57-801d-1560ad84966f","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd8d7c7627ba8","instance":"chief","turn":"288e9f5b-eb1f-4a66-a216-0e2e6e8a21c8","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra8bf65ecb11d","instance":"pm","turn":"47125f10-7905-43f3-9d19-50b94f2c2025","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra8bf65ecb11d","instance":"pm","turn":"96a194ac-2588-4135-ab20-7a4d85208a2c","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd8d7c7627ba8","instance":"chief","turn":"b836f76e-02f0-44e2-902f-b820e5601ec1","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra8bf65ecb11d","instance":"pm","turn":"469bfa42-84ac-439a-8f22-a27ff0cd2b0f","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd8d7c7627ba8","instance":"chief","turn":"79a1518c-ca9f-494e-87aa-df1ea958fd71","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold
|
||||
ok 4 - a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold
|
||||
---
|
||||
duration_ms: 1196.320237
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged
|
||||
ok 5 - each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged
|
||||
---
|
||||
duration_ms: 4059.673988
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none
|
||||
ok 6 - a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none
|
||||
---
|
||||
duration_ms: 610.995934
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 7 - 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
|
||||
---
|
||||
duration_ms: 364.057414
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r6bea6ac4c470","instance":"coder","turn":"d55a4936-6ea7-4bd6-986c-6e8cca2f0052","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: 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
|
||||
ok 8 - 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
|
||||
---
|
||||
duration_ms: 686.195959
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder
|
||||
ok 9 - a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder
|
||||
---
|
||||
duration_ms: 633.426446
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: after a restart, the new host's first tick starts a holder whose decision is still held
|
||||
ok 10 - after a restart, the new host's first tick starts a holder whose decision is still held
|
||||
---
|
||||
duration_ms: 839.982216
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 11 - 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
|
||||
---
|
||||
duration_ms: 622.725531
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left
|
||||
ok 12 - a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left
|
||||
---
|
||||
duration_ms: 257.600871
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner that stops at once ends its launch with the runner's reason
|
||||
ok 13 - a runner that stops at once ends its launch with the runner's reason
|
||||
---
|
||||
duration_ms: 336.235131
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a Claude Code launch with no session credential refuses before it starts
|
||||
ok 14 - a Claude Code launch with no session credential refuses before it starts
|
||||
---
|
||||
duration_ms: 185.109906
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables
|
||||
ok 15 - a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables
|
||||
---
|
||||
duration_ms: 376.058384
|
||||
type: 'test'
|
||||
...
|
||||
# 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":[]}
|
||||
# Subtest: row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason
|
||||
ok 16 - row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason
|
||||
---
|
||||
duration_ms: 375.264214
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner killed from the host ends its launch as killed, not failed
|
||||
ok 17 - a runner killed from the host ends its launch as killed, not failed
|
||||
---
|
||||
duration_ms: 378.898804
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback
|
||||
ok 18 - a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback
|
||||
---
|
||||
duration_ms: 189.672473
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 19 - 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
|
||||
---
|
||||
duration_ms: 198.478931
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason
|
||||
ok 20 - row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason
|
||||
---
|
||||
duration_ms: 273.044614
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts
|
||||
ok 21 - row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts
|
||||
---
|
||||
duration_ms: 197.74503
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r8a3b586b8f2f","instance":"chief","turn":"4b701d58-8cbe-4466-a7de-18c2246211c5","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r04010eaba86b","instance":"coder","turn":"5bddbfc5-6a5a-4eab-b5ca-bf4fa2040769","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold
|
||||
ok 22 - a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold
|
||||
---
|
||||
duration_ms: 1472.6753
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 23 - 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
|
||||
---
|
||||
duration_ms: 1050.128747
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 24 - 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
|
||||
---
|
||||
duration_ms: 3972.696162
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was
|
||||
ok 25 - bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was
|
||||
---
|
||||
duration_ms: 232.233441
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned
|
||||
ok 26 - bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned
|
||||
---
|
||||
duration_ms: 192.380723
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch starts no thread tick; the same host with launches runs it
|
||||
ok 27 - bus start --no-launch starts no thread tick; the same host with launches runs it
|
||||
---
|
||||
duration_ms: 1168.043143
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a malformed sessions.json refuses the host start with exit 3 and stays as it was
|
||||
ok 28 - a malformed sessions.json refuses the host start with exit 3 and stays as it was
|
||||
---
|
||||
duration_ms: 173.460107
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an over-long launch request is refused at once, not at the 10 s idle timeout
|
||||
ok 29 - an over-long launch request is refused at once, not at the 10 s idle timeout
|
||||
---
|
||||
duration_ms: 181.721277
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a launch client that never closes its side doesn't hold the host's close
|
||||
ok 30 - a launch client that never closes its side doesn't hold the host's close
|
||||
---
|
||||
duration_ms: 184.217213
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner that ignores SIGTERM is killed when the host closes
|
||||
ok 31 - a runner that ignores SIGTERM is killed when the host closes
|
||||
---
|
||||
duration_ms: 1355.394246
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: kill switch refuses chief and hire before launch work and a clear permits a later request
|
||||
ok 32 - kill switch refuses chief and hire before launch work and a clear permits a later request
|
||||
---
|
||||
duration_ms: 319.95812
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle
|
||||
ok 33 - kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle
|
||||
---
|
||||
duration_ms: 327.164689
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a launch waiting across halt and resume cannot use its stale admission
|
||||
ok 34 - a launch waiting across halt and resume cannot use its stale admission
|
||||
---
|
||||
duration_ms: 194.717407
|
||||
type: 'test'
|
||||
...
|
||||
1..34
|
||||
# tests 34
|
||||
# suites 0
|
||||
# pass 34
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 26156.328784
|
||||
@@ -0,0 +1,113 @@
|
||||
TAP version 13
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rc568ee5fade9","instance":"assistant","turn":"8a8b601e-f850-41ae-8370-4a4948e785e0","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r051f145959ab","instance":"assistant","turn":"19e244d5-1e6e-4797-a655-41f6380c26dd","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rec6f0012e42e","instance":"assistant","turn":"b77db7a5-f03b-480a-8c9e-258b2baed6a2","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rcbca03b4294d","instance":"assistant","turn":"0ea60c25-f171-47f8-b71f-2d3cad84b496","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it
|
||||
ok 1 - REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it
|
||||
---
|
||||
duration_ms: 5892.762685
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r0404b31e175a","instance":"assistant","turn":"d0ac6a94-d898-4f7d-82be-4fcf63c992ac","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rc88d83c6460c","instance":"assistant","turn":"ead59d62-6b55-45cd-955d-caf53ee8e25f","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't
|
||||
ok 2 - REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't
|
||||
---
|
||||
duration_ms: 1692.527776
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra1708b66d4b7","instance":"assistant","turn":"e27e2188-87f0-4971-967d-93a96eeedff4","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it
|
||||
ok 3 - REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it
|
||||
---
|
||||
duration_ms: 4388.820082
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rfbd6a0a0afa4","instance":"assistant","turn":"ddec8f31-aec7-4eb4-90d8-bbd4e7ee0394","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rfbd6a0a0afa4","instance":"assistant","turn":"2f664ba9-6f69-4eab-86a2-62da25b64273","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it
|
||||
ok 4 - REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it
|
||||
---
|
||||
duration_ms: 2886.685515
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session
|
||||
ok 5 - REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session
|
||||
---
|
||||
duration_ms: 82.134614
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r6f1704540344","instance":"assistant","turn":"5132642f-f52a-436c-8648-6b11d6a0d812","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-LAUNCH-1 a thread run's session file has no landing, even when landHolders names its instance
|
||||
ok 6 - REQ-LAUNCH-1 a thread run's session file has no landing, even when landHolders names its instance
|
||||
---
|
||||
duration_ms: 371.847425
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message
|
||||
ok 7 - REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message
|
||||
---
|
||||
duration_ms: 223.179675
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing
|
||||
ok 8 - REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing
|
||||
---
|
||||
duration_ms: 222.380867
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread
|
||||
ok 9 - REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread
|
||||
---
|
||||
duration_ms: 80.396078
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: fromSession refuses a creative instance outside a thread without a sandbox
|
||||
ok 10 - C2-09a: fromSession refuses a creative instance outside a thread without a sandbox
|
||||
---
|
||||
duration_ms: 72.675249
|
||||
type: 'test'
|
||||
...
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mayLaunch","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":0}
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mayLaunch","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":0}
|
||||
# Subtest: REQ-LIMIT-3 REQ-LIMIT-4 a thread start whose instance is at its token limit is refused, logged once with the limit and the count
|
||||
ok 11 - REQ-LIMIT-3 REQ-LIMIT-4 a thread start whose instance is at its token limit is refused, logged once with the limit and the count
|
||||
---
|
||||
duration_ms: 194.687144
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r45d9f1feb664","instance":"assistant","turn":"94f62246-a46b-4bff-9b85-43cad6f2f9da","source":"@none","code":"baseline-unknown"}
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mustStop","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":1}
|
||||
# Subtest: REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn: the reply lands, and the end record names the limit
|
||||
ok 12 - REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn: the reply lands, and the end record names the limit
|
||||
---
|
||||
duration_ms: 363.771015
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r25fd94375762","instance":"bean","turn":"8a8a214f-68b7-4940-9b10-7764e16b4d0d","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r6d58cdce8c9f","instance":"chet","turn":"a12dee45-9efc-4542-9b7b-982f60843525","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r25fd94375762","instance":"bean","turn":"5b798386-3f51-4de8-82db-a66ac44276c6","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
ok 13 - C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
---
|
||||
duration_ms: 749.150495
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r6b2fca8831e0","instance":"bean","turn":"936ceedd-82ae-41ae-81f6-06b862035858","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r579a6302e6d2","instance":"bean","turn":"73cb49bf-b4ea-4781-8a7f-4821a1e59286","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: C2-09a: terminating one creative thread does not signal an unselected peer of the same instance
|
||||
ok 14 - C2-09a: terminating one creative thread does not signal an unselected peer of the same instance
|
||||
---
|
||||
duration_ms: 639.42083
|
||||
type: 'test'
|
||||
...
|
||||
1..14
|
||||
# tests 14
|
||||
# suites 0
|
||||
# pass 14
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 17983.289749
|
||||
@@ -0,0 +1,94 @@
|
||||
TAP version 13
|
||||
# Subtest: chat browser: list/create named projects and threads, hostile labels inert and no implicit writes
|
||||
ok 1 - chat browser: list/create named projects and threads, hostile labels inert and no implicit writes
|
||||
---
|
||||
duration_ms: 691.67169
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: thread drafts, receipts and cursor history stay isolated; refresh never writes
|
||||
ok 2 - chat browser: thread drafts, receipts and cursor history stay isolated; refresh never writes
|
||||
---
|
||||
duration_ms: 480.248405
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: uncertain writes retain draft, ownership refusal clears it, read-only cannot send
|
||||
ok 3 - chat browser: uncertain writes retain draft, ownership refusal clears it, read-only cannot send
|
||||
---
|
||||
duration_ms: 597.238297
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a late read from A cannot paint B; sign-out clears private state and stops reads
|
||||
ok 4 - chat browser: a late read from A cannot paint B; sign-out clears private state and stops reads
|
||||
---
|
||||
duration_ms: 818.266171
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: page forward and deduplicate replies; pending and byte-limit submissions do not duplicate
|
||||
ok 5 - chat browser: page forward and deduplicate replies; pending and byte-limit submissions do not duplicate
|
||||
---
|
||||
duration_ms: 502.038978
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: scrolled history stays put, New messages and an own send return to the tail
|
||||
ok 6 - chat browser: scrolled history stays put, New messages and an own send return to the tail
|
||||
---
|
||||
duration_ms: 546.644083
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: automatic polling follows a reply without a POST or a lost draft
|
||||
ok 7 - chat browser: automatic polling follows a reply without a POST or a lost draft
|
||||
---
|
||||
duration_ms: 10578.074278
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: display stays bounded while every forward page remains reachable
|
||||
ok 8 - chat browser: display stays bounded while every forward page remains reachable
|
||||
---
|
||||
duration_ms: 581.659608
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a confirmed visible message replaces its pending receipt; malformed receipts stay unknown
|
||||
ok 9 - chat browser: a confirmed visible message replaces its pending receipt; malformed receipts stay unknown
|
||||
---
|
||||
duration_ms: 444.584502
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a refusal elsewhere forgets private chat drafts
|
||||
ok 10 - chat browser: a refusal elsewhere forgets private chat drafts
|
||||
---
|
||||
duration_ms: 583.995207
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a late project creation receipt cannot navigate away from another thread
|
||||
ok 11 - chat browser: a late project creation receipt cannot navigate away from another thread
|
||||
---
|
||||
duration_ms: 611.03461
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
ok 12 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 560.328725
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
ok 13 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 648.448462
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread
|
||||
ok 14 - C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread
|
||||
---
|
||||
duration_ms: 425.089318
|
||||
type: 'test'
|
||||
...
|
||||
1..14
|
||||
# tests 14
|
||||
# suites 0
|
||||
# pass 14
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 18170.580111
|
||||
@@ -0,0 +1,34 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 16.444565
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata uses the private tester listener own bus and no human transport
|
||||
ok 2 - C2-09a metadata uses the private tester listener own bus and no human transport
|
||||
---
|
||||
duration_ms: 2.808985
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields
|
||||
ok 3 - C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields
|
||||
---
|
||||
duration_ms: 3.286588
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity
|
||||
ok 4 - C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity
|
||||
---
|
||||
duration_ms: 2.026814
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
# tests 4
|
||||
# suites 0
|
||||
# pass 4
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 123.938342
|
||||
@@ -0,0 +1,160 @@
|
||||
TAP version 13
|
||||
# Subtest: chat reads map only fixed verbs, strict forward paging and pure GET
|
||||
ok 1 - chat reads map only fixed verbs, strict forward paging and pure GET
|
||||
---
|
||||
duration_ms: 34.208753
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat refuses malformed and repeated query/id values before transport
|
||||
ok 2 - chat refuses malformed and repeated query/id values before transport
|
||||
---
|
||||
duration_ms: 4.797632
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: one verified write, fixed identity/class and private log
|
||||
ok 3 - chat project.create: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 2.811902
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: each existing Console write fence makes zero bus calls
|
||||
ok 4 - chat project.create: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 6.841947
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 5 - chat project.create: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 3.588766
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: one verified write, fixed identity/class and private log
|
||||
ok 6 - chat thread.create: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 1.139425
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: each existing Console write fence makes zero bus calls
|
||||
ok 7 - chat thread.create: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 5.609374
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 8 - chat thread.create: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 3.766206
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: one verified write, fixed identity/class and private log
|
||||
ok 9 - chat thread.send: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 1.047356
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: each existing Console write fence makes zero bus calls
|
||||
ok 10 - chat thread.send: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 4.912497
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 11 - chat thread.send: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 2.781203
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: one verified write, fixed identity/class and private log
|
||||
ok 12 - chat thread.open: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 0.929315
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: each existing Console write fence makes zero bus calls
|
||||
ok 13 - chat thread.open: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 5.993363
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 14 - chat thread.open: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 4.414109
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat createThread receipt requires an instance even when its id is valid
|
||||
ok 15 - chat createThread receipt requires an instance even when its id is valid
|
||||
---
|
||||
duration_ms: 1.984854
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat write receipts expose only the fields belonging to their operation
|
||||
ok 16 - chat write receipts expose only the fields belonging to their operation
|
||||
---
|
||||
duration_ms: 3.123412
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat validates names, body, project and strict empty open payload
|
||||
ok 17 - chat validates names, body, project and strict empty open payload
|
||||
---
|
||||
duration_ms: 3.374476
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat read failures redact ownership and refuse invalid transport arrays
|
||||
ok 18 - chat read failures redact ownership and refuse invalid transport arrays
|
||||
---
|
||||
duration_ms: 3.309239
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-USER-2 real broker: owned catalog, create/name/filter, isolated history and 403/404 without mutations
|
||||
ok 19 - REQ-USER-2 real broker: owned catalog, create/name/filter, isolated history and 403/404 without mutations
|
||||
---
|
||||
duration_ms: 82.677307
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat repeats every POST boundary even when called behind an admitted request
|
||||
ok 20 - chat repeats every POST boundary even when called behind an admitted request
|
||||
---
|
||||
duration_ms: 0.912069
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: configured Console process injects chat through its existing human transport
|
||||
ok 21 - configured Console process injects chat through its existing human transport
|
||||
---
|
||||
duration_ms: 135.46624
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat assets, GET purity, method and unknown-route refusals are explicit
|
||||
ok 22 - chat assets, GET purity, method and unknown-route refusals are explicit
|
||||
---
|
||||
duration_ms: 11.555701
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the chat seam names the transport it is given: the human one and the tester one both pass, anything else is a TypeError
|
||||
ok 23 - the chat seam names the transport it is given: the human one and the tester one both pass, anything else is a TypeError
|
||||
---
|
||||
duration_ms: 0.45427
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a createThread forwards an explicit instance through the existing channel
|
||||
ok 24 - C2-09a createThread forwards an explicit instance through the existing channel
|
||||
---
|
||||
duration_ms: 3.503543
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
ok 25 - C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
---
|
||||
duration_ms: 3.129652
|
||||
type: 'test'
|
||||
...
|
||||
1..25
|
||||
# tests 25
|
||||
# suites 0
|
||||
# pass 25
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 442.329912
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"counts": {
|
||||
"tests": 2509,
|
||||
"pass": 2506,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 2
|
||||
},
|
||||
"skips": [
|
||||
"ok 193 - X-G3: on scratch 1.27.1, a grant makes the user, mints, forks, checks reach, writes the file, and revoke deletes the token # SKIP no Docker or no local gitea/gitea:1.27.1; this test never pulls",
|
||||
"ok 107 - rebuilding from the source gives the same bytes (needs the pinned esbuild; MOSAIC_REQUIRE_EDITOR_BUILD=1 makes its absence a failure) # SKIP esbuild 0.28.1 is installed at /mnt/storage/src/mosaic-stack/node_modules/esbuild; the editor rebuild needs exactly 0.28.2 (npm ci --ignore-scripts in packages/webui) (set MOSAIC_REQUIRE_EDITOR_BUILD=1 to fail instead of skip)"
|
||||
],
|
||||
"stop": "suite-harness",
|
||||
"unrun": [
|
||||
"shells",
|
||||
"24 mutants",
|
||||
"final reader audit"
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,945 @@
|
||||
TAP version 13
|
||||
# Subtest: sessionModel: the route is the instance's own vars, and a missing one refuses no-route by name
|
||||
ok 1 - sessionModel: the route is the instance's own vars, and a missing one refuses no-route by name
|
||||
---
|
||||
duration_ms: 34.856426
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory
|
||||
ok 2 - a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory
|
||||
---
|
||||
duration_ms: 9.851494
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools
|
||||
ok 3 - a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools
|
||||
---
|
||||
duration_ms: 5.120431
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a chief-of-staff bundle lists end_run, change_organization and set_name as typed and nothing untyped, for either harness
|
||||
ok 4 - a chief-of-staff bundle lists end_run, change_organization and set_name as typed and nothing untyped, for either harness
|
||||
---
|
||||
duration_ms: 8.232092
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the stop line names end_run for a role.end holder, and every other role keeps today's text
|
||||
ok 5 - the stop line names end_run for a role.end holder, and every other role keeps today's text
|
||||
---
|
||||
duration_ms: 13.301817
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a claude-code bundle adds the wrapped gate hook and the MCP config
|
||||
ok 6 - a claude-code bundle adds the wrapped gate hook and the MCP config
|
||||
---
|
||||
duration_ms: 8.191276
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt's built-in tools line is the harness's own names, as the manifest lists them
|
||||
ok 7 - the prompt's built-in tools line is the harness's own names, as the manifest lists them
|
||||
---
|
||||
duration_ms: 20.825509
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt names the project clones in the workspace, and none when there are none
|
||||
ok 8 - the prompt names the project clones in the workspace, and none when there are none
|
||||
---
|
||||
duration_ms: 12.281607
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review
|
||||
ok 9 - the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review
|
||||
---
|
||||
duration_ms: 14.129552
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt explains landing to a role with land_work, and to no other
|
||||
ok 10 - the prompt explains landing to a role with land_work, and to no other
|
||||
---
|
||||
duration_ms: 7.467651
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt tells the pm to ask the chief of staff for sessions, and no other role
|
||||
ok 11 - the prompt tells the pm to ask the chief of staff for sessions, and no other role
|
||||
---
|
||||
duration_ms: 14.371613
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a bundle is written once: an existing file refuses
|
||||
ok 12 - a bundle is written once: an existing file refuses
|
||||
---
|
||||
duration_ms: 3.698221
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a path with a single quote can't go into the hook command
|
||||
ok 13 - a path with a single quote can't go into the hook command
|
||||
---
|
||||
duration_ms: 3.75786
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
ok 14 - web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
---
|
||||
duration_ms: 5.149102
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no web grant on pi: no web tool in the bundle, and the gate blocks a web call
|
||||
ok 15 - no web grant on pi: no web tool in the bundle, and the gate blocks a web call
|
||||
---
|
||||
duration_ms: 6.16053
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
ok 16 - web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
---
|
||||
duration_ms: 4.111996
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call
|
||||
ok 17 - no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call
|
||||
---
|
||||
duration_ms: 4.051441
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a granted session's gate lets the typed web tools through and still blocks the built-ins
|
||||
ok 18 - a granted session's gate lets the typed web tools through and still blocks the built-ins
|
||||
---
|
||||
duration_ms: 3.69592
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
ok 19 - search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
---
|
||||
duration_ms: 10.440022
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
ok 20 - search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
---
|
||||
duration_ms: 11.39935
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted
|
||||
ok 21 - search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted
|
||||
---
|
||||
duration_ms: 12.01268
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source harness-builtin is refused for a granted pi role, which has no built-in web tool
|
||||
ok 22 - search-source harness-builtin is refused for a granted pi role, which has no built-in web tool
|
||||
---
|
||||
duration_ms: 3.963537
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: allow exits 0, a deny exits 2 with the reason on stderr
|
||||
ok 23 - allow exits 0, a deny exits 2 with the reason on stderr
|
||||
---
|
||||
duration_ms: 198.492155
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or wrong policy, or a bad event, exits 2
|
||||
ok 24 - a missing or wrong policy, or a bad event, exits 2
|
||||
---
|
||||
duration_ms: 112.79382
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bundle's wrapped command: a missing gate or node still blocks
|
||||
ok 25 - the bundle's wrapped command: a missing gate or node still blocks
|
||||
---
|
||||
duration_ms: 1094.954866
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 26 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 963.051269
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 27 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 494.23923
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 28 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 903.815433
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 29 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.775681
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 30 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 17.582625
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 31 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 6.164679
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
not ok 32 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 872.829879
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
'MARKER-USER',
|
||||
'MARKER-PARENT',
|
||||
'MARKER-WS',
|
||||
- 'MARKER-MEMORY'
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
3: 'MARKER-MEMORY'
|
||||
actual:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs:298:10)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 33 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.368667
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 34 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1785.018464
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 35 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 853.709418
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M2: the gate refuses write, edit and bash to every creative role on pi and claude-code
|
||||
ok 36 - M2: the gate refuses write, edit and bash to every creative role on pi and claude-code
|
||||
---
|
||||
duration_ms: 69.878437
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M6: no creative session gets raise_decision; the assistant and the chief of staff keep it
|
||||
ok 37 - M6: no creative session gets raise_decision; the assistant and the chief of staff keep it
|
||||
---
|
||||
duration_ms: 24.848412
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web: research and companion get the broker's typed web tools, and a harness-builtin source refuses web-source-not-allowed
|
||||
ok 38 - web: research and companion get the broker's typed web tools, and a harness-builtin source refuses web-source-not-allowed
|
||||
---
|
||||
duration_ms: 30.528945
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: persona: the block sits between the contract and \#\# This session, fenced, with the name and digest
|
||||
ok 39 - persona: the block sits between the contract and \#\# This session, fenced, with the name and digest
|
||||
---
|
||||
duration_ms: 9.664778
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: persona: each unsafe or unpinned file refuses before the bundle directory is made
|
||||
ok 40 - persona: each unsafe or unpinned file refuses before the bundle directory is made
|
||||
---
|
||||
duration_ms: 28.523424
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: adapters pass the prompt file's absolute path; the persona and the prompt text never sit in argv
|
||||
ok 41 - adapters pass the prompt file's absolute path; the persona and the prompt text never sit in argv
|
||||
---
|
||||
duration_ms: 38.381105
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the pi adapter refuses a missing, unreadable or directory prompt file before pi starts
|
||||
ok 42 - the pi adapter refuses a missing, unreadable or directory prompt file before pi starts
|
||||
---
|
||||
duration_ms: 12.120999
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: policy tools and typed tools pass, anything else is blocked
|
||||
ok 43 - pi: policy tools and typed tools pass, anything else is blocked
|
||||
---
|
||||
duration_ms: 4.788064
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: builtins map from pi names, typed tools need the mcp prefix
|
||||
ok 44 - claude: builtins map from pi names, typed tools need the mcp prefix
|
||||
---
|
||||
duration_ms: 1.088307
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: file tool paths must resolve inside the workspace
|
||||
ok 45 - file tool paths must resolve inside the workspace
|
||||
---
|
||||
duration_ms: 2.117046
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi's own path normalisation can't be used to step out
|
||||
ok 46 - pi's own path normalisation can't be used to step out
|
||||
---
|
||||
duration_ms: 3.792384
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a symlink inside the workspace that points out is outside
|
||||
ok 47 - a symlink inside the workspace that points out is outside
|
||||
---
|
||||
duration_ms: 2.415204
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a dangling symlink is refused at any depth, in both harnesses
|
||||
ok 48 - a dangling symlink is refused at any depth, in both harnesses
|
||||
---
|
||||
duration_ms: 5.167029
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: read is checked under every spelling pi's read would open, in both harnesses
|
||||
ok 49 - read is checked under every spelling pi's read would open, in both harnesses
|
||||
---
|
||||
duration_ms: 30.76287
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: other spellings cover directories, dangling links and pi's cwd
|
||||
ok 50 - other spellings cover directories, dangling links and pi's cwd
|
||||
---
|
||||
duration_ms: 2.671956
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a relative path climbs from the workspace's real path, in both harnesses
|
||||
ok 51 - a relative path climbs from the workspace's real path, in both harnesses
|
||||
---
|
||||
duration_ms: 10.167886
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude path fields per tool
|
||||
ok 52 - claude path fields per tool
|
||||
---
|
||||
duration_ms: 1.56407
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: glob patterns stay inside the workspace
|
||||
ok 53 - glob patterns stay inside the workspace
|
||||
---
|
||||
duration_ms: 1.269903
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a path that can't be checked is blocked
|
||||
ok 54 - a path that can't be checked is blocked
|
||||
---
|
||||
duration_ms: 0.552002
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX
|
||||
ok 55 - fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX
|
||||
---
|
||||
duration_ms: 350.146065
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: fetch_review's have orders the working refs newest first within each clone, one clone after another
|
||||
ok 56 - fetch_review's have orders the working refs newest first within each clone, one clone after another
|
||||
---
|
||||
duration_ms: 151.918127
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period
|
||||
ok 57 - a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period
|
||||
---
|
||||
duration_ms: 1808.893824
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too
|
||||
ok 58 - once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too
|
||||
---
|
||||
duration_ms: 302.665475
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: land_work sends one land line and resolves the host's started answer
|
||||
ok 59 - land_work sends one land line and resolves the host's started answer
|
||||
---
|
||||
duration_ms: 3.310262
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: initialize, ping and tools/list
|
||||
ok 60 - initialize, ping and tools/list
|
||||
---
|
||||
duration_ms: 71.924925
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: tools/call goes through the tool socket; a refusal is an isError result
|
||||
ok 61 - tools/call goes through the tool socket; a refusal is an isError result
|
||||
---
|
||||
duration_ms: 53.929883
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: replies are compact JSON; over the cap a tool error names the size and the cap
|
||||
ok 62 - replies are compact JSON; over the cap a tool error names the size and the cap
|
||||
---
|
||||
duration_ms: 62.845386
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: unknown tools and methods are JSON-RPC errors and never reach the socket
|
||||
ok 63 - unknown tools and methods are JSON-RPC errors and never reach the socket
|
||||
---
|
||||
duration_ms: 47.664888
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing argument is a usage error
|
||||
ok 64 - a missing argument is a usage error
|
||||
---
|
||||
duration_ms: 33.983265
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: typed tools reach the socket, the gate blocks, agent_end writes the marker
|
||||
ok 65 - pi: typed tools reach the socket, the gate blocks, agent_end writes the marker
|
||||
---
|
||||
duration_ms: 623.733255
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks
|
||||
ok 66 - pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks
|
||||
---
|
||||
duration_ms: 437.262054
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a write through a dangling symlink is blocked, and nothing appears outside
|
||||
ok 67 - pi: a write through a dangling symlink is blocked, and nothing appears outside
|
||||
---
|
||||
duration_ms: 441.96058
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a read is refused when pi would open another spelling outside
|
||||
ok 68 - pi: a read is refused when pi would open another spelling outside
|
||||
---
|
||||
duration_ms: 442.313486
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a relative path climbs from the real path of a workspace behind a symlink
|
||||
ok 69 - pi: a relative path climbs from the real path of a workspace behind a symlink
|
||||
---
|
||||
duration_ms: 467.731209
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a relative path climbs from the real path of a dataRoot behind a symlink
|
||||
ok 70 - pi: a relative path climbs from the real path of a dataRoot behind a symlink
|
||||
---
|
||||
duration_ms: 434.995228
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a missing extension refuses before any model call
|
||||
ok 71 - pi: a missing extension refuses before any model call
|
||||
---
|
||||
duration_ms: 6.502861
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: an extension without its configuration fails pi's start
|
||||
ok 72 - pi: an extension without its configuration fails pi's start
|
||||
---
|
||||
duration_ms: 380.396774
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 73 - pi: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1358.948547
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 74 - pi: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 707.366425
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: raise_decision offers domain as technical or delivery only, optional, and says where a raise goes
|
||||
ok 75 - raise_decision offers domain as technical or delivery only, optional, and says where a raise goes
|
||||
---
|
||||
duration_ms: 27.051506
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: raise_decision forwards domain to decision.raise, and a call without it sends none
|
||||
ok 76 - raise_decision forwards domain to decision.raise, and a call without it sends none
|
||||
---
|
||||
duration_ms: 90.915335
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: founderCheck: founder variables, then a needed service without a usable token
|
||||
ok 77 - founderCheck: founder variables, then a needed service without a usable token
|
||||
---
|
||||
duration_ms: 2.609338
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest names the sender, class, reply and decision
|
||||
ok 78 - turnRequest names the sender, class, reply and decision
|
||||
---
|
||||
duration_ms: 0.351146
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest says a tester's message is a test and never Jason's instruction
|
||||
ok 79 - turnRequest says a tester's message is a test and never Jason's instruction
|
||||
---
|
||||
duration_ms: 0.451421
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest says a user's message is a granted user's and never the owner's instruction
|
||||
ok 80 - turnRequest says a user's message is a granted user's and never the owner's instruction
|
||||
---
|
||||
duration_ms: 0.338738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest shows the message's own sent time, a day old as well as new
|
||||
ok 81 - turnRequest shows the message's own sent time, a day old as well as new
|
||||
---
|
||||
duration_ms: 0.838097
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: stateBlock names the launch state with its time and event, and the open tasks with the cap
|
||||
ok 82 - stateBlock names the launch state with its time and event, and the open tasks with the cap
|
||||
---
|
||||
duration_ms: 0.438412
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0
|
||||
ok 83 - a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0
|
||||
---
|
||||
duration_ms: 274.936534
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: launches revoked and then restored: the turn's block reads allowed and gives the restore time
|
||||
ok 84 - launches revoked and then restored: the turn's block reads allowed and gives the restore time
|
||||
---
|
||||
duration_ms: 231.401784
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a task closed on the tracker is missing from the next turn's open list
|
||||
ok 85 - a task closed on the tracker is missing from the next turn's open list
|
||||
---
|
||||
duration_ms: 225.343214
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a message read a day after it was sent shows the time it was sent
|
||||
ok 86 - a message read a day after it was sent shows the time it was sent
|
||||
---
|
||||
duration_ms: 114.024862
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a decision the human resolves becomes a turn citing the decision and the answer
|
||||
ok 87 - a decision the human resolves becomes a turn citing the decision and the answer
|
||||
---
|
||||
duration_ms: 165.1602
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a failed state read fails the turn: no adapter runs, the sender hears why, the message is read
|
||||
ok 88 - a failed state read fails the turn: no adapter runs, the sender hears why, the message is read
|
||||
---
|
||||
duration_ms: 87.646023
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a SIGTERM before the claim stops the runner with exit 0 and no claim
|
||||
ok 89 - a SIGTERM before the claim stops the runner with exit 0 and no claim
|
||||
---
|
||||
duration_ms: 73.002788
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: typed tools carry the runner's capability; launch goes to the host's launch socket
|
||||
ok 90 - typed tools carry the runner's capability; launch goes to the host's launch socket
|
||||
---
|
||||
duration_ms: 329.934911
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: end_run, organization_revision and change_organization reach the broker with the tool's arguments, and refusals keep their codes
|
||||
ok 91 - end_run, organization_revision and change_organization reach the broker with the tool's arguments, and refusals keep their codes
|
||||
---
|
||||
duration_ms: 394.890047
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: set_name reaches the broker's name.set with the tool's arguments, and refusals keep their codes
|
||||
ok 92 - set_name reaches the broker's name.set with the tool's arguments, and refusals keep their codes
|
||||
---
|
||||
duration_ms: 172.910326
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a RESULT gets no automatic reply; failed turns reply with the reason
|
||||
ok 93 - a RESULT gets no automatic reply; failed turns reply with the reason
|
||||
---
|
||||
duration_ms: 1262.379947
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bus's launch notice is one turn with no reply, and is not taken again
|
||||
ok 94 - the bus's launch notice is one turn with no reply, and is not taken again
|
||||
---
|
||||
duration_ms: 272.213669
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: SIGTERM during a turn kills the turn's process group and still exits 0
|
||||
ok 95 - SIGTERM during a turn kills the turn's process group and still exits 0
|
||||
---
|
||||
duration_ms: 119.660067
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: founder credentials stop before the claim (20)
|
||||
ok 96 - founder credentials stop before the claim (20)
|
||||
---
|
||||
duration_ms: 151.103872
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a refused claim exits 21; an ended run's capability exits 22
|
||||
ok 97 - a refused claim exits 21; an ended run's capability exits 22
|
||||
---
|
||||
duration_ms: 161.135577
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the launch ending under a running session exits 22
|
||||
ok 98 - the launch ending under a running session exits 22
|
||||
---
|
||||
duration_ms: 133.354952
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a broker that stays unreachable exits 23 after brokerRetries polls
|
||||
ok 99 - a broker that stays unreachable exits 23 after brokerRetries polls
|
||||
---
|
||||
duration_ms: 228.779063
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a broker that is down at the claim exits 23, not 21
|
||||
ok 100 - a broker that is down at the claim exits 23, not 21
|
||||
---
|
||||
duration_ms: 90.478293
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no capability, or a malformed one, on stdin exits 2
|
||||
ok 101 - no capability, or a malformed one, on stdin exits 2
|
||||
---
|
||||
duration_ms: 198.639044
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or malformed policy exits 2 before the claim
|
||||
ok 102 - a missing or malformed policy exits 2 before the claim
|
||||
---
|
||||
duration_ms: 117.131672
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LIMIT-4 runner brackets its actual harness turn before the reply and read receipt
|
||||
ok 103 - REQ-LIMIT-4 runner brackets its actual harness turn before the reply and read receipt
|
||||
---
|
||||
duration_ms: 166.804096
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LIMIT-4 a runner at its limit stops at the end of its turn: RESULT and read first, then exit 22 and a limit-check revoke
|
||||
ok 104 - REQ-LIMIT-4 a runner at its limit stops at the end of its turn: RESULT and read first, then exit 22 and a limit-check revoke
|
||||
---
|
||||
duration_ms: 174.919803
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: landingRequest is the fixed template, with the decision and task ref and nothing else
|
||||
ok 105 - landingRequest is the fixed template, with the decision and task ref and nothing else
|
||||
---
|
||||
duration_ms: 0.164816
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each landing entry is one turn before any message, with the state block and the fixed request; it sends nothing and reads nothing
|
||||
ok 106 - each landing entry is one turn before any message, with the state block and the fixed request; it sends nothing and reads nothing
|
||||
---
|
||||
duration_ms: 194.388382
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an empty landing takes no landing turn: the message is turn 1
|
||||
ok 107 - an empty landing takes no landing turn: the message is turn 1
|
||||
---
|
||||
duration_ms: 169.087161
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages
|
||||
ok 108 - a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages
|
||||
---
|
||||
duration_ms: 593.697326
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a malformed landing exits 2 before the claim, with no turn
|
||||
ok 109 - a malformed landing exits 2 before the claim, with no turn
|
||||
---
|
||||
duration_ms: 588.465293
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 65 a session.json without a turnEnd of marker or exit, or a harnessEnv of strings, exits 2 before the claim
|
||||
ok 110 - row 65 a session.json without a turnEnd of marker or exit, or a harnessEnv of strings, exits 2 before the claim
|
||||
---
|
||||
duration_ms: 269.490704
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 65 harnessEnv reaches the adapter, and an exit harness needs no turn marker
|
||||
ok 111 - row 65 harnessEnv reaches the adapter, and an exit harness needs no turn marker
|
||||
---
|
||||
duration_ms: 140.939478
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 the adapter gets the run's unslop log, and a flagged reply's note rides that reply's RESULT, once
|
||||
ok 112 - row 66 the adapter gets the run's unslop log, and a flagged reply's note rides that reply's RESULT, once
|
||||
---
|
||||
duration_ms: 299.513041
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a turn with no reply holds its note for the next reply; a broken check is told once
|
||||
ok 113 - row 66 a turn with no reply holds its note for the next reply; a broken check is told once
|
||||
---
|
||||
duration_ms: 344.053772
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 unslopNotes keeps a note until sent(), reads only whole lines, and unslopCounts reads a log after the session
|
||||
ok 114 - row 66 unslopNotes keeps a note until sent(), reads only whole lines, and unslopCounts reads a log after the session
|
||||
---
|
||||
duration_ms: 1.625977
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a clipped answer with both note parts stays under the bus's body limit, and the note under 600
|
||||
ok 115 - row 66 a clipped answer with both note parts stays under the bus's body limit, and the note under 600
|
||||
---
|
||||
duration_ms: 164.004169
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a refused send keeps the note: it rides the next RESULT the session sends
|
||||
ok 116 - row 66 a refused send keeps the note: it rides the next RESULT the session sends
|
||||
---
|
||||
duration_ms: 265.387583
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each repo role's prompt carries exactly its listed skills, each file as the bundle copy and the source
|
||||
ok 117 - each repo role's prompt carries exactly its listed skills, each file as the bundle copy and the source
|
||||
---
|
||||
duration_ms: 67.932587
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill's files go into the prompt in sorted path order, sub-directories included
|
||||
ok 118 - a skill's files go into the prompt in sorted path order, sub-directories included
|
||||
---
|
||||
duration_ms: 8.841973
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role with no skills gets no Skills section, no skills directory and an empty manifest list
|
||||
ok 119 - a role with no skills gets no Skills section, no skills directory and an empty manifest list
|
||||
---
|
||||
duration_ms: 9.451587
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an enabled skill the role doesn't list stays out of the prompt
|
||||
ok 120 - an enabled skill the role doesn't list stays out of the prompt
|
||||
---
|
||||
duration_ms: 8.012055
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bundle copy outlives the source: deactivating a skill after the build leaves the run's copy
|
||||
ok 121 - the bundle copy outlives the source: deactivating a skill after the build leaves the run's copy
|
||||
---
|
||||
duration_ms: 4.002388
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a listed skill that isn't enabled refuses skill-not-enabled, naming the activate command
|
||||
ok 122 - a listed skill that isn't enabled refuses skill-not-enabled, naming the activate command
|
||||
---
|
||||
duration_ms: 8.866982
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill directory that isn't plain refuses: a symlinked skill, SKILL.md or sub-file, or a non-file entry
|
||||
ok 123 - a skill directory that isn't plain refuses: a symlinked skill, SKILL.md or sub-file, or a non-file entry
|
||||
---
|
||||
duration_ms: 2.434392
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill file that can't go into the prompt refuses: a bad name, non-UTF-8 bytes, or the end marker
|
||||
ok 124 - a skill file that can't go into the prompt refuses: a bad name, non-UTF-8 bytes, or the end marker
|
||||
---
|
||||
duration_ms: 2.963756
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role's skills over SKILL_BYTES together refuse, naming the skill that crossed it
|
||||
ok 125 - a role's skills over SKILL_BYTES together refuse, naming the skill that crossed it
|
||||
---
|
||||
duration_ms: 10.218264
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each adapter passes the skills only in the prompt file, with skill discovery off
|
||||
ok 126 - each adapter passes the skills only in the prompt file, with skill discovery off
|
||||
---
|
||||
duration_ms: 51.481115
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: every role sees read_spec, record writer follows its grant, citation schemas stay strict
|
||||
ok 127 - every role sees read_spec, record writer follows its grant, citation schemas stay strict
|
||||
---
|
||||
duration_ms: 26.090685
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: typed socket forwards read content/history and agent record writes, and cannot write a spec
|
||||
ok 128 - typed socket forwards read content/history and agent record writes, and cannot write a spec
|
||||
---
|
||||
duration_ms: 160.029157
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the PM gets its task verbs and the reads, and no launch
|
||||
ok 129 - the PM gets its task verbs and the reads, and no launch
|
||||
---
|
||||
duration_ms: 16.993015
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: send_message offers the BLOCK class, beside the classes it already had
|
||||
ok 130 - send_message offers the BLOCK class, beside the classes it already had
|
||||
---
|
||||
duration_ms: 6.326843
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the chief of staff gets launch, send_message, end_run, hire, fire, change_organization and set_name, and no task verbs
|
||||
ok 131 - the chief of staff gets launch, send_message, end_run, hire, fire, change_organization and set_name, and no task verbs
|
||||
---
|
||||
duration_ms: 6.133336
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: hire and fire send instance.hire and instance.fire under role.hire and role.fire, only for a holder of the grant
|
||||
ok 132 - hire and fire send instance.hire and instance.fire under role.hire and role.fire, only for a holder of the grant
|
||||
---
|
||||
duration_ms: 32.305882
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: request_staff is the pm's alone: staff.request over message.send, roles and counts bounded
|
||||
ok 133 - request_staff is the pm's alone: staff.request over message.send, roles and counts bounded
|
||||
---
|
||||
duration_ms: 11.979392
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: end_run sends role and reason, no decision; change_organization sends revision and the organization keys
|
||||
ok 134 - end_run sends role and reason, no decision; change_organization sends revision and the organization keys
|
||||
---
|
||||
duration_ms: 3.333633
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: set_name sends instance and name to name.set under instance.name, only for a holder of that grant
|
||||
ok 135 - set_name sends instance and name to name.set under instance.name, only for a holder of that grant
|
||||
---
|
||||
duration_ms: 11.144938
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the organization keys change_organization takes are the broker's ORGANIZATION_KEYS and the settings' SETTINGS_KEYS
|
||||
ok 136 - the organization keys change_organization takes are the broker's ORGANIZATION_KEYS and the settings' SETTINGS_KEYS
|
||||
---
|
||||
duration_ms: 0.154911
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role without role.end or organization.change gets none of the three tools, and each follows its own grant
|
||||
ok 137 - a role without role.end or organization.change gets none of the three tools, and each follows its own grant
|
||||
---
|
||||
duration_ms: 11.053899
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no role's tools send instances or instances.set, and change_organization takes no instance write keys
|
||||
ok 138 - no role's tools send instances or instances.set, and change_organization takes no instance write keys
|
||||
---
|
||||
duration_ms: 16.543469
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch
|
||||
ok 139 - the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch
|
||||
---
|
||||
duration_ms: 2.023044
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: list_requirements reads the requirement ids, for a task.create holder with a tracker
|
||||
ok 140 - list_requirements reads the requirement ids, for a task.create holder with a tracker
|
||||
---
|
||||
duration_ms: 3.61918
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a coder gets no launch, no resolve_decision, and no task tools without a tracker
|
||||
ok 141 - a coder gets no launch, no resolve_decision, and no task tools without a tracker
|
||||
---
|
||||
duration_ms: 1.306923
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a coder with a tracker gets its own task tools and no task_reassign
|
||||
ok 142 - a coder with a tracker gets its own task tools and no task_reassign
|
||||
---
|
||||
duration_ms: 1.839146
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: launch only when the business's launch block names the instance as launcher
|
||||
ok 143 - launch only when the business's launch block names the instance as launcher
|
||||
---
|
||||
duration_ms: 3.69801
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an action outside the instance's authority has no tool
|
||||
ok 144 - an action outside the instance's authority has no tool
|
||||
---
|
||||
duration_ms: 2.748294
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM
|
||||
ok 145 - the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM
|
||||
---
|
||||
duration_ms: 7.876885
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: land_work is there only with land, after push_working, with the task and the decision
|
||||
ok 146 - land_work is there only with land, after push_working, with the task and the decision
|
||||
---
|
||||
duration_ms: 3.4848
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: callTool: one JSON line out, the result back, a refusal rejects
|
||||
ok 147 - callTool: one JSON line out, the result back, a refusal rejects
|
||||
---
|
||||
duration_ms: 19.887473
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: list_tasks takes the broker's filters and pages; get_task takes a task_ref
|
||||
ok 148 - list_tasks takes the broker's filters and pages; get_task takes a task_ref
|
||||
---
|
||||
duration_ms: 2.905426
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: callTool sends list_tasks done false unless the session names done; other tools as given
|
||||
ok 149 - callTool sends list_tasks done false unless the session names done; other tools as given
|
||||
---
|
||||
duration_ms: 3.254658
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: replyText: compact JSON up to the cap, an error naming the size and the cap over it
|
||||
ok 150 - replyText: compact JSON up to the cap, an error naming the size and the cap over it
|
||||
---
|
||||
duration_ms: 0.93267
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS
|
||||
ok 151 - web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS
|
||||
---
|
||||
duration_ms: 2.974653
|
||||
type: 'test'
|
||||
...
|
||||
1..151
|
||||
# tests 151
|
||||
# suites 0
|
||||
# pass 150
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 11932.623925
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
{"head": "06d7cc2f0ffc544abfb2755f99dce76ca164212c", "manifest": "420befed0aa8291736d34187ac7e745b7660efed15348ece045a7dd8957c9124", "start": "2026-10-23T09:21:11.121484+00:00"}
|
||||
@@ -0,0 +1,2 @@
|
||||
Error response from daemon: network rocko-r219-gate_default not found
|
||||
exit status 1
|
||||
@@ -0,0 +1,23 @@
|
||||
{"label": "single-bus-creative.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/creative.test.mjs"], "start": "2026-10-23T09:21:11.124448+00:00", "end": "2026-10-23T09:21:11.489626+00:00", "seconds": 0.365, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-creative.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rE8UFj4"}
|
||||
{"label": "single-bus-grant-executor.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/grant-executor.test.mjs"], "start": "2026-10-23T09:21:11.492089+00:00", "end": "2026-10-23T09:21:33.052545+00:00", "seconds": 21.56, "exit": 0, "timeout": false, "counts": {"tests": 42, "pass": 42, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-grant-executor.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rgY53eZ"}
|
||||
{"label": "single-bus-project-runtime.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/project-runtime.test.mjs"], "start": "2026-10-23T09:21:33.054938+00:00", "end": "2026-10-23T09:21:33.469616+00:00", "seconds": 0.415, "exit": 0, "timeout": false, "counts": {"tests": 3, "pass": 3, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-project-runtime.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rlFp4K6"}
|
||||
{"label": "single-bus-threads.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/threads.test.mjs"], "start": "2026-10-23T09:21:33.471762+00:00", "end": "2026-10-23T09:21:34.838718+00:00", "seconds": 1.367, "exit": 0, "timeout": false, "counts": {"tests": 20, "pass": 20, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-threads.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rshM4G7"}
|
||||
{"label": "single-bus-user-principal.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/bus/tests/user-principal.test.mjs"], "start": "2026-10-23T09:21:34.841038+00:00", "end": "2026-10-23T09:21:35.456433+00:00", "seconds": 0.615, "exit": 0, "timeout": false, "counts": {"tests": 23, "pass": 23, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-bus-user-principal.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYf1Xvx"}
|
||||
{"label": "single-cli-launcher.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/launcher.test.mjs"], "start": "2026-10-23T09:21:35.458772+00:00", "end": "2026-10-23T09:22:02.030225+00:00", "seconds": 26.571, "exit": 0, "timeout": false, "counts": {"tests": 34, "pass": 34, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-cli-launcher.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/raf1e60"}
|
||||
{"label": "single-cli-thread-launch.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/cli/tests/thread-launch.test.mjs"], "start": "2026-10-23T09:22:02.032690+00:00", "end": "2026-10-23T09:22:20.094607+00:00", "seconds": 18.062, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-cli-thread-launch.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/r1Bsuqs"}
|
||||
{"label": "single-webui-chat-browser.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-browser.test.mjs"], "start": "2026-10-23T09:22:20.097013+00:00", "end": "2026-10-23T09:22:38.808507+00:00", "seconds": 18.711, "exit": 0, "timeout": false, "counts": {"tests": 14, "pass": 14, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat-browser.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYKVUnz"}
|
||||
{"label": "single-webui-chat-instances.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat-instances.test.mjs"], "start": "2026-10-23T09:22:38.810775+00:00", "end": "2026-10-23T09:22:38.975118+00:00", "seconds": 0.164, "exit": 0, "timeout": false, "counts": {"tests": 4, "pass": 4, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat-instances.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rRn9NQr"}
|
||||
{"label": "single-webui-chat.test", "args": ["timeout", "-k", "10", "300", "node", "--test-reporter=tap", "--test", "packages/webui/tests/chat.test.mjs"], "start": "2026-10-23T09:22:38.977256+00:00", "end": "2026-10-23T09:22:39.442318+00:00", "seconds": 0.465, "exit": 0, "timeout": false, "counts": {"tests": 25, "pass": 25, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/single-webui-chat.test.tap", "tmpdir": "/mnt/storage/scratch/tmp/rZRH3FV"}
|
||||
{"label": "suite-bus", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/account-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/approval-binding.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/broker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/business.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/channel-proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/chief-of-staff.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-cursors.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/comment-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-claim.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-store.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credential-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/csuite-messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/daily-quota-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-close.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decision-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/decisions.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/end-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/fire-revokes-grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant-docker.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-grant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/gitea-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-enroll.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-executor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/grant-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/hard-waits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-run.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/host-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/human.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/instances-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/interpreter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/land.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launch-notice.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/launcher-released.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library-sync.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/library.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-revoke.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/lifecycle-verbs.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limit-stop.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-citation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/message-filter.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/messaging.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/name-migration.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peer-transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/peercred.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/plugins-verb.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/principal.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/process.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-runtime.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-timeout.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing-web.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-await.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-files.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/bus/tests/project-runtime.test.mjs", "/mnt/Line truncated
|
||||
{"label": "suite-cli", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/access.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/app.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/boot-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-accept.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case1-hostcheck.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-persona-import.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/case2-unit.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/channel-recovery.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/compactions-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/config.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/credentials.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/follow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/format.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-auth.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-fixtures.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-image.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane-state.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/gate-lane.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/git-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/grants.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/host.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/hosts.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/idle-stop-race.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-account.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limit-checks.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launch-routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/launcher.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/lifecycle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits-tokens.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/limits.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/mark-read.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/names.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/notifier.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/other-tree.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/processing-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/project.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/publish-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-clear.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/session-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release-external.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-release.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/stack-upgrade.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-http.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester-threads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/tester.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/thread-launch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/trackers-boot.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/transport.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/cli/tests/verbs.test.mjs"], "start": "2026-10-23T09:23:03.024737+00:00", "end": "2026-10-23T09:33:27.205598+00:00", "seconds": 624.181, "exit": 0, "timeout": false, "counts": {"tests": 921, "pass": 921, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/suite-cli.tap", "tmpdir": "/mnt/storage/scratch/tmp/rl2zH3q"}
|
||||
{"label": "suite-webui", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/agents.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/assistant.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/board-held.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser-edge.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/bus.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/channel-chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat-instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/chat.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/conversation.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/discord.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/docs-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor-provenance.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/editor.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/granted-user.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/history-return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/instances.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/library-status.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/limits-route.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/markdown-preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/messages.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/pinned-copy.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/preview.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing-ui.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/processing.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-file.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/project-name-repo.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/proof.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/reads.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/relaunch.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/return-flow.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/routes.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/send.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/serve.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/service.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-form.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/settings-write.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/shell.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/sso.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-cli.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-listener.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/tester-socket.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/thread-claims.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage-browser.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/usage.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/webui/tests/views.test.mjs"], "start": "2026-10-23T09:33:27.214222+00:00", "end": "2026-10-23T09:34:24.087380+00:00", "seconds": 56.873, "exit": 0, "timeout": false, "counts": {"tests": 374, "pass": 373, "fail": 0, "cancelled": 0, "skipped": 1}, "skips": ["ok 107 - rebuilding from the source gives the same bytes (needLine truncated
|
||||
{"label": "suite-harness", "args": ["timeout", "-k", "10", "1800", "node", "--test-reporter=tap", "--test", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/bundle.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/claude-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/creative.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/gate.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/git-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/mcp-server.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/pi-session.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/raise-domain.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/runner.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/skills.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/spec-tools.test.mjs", "/mnt/storage/scratch/rocko-r219/packages/harness/tests/tools.test.mjs"], "start": "2026-10-23T09:34:24.092087+00:00", "end": "2026-10-23T09:34:36.185801+00:00", "seconds": 12.094, "exit": 0, "timeout": false, "counts": {"tests": 151, "pass": 151, "fail": 0, "cancelled": 0, "skipped": 0}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/suite-harness.tap", "tmpdir": "/mnt/storage/scratch/tmp/rYOp9Yo"}
|
||||
{"label": "test-auth", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-auth.sh"], "start": "2026-10-23T09:34:36.189152+00:00", "end": "2026-10-23T09:34:37.005046+00:00", "seconds": 0.816, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-auth.tap", "tmpdir": "/mnt/storage/scratch/tmp/r7XakMj"}
|
||||
{"label": "test-conductor", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-conductor.sh"], "start": "2026-10-23T09:34:37.007148+00:00", "end": "2026-10-23T09:34:43.835703+00:00", "seconds": 6.829, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-conductor.tap", "tmpdir": "/mnt/storage/scratch/tmp/rH7Fj9q"}
|
||||
{"label": "test-config", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-config.sh"], "start": "2026-10-23T09:34:43.837837+00:00", "end": "2026-10-23T09:34:46.357228+00:00", "seconds": 2.519, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-config.tap", "tmpdir": "/mnt/storage/scratch/tmp/rXiHyiw"}
|
||||
{"label": "test-discord", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-discord.sh"], "start": "2026-10-23T09:34:46.359375+00:00", "end": "2026-10-23T09:34:53.590250+00:00", "seconds": 7.231, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-discord.tap", "tmpdir": "/mnt/storage/scratch/tmp/rcHYakY"}
|
||||
{"label": "test-extension-package", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-extension-package.sh"], "start": "2026-10-23T09:34:53.592317+00:00", "end": "2026-10-23T09:34:54.908860+00:00", "seconds": 1.317, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-extension-package.tap", "tmpdir": "/mnt/storage/scratch/tmp/rxrTT3R"}
|
||||
{"label": "test-foundation", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-foundation.sh"], "start": "2026-10-23T09:34:54.910888+00:00", "end": "2026-10-23T09:35:33.605612+00:00", "seconds": 38.695, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-foundation.tap", "tmpdir": "/mnt/storage/scratch/tmp/rs2BwtK"}
|
||||
{"label": "test-land-work", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-land-work.sh"], "start": "2026-10-23T09:35:33.607688+00:00", "end": "2026-10-23T09:35:45.646160+00:00", "seconds": 12.038, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-land-work.tap", "tmpdir": "/mnt/storage/scratch/tmp/rZFhfL5"}
|
||||
{"label": "test-queue", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-queue.sh"], "start": "2026-10-23T09:35:45.648522+00:00", "end": "2026-10-23T09:36:06.604342+00:00", "seconds": 20.956, "exit": 0, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": ["skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-queue.tap", "tmpdir": "/mnt/storage/scratch/tmp/rAKp0eR"}
|
||||
{"label": "test-release", "args": ["timeout", "-k", "10", "7200", "bash", "/mnt/storage/scratch/rocko-r219/scripts/test-release.sh"], "start": "2026-10-23T09:36:06.606593+00:00", "end": "2026-10-23T09:36:07.873175+00:00", "seconds": 1.267, "exit": 1, "timeout": false, "counts": {"tests": null, "pass": null, "fail": null, "cancelled": null, "skipped": null}, "skips": [], "log": "agents/rocko/work/queue-219/run-0780-mos1432/test-release.tap", "tmpdir": "/mnt/storage/scratch/tmp/rbunO3T"}
|
||||
@@ -0,0 +1,36 @@
|
||||
TAP version 13
|
||||
# organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
# organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
# Subtest: M6: a creative raise refuses decision-not-allowed, cited or not, and no decision row appears; the assistant still raises
|
||||
ok 1 - M6: a creative raise refuses decision-not-allowed, cited or not, and no decision row appears; the assistant still raises
|
||||
---
|
||||
duration_ms: 36.85368
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a creative instance sends only to the user and hears only from the user
|
||||
ok 2 - a creative instance sends only to the user and hears only from the user
|
||||
---
|
||||
duration_ms: 43.623512
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M10 through the broker: the chief and the tester are refused on bean, the human's limits.set of its models key works
|
||||
ok 3 - M10 through the broker: the chief and the tester are refused on bean, the human's limits.set of its models key works
|
||||
---
|
||||
duration_ms: 75.244973
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 256 T6 the human deletes a creative instance through the broker; the chief and the tester are refused at the verb
|
||||
ok 4 - row 256 T6 the human deletes a creative instance through the broker; the chief and the tester are refused at the verb
|
||||
---
|
||||
duration_ms: 59.840986
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
# tests 4
|
||||
# suites 0
|
||||
# pass 4
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 329.154565
|
||||
@@ -0,0 +1,262 @@
|
||||
TAP version 13
|
||||
# Subtest: row 280: an occupied TCP port is attempted, refused, and retried with our sshd
|
||||
ok 1 - row 280: an occupied TCP port is attempted, refused, and retried with our sshd
|
||||
---
|
||||
duration_ms: 84.792579
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 280: every injected picker sample is unprivileged and outside the ephemeral range
|
||||
ok 2 - row 280: every injected picker sample is unprivileged and outside the ephemeral range
|
||||
---
|
||||
duration_ms: 0.326649
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G7: an Approve installs the tagged line, logs in with the new key, and writes the key file, record and grant.applied
|
||||
ok 3 - G7: an Approve installs the tagged line, logs in with the new key, and writes the key file, record and grant.applied
|
||||
---
|
||||
duration_ms: 664.962935
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G7: a commands change on a live grant updates the record in one transaction and keeps the key and line
|
||||
ok 4 - G7: a commands change on a live grant updates the record in one transaction and keeps the key and line
|
||||
---
|
||||
duration_ms: 530.919797
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failure at install or verify removes the line and leaves no record, key file or reference
|
||||
ok 5 - G8: a failure at install or verify removes the line and leaves no record, key file or reference
|
||||
---
|
||||
duration_ms: 1515.247467
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failed remove adds hostLineLeft and tells the human to sweep
|
||||
ok 6 - G8: a failed remove adds hostLineLeft and tells the human to sweep
|
||||
---
|
||||
duration_ms: 652.389071
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failure in step 5 before commit unlinks the key file, drops the reference and removes the line
|
||||
ok 7 - G8: a failure in step 5 before commit unlinks the key file, drops the reference and removes the line
|
||||
---
|
||||
duration_ms: 682.957188
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a store fault in the commit transaction ends host-failed with no record, key file, reference or line
|
||||
ok 8 - G8: a store fault in the commit transaction ends host-failed with no record, key file, reference or line
|
||||
---
|
||||
duration_ms: 652.039785
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G8: a failed step 1 check spends the decision and runs nothing remote
|
||||
ok 9 - G8: a failed step 1 check spends the decision and runs nothing remote
|
||||
---
|
||||
duration_ms: 83.702893
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G9: a registry, definition or commands change between raise and Approve ends decision-mismatch before any remote step
|
||||
ok 10 - G9: a registry, definition or commands change between raise and Approve ends decision-mismatch before any remote step
|
||||
---
|
||||
duration_ms: 501.685122
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G9: an agent no longer a role or no longer declaring host ends with its code, spent
|
||||
ok 11 - G9: an agent no longer a role or no longer declaring host ends with its code, spent
|
||||
---
|
||||
duration_ms: 70.200852
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G10: a second start refuses decision-consumed, and an unresolved or agent-resolved decision not-authorized, writing nothing
|
||||
ok 12 - G10: a second start refuses decision-consumed, and an unresolved or agent-resolved decision not-authorized, writing nothing
|
||||
---
|
||||
duration_ms: 495.905464
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G15: no event, message or decision holds the private key
|
||||
ok 13 - G15: no event, message or decision holds the private key
|
||||
---
|
||||
duration_ms: 507.045691
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23: a revoke during install ends grant.failed revoked with no key file, no grant and no line
|
||||
ok 14 - G23: a revoke during install ends grant.failed revoked with no key file, no grant and no line
|
||||
---
|
||||
duration_ms: 487.107602
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (row 249): an add that writes after an abort's remove leaves hostLineLeft until the sweep
|
||||
ok 15 - G23 (row 249): an add that writes after an abort's remove leaves hostLineLeft until the sweep
|
||||
---
|
||||
duration_ms: 868.96012
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (row 249): an add that writes after a timed-out install's remove leaves hostLineLeft until the sweep
|
||||
ok 16 - G23 (row 249): an add that writes after a timed-out install's remove leaves hostLineLeft until the sweep
|
||||
---
|
||||
duration_ms: 854.053656
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23: a revoke recorded after the raise and before the start ends step 1 revoked, and a held slot ends host-busy
|
||||
ok 17 - G23: a revoke recorded after the raise and before the start ends step 1 revoked, and a held slot ends host-busy
|
||||
---
|
||||
duration_ms: 518.869102
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G24: names at 64 characters with . and _ give distinct tags of the fixed length
|
||||
ok 18 - G24: names at 64 characters with . and _ give distinct tags of the fixed length
|
||||
---
|
||||
duration_ms: 0.35727
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after install removes the line, then ends interrupted with the tag, holding the slot until then
|
||||
ok 19 - G11: a restart after install removes the line, then ends interrupted with the tag, holding the slot until then
|
||||
---
|
||||
duration_ms: 209.447782
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after a new key's commit, with the key file written, ends with no key file, record, reference or line
|
||||
ok 20 - G11: a restart after a new key's commit, with the key file written, ends with no key file, record, reference or line
|
||||
---
|
||||
duration_ms: 212.583298
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart after a commands change's commit leaves the record as it was and asks nothing of the host
|
||||
ok 21 - G11: a restart after a commands change's commit leaves the record as it was and asks nothing of the host
|
||||
---
|
||||
duration_ms: 513.973581
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11 (B2): a restart before step 1, spent or not yet spent, ends interrupted and nothing runs later
|
||||
ok 22 - G11 (B2): a restart before step 1, spent or not yet spent, ends interrupted and nothing runs later
|
||||
---
|
||||
duration_ms: 69.77008
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a remote undo that fails ends interrupted with hostLineLeft and the sweep hint
|
||||
ok 23 - G11: a remote undo that fails ends interrupted with hostLineLeft and the sweep hint
|
||||
---
|
||||
duration_ms: 273.086714
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G11: a restart leaves a finished grant alone, and the reconcile adds nothing for it
|
||||
ok 24 - G11: a restart leaves a finished grant alone, and the reconcile adds nothing for it
|
||||
---
|
||||
duration_ms: 509.129523
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: N1 (G27): the start sweep unlinks host.<id> files with no record in loaded businesses only, and refuses a store dir that is not private
|
||||
ok 25 - N1 (G27): the start sweep unlinks host.<id> files with no record in loaded businesses only, and refuses a store dir that is not private
|
||||
---
|
||||
duration_ms: 6.448287
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12: the human's hosts.revoke deletes the record, the key file, the reference and the line, with a closed marker
|
||||
ok 26 - G12: the human's hosts.revoke deletes the record, the key file, the reference and the line, with a closed marker
|
||||
---
|
||||
duration_ms: 656.766603
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12 (N4): a revoke with no record still removes the computed tag's line, with granted false; bad args refuse
|
||||
ok 27 - G12 (N4): a revoke with no record still removes the computed tag's line, with granted false; bad args refuse
|
||||
---
|
||||
duration_ms: 212.916285
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G13: a revoke during install aborts the executor, which ends revoked, and the line goes
|
||||
ok 28 - G13: a revoke during install aborts the executor, which ends revoked, and the line goes
|
||||
---
|
||||
duration_ms: 556.515063
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G26: the human, the assistant and the tester revoke; the chief and a pm refuse; sweep is the human's or the tester's
|
||||
ok 29 - G26: the human, the assistant and the tester revoke; the chief and a pm refuse; sweep is the human's or the tester's
|
||||
---
|
||||
duration_ms: 506.975086
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 281 T8: a tester hosts.revoke refuses tester-dev-only once bus.tester is off, and a human revoke writes no job records
|
||||
ok 30 - row 281 T8: a tester hosts.revoke refuses tester-dev-only once bus.tester is off, and a human revoke writes no job records
|
||||
---
|
||||
duration_ms: 656.756338
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: a restart after step 1 sweeps the key file and runs step 3 once the bus is up; status shows the revoke until then
|
||||
ok 31 - G27: a restart after step 1 sweeps the key file and runs step 3 once the bus is up; status shows the revoke until then
|
||||
---
|
||||
duration_ms: 656.196081
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: after step 2 with the host down, the restart closes the marker with hostLineLeft; a marker without a revoke id is not reopened
|
||||
ok 32 - G27: after step 2 with the host down, the restart closes the marker with hostLineLeft; a marker without a revoke id is not reopened
|
||||
---
|
||||
duration_ms: 948.521525
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G27: a key file a revoke could not unlink is reported left and goes at the next start
|
||||
ok 33 - G27: a key file a revoke could not unlink is reported left and goes at the next start
|
||||
---
|
||||
duration_ms: 656.796578
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G28: a commands change, then a revoke, then a restart leave no record, key, reference or line
|
||||
ok 34 - G28: a commands change, then a revoke, then a restart leave no record, key, reference or line
|
||||
---
|
||||
duration_ms: 681.732565
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G24 (B4): hosts.sweep removes only this business's recorded tags no live grant holds, and records what it left
|
||||
ok 35 - G24 (B4): hosts.sweep removes only this business's recorded tags no live grant holds, and records what it left
|
||||
---
|
||||
duration_ms: 950.42161
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G12: the local steps finish before the host step, so a host that hangs leaves the agent no access
|
||||
ok 36 - G12: the local steps finish before the host step, so a host that hangs leaves the agent no access
|
||||
---
|
||||
duration_ms: 706.747634
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (X5): a revoke right after the spend reaches the executor's claim, so the grant ends revoked
|
||||
ok 37 - G23 (X5): a revoke right after the spend reaches the executor's claim, so the grant ends revoked
|
||||
---
|
||||
duration_ms: 208.910785
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G23 (X5): a revoke that lands as verify returns ends revoked with no record, key file or line
|
||||
ok 38 - G23 (X5): a revoke that lands as verify returns ends revoked with no record, key file or line
|
||||
---
|
||||
duration_ms: 653.947432
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G13: a revoke whose host remove fails still drops the record and key, and reports the line left for a sweep
|
||||
ok 39 - G13: a revoke whose host remove fails still drops the record and key, and reports the line left for a sweep
|
||||
---
|
||||
duration_ms: 655.105432
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: G22: enroll, check, grant, host.run, a commands change the next host.run uses, and a revoke that kills a run in flight
|
||||
ok 40 - G22: enroll, check, grant, host.run, a commands change the next host.run uses, and a revoke that kills a run in flight
|
||||
---
|
||||
duration_ms: 1175.585222
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: mos-1163: a grant whose agent became a creative role after the raise ends host-creative-role at step 1, spent, with nothing remote
|
||||
ok 41 - mos-1163: a grant whose agent became a creative role after the raise ends host-creative-role at step 1, spent, with nothing remote
|
||||
---
|
||||
duration_ms: 64.065129
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: sage-1908: once the agent of an applied grant is a creative role, host.run refuses host-creative-role, runs nothing remote and keeps the record
|
||||
ok 42 - sage-1908: once the agent of an applied grant is a creative role, host.run refuses host-creative-role, runs nothing remote and keeps the record
|
||||
---
|
||||
duration_ms: 515.14952
|
||||
type: 'test'
|
||||
...
|
||||
1..42
|
||||
# tests 42
|
||||
# suites 0
|
||||
# pass 42
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 21511.94314
|
||||
@@ -0,0 +1,28 @@
|
||||
TAP version 13
|
||||
# Subtest: Broker keeps the sandbox client import closure: only the listed imports, no lazy project import
|
||||
ok 1 - Broker keeps the sandbox client import closure: only the listed imports, no lazy project import
|
||||
---
|
||||
duration_ms: 2.221263
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: without a trusted project adapter all three async paths refuse project-not-configured
|
||||
ok 2 - without a trusted project adapter all three async paths refuse project-not-configured
|
||||
---
|
||||
duration_ms: 46.879844
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: real startBroker injects the project adapter for socket reads and bound-author record writes
|
||||
ok 3 - real startBroker injects the project adapter for socket reads and bound-author record writes
|
||||
---
|
||||
duration_ms: 198.251134
|
||||
type: 'test'
|
||||
...
|
||||
1..3
|
||||
# tests 3
|
||||
# suites 0
|
||||
# pass 3
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 358.792646
|
||||
@@ -0,0 +1,130 @@
|
||||
TAP version 13
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger
|
||||
ok 1 - REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger
|
||||
---
|
||||
duration_ms: 46.276479
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker
|
||||
ok 2 - REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker
|
||||
---
|
||||
duration_ms: 69.469229
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: a message to or from the assistant names its thread, or is refused
|
||||
ok 3 - REQ-MSG-1: a message to or from the assistant names its thread, or is refused
|
||||
---
|
||||
duration_ms: 34.991913
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work
|
||||
ok 4 - REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work
|
||||
---
|
||||
duration_ms: 594.420694
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance
|
||||
ok 5 - REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance
|
||||
---
|
||||
duration_ms: 23.495652
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder
|
||||
ok 6 - REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder
|
||||
---
|
||||
duration_ms: 27.65556
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it
|
||||
ok 7 - REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it
|
||||
---
|
||||
duration_ms: 30.593037
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder
|
||||
ok 8 - REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder
|
||||
---
|
||||
duration_ms: 32.534079
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder
|
||||
ok 9 - REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder
|
||||
---
|
||||
duration_ms: 28.389825
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-THREAD-1 Q169: a role.revoke the human approved ends every thread run of the assistant
|
||||
ok 10 - REQ-ROLE-2 REQ-THREAD-1 Q169: a role.revoke the human approved ends every thread run of the assistant
|
||||
---
|
||||
duration_ms: 25.464009
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: Q169 REQ-USER-2: assistant.stop ends the human's own assistant thread runs, and only the human's
|
||||
ok 11 - Q169 REQ-USER-2: assistant.stop ends the human's own assistant thread runs, and only the human's
|
||||
---
|
||||
duration_ms: 39.491556
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-USER-2: the human verbs refuse another owner's thread
|
||||
ok 12 - REQ-USER-2: the human verbs refuse another owner's thread
|
||||
---
|
||||
duration_ms: 28.048633
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one
|
||||
ok 13 - REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one
|
||||
---
|
||||
duration_ms: 24.088048
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ORG-2: projects and threads are named once, and the repo names a business project
|
||||
ok 14 - REQ-ORG-2: projects and threads are named once, and the repo names a business project
|
||||
---
|
||||
duration_ms: 26.256197
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing
|
||||
ok 15 - REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing
|
||||
---
|
||||
duration_ms: 87.797965
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: project.create refuses a repository name without its matching repo before any write
|
||||
ok 16 - project.create refuses a repository name without its matching repo before any write
|
||||
---
|
||||
duration_ms: 16.297996
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: project.create keeps unrelated names with and without a repository
|
||||
ok 17 - project.create keeps unrelated names with and without a repository
|
||||
---
|
||||
duration_ms: 11.447173
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
ok 18 - C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
---
|
||||
duration_ms: 46.283738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
ok 19 - C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
---
|
||||
duration_ms: 19.79704
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
ok 20 - C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
---
|
||||
duration_ms: 10.088475
|
||||
type: 'test'
|
||||
...
|
||||
1..20
|
||||
# tests 20
|
||||
# suites 0
|
||||
# pass 20
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 1306.906064
|
||||
@@ -0,0 +1,148 @@
|
||||
TAP version 13
|
||||
# Subtest: R3: bindUser binds a granted user and refuses one with no live grant
|
||||
ok 1 - R3: bindUser binds a granted user and refuses one with no live grant
|
||||
---
|
||||
duration_ms: 24.024956
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user named like the business human, the tester or a principal word is refused, whatever the grants say
|
||||
ok 2 - R3: a user named like the business human, the tester or a principal word is refused, whatever the grants say
|
||||
---
|
||||
duration_ms: 9.836512
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: each collaborator verb is allowed to a granted user
|
||||
ok 3 - R3: each collaborator verb is allowed to a granted user
|
||||
---
|
||||
duration_ms: 18.664347
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: every verb off the collaborator list refuses a user access-refused before its own checks
|
||||
ok 4 - R3: every verb off the collaborator list refuses a user access-refused before its own checks
|
||||
---
|
||||
duration_ms: 103.87669
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: task, web and host verbs refuse a user access-refused
|
||||
ok 5 - R3: task, web and host verbs refuse a user access-refused
|
||||
---
|
||||
duration_ms: 24.446629
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: project.list shows granted projects only
|
||||
ok 6 - R3 leak: project.list shows granted projects only
|
||||
---
|
||||
duration_ms: 13.549355
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: thread.create needs the project and the thread instance granted, and an ungranted id reads as one that does not exist
|
||||
ok 7 - R3 leak: thread.create needs the project and the thread instance granted, and an ungranted id reads as one that does not exist
|
||||
---
|
||||
duration_ms: 15.528212
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: thread.list shows the user its own threads that are still granted, never others
|
||||
ok 8 - R3 leak: thread.list shows the user its own threads that are still granted, never others
|
||||
---
|
||||
duration_ms: 32.908592
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 leak: names shows granted instances only
|
||||
ok 9 - R3 leak: names shows granted instances only
|
||||
---
|
||||
duration_ms: 14.244576
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: thread.send is from user:<id> and writes no human.input
|
||||
ok 10 - R3: thread.send is from user:<id> and writes no human.input
|
||||
---
|
||||
duration_ms: 12.891074
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a reply-chain message.send into another user thread is refused
|
||||
ok 11 - R3: a reply-chain message.send into another user thread is refused
|
||||
---
|
||||
duration_ms: 14.699119
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: the run reply to a user message reaches that user thread.messages, with no waiting and no notice
|
||||
ok 12 - R3: the run reply to a user message reaches that user thread.messages, with no waiting and no notice
|
||||
---
|
||||
duration_ms: 18.27228
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a reply to: user without a matching in_reply_to is refused user-reply-required
|
||||
ok 13 - R3: a reply to: user without a matching in_reply_to is refused user-reply-required
|
||||
---
|
||||
duration_ms: 27.890498
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a non-thread run, the human and the tester cannot send to: user
|
||||
ok 14 - R3: a non-thread run, the human and the tester cannot send to: user
|
||||
---
|
||||
duration_ms: 18.357501
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user thread run cannot message the owner, while its uncited gated raise reaches only the owner inbox, B9
|
||||
ok 15 - R3: a user thread run cannot message the owner, while its uncited gated raise reaches only the owner inbox, B9
|
||||
---
|
||||
duration_ms: 20.248033
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a removed or expired grant refuses the next request access-revoked, and the file is read per request
|
||||
ok 16 - R3: a removed or expired grant refuses the next request access-revoked, and the file is read per request
|
||||
---
|
||||
duration_ms: 18.534911
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a user refusal is recorded as action.refused by user:<id>
|
||||
ok 17 - R3: a user refusal is recorded as action.refused by user:<id>
|
||||
---
|
||||
duration_ms: 13.664712
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: a business with a role keyed user refuses invalid-business
|
||||
ok 18 - R3: a business with a role keyed user refuses invalid-business
|
||||
---
|
||||
duration_ms: 9.426995
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3: name.set refuses the name user
|
||||
ok 19 - R3: name.set refuses the name user
|
||||
---
|
||||
duration_ms: 10.045778
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: while halted, a granted user's thread.send refuses processing-halted and thread.messages still answers
|
||||
ok 20 - R3 r4: while halted, a granted user's thread.send refuses processing-halted and thread.messages still answers
|
||||
---
|
||||
duration_ms: 13.715167
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: the chief's hire refuses an instance named user with the code it gives human and tester
|
||||
ok 21 - R3 r4: the chief's hire refuses an instance named user with the code it gives human and tester
|
||||
---
|
||||
duration_ms: 14.879652
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: R3 r4: a non-function access throws before the store is read
|
||||
ok 22 - R3 r4: a non-function access throws before the store is read
|
||||
---
|
||||
duration_ms: 0.118911
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
ok 23 - C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
---
|
||||
duration_ms: 16.011863
|
||||
type: 'test'
|
||||
...
|
||||
1..23
|
||||
# tests 23
|
||||
# suites 0
|
||||
# pass 23
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 546.253182
|
||||
@@ -0,0 +1,231 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-04: launcher workspace clones code but never the library
|
||||
ok 1 - C2-04: launcher workspace clones code but never the library
|
||||
---
|
||||
duration_ms: 1406.523375
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest
|
||||
ok 2 - bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest
|
||||
---
|
||||
duration_ms: 1320.670671
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r3012fd8ab4ab","instance":"chief","turn":"6ed30efc-4fea-4331-ba08-46f0a1dc9a41","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r00eaf5e634a6","instance":"coder","turn":"10861190-6c32-41eb-93b4-29b0a5dd8c00","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code
|
||||
ok 3 - the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code
|
||||
---
|
||||
duration_ms: 730.802466
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r1fd25c512b27","instance":"chief","turn":"cec8f880-bf75-4659-8da8-ed89c1dbf6e9","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r21039fe49a81","instance":"pm","turn":"eaa555de-47cd-41f1-8f03-56b33e8a74bd","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r1fd25c512b27","instance":"chief","turn":"4229d602-cd6b-4750-bf5b-b323b8a6f858","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r1fd25c512b27","instance":"chief","turn":"954dca21-de1b-4976-93c6-84f21c2dbd09","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r21039fe49a81","instance":"pm","turn":"ab644a01-0890-425c-92ad-b29a72ad01ed","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r21039fe49a81","instance":"pm","turn":"f63766ea-00f5-46aa-9c1c-4efd8d9e707b","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r1fd25c512b27","instance":"chief","turn":"c621466f-f3c9-4e9b-b41a-f4c8dc8fb5f8","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r21039fe49a81","instance":"pm","turn":"bedfe37d-d6ed-4461-82a3-f5dda0a0373a","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r1fd25c512b27","instance":"chief","turn":"03c5fd16-fd6d-47ea-84c1-b6845607ce0e","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold
|
||||
ok 4 - a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold
|
||||
---
|
||||
duration_ms: 1051.54464
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged
|
||||
ok 5 - each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged
|
||||
---
|
||||
duration_ms: 4090.531559
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none
|
||||
ok 6 - a role the broker says holds a merge decision gets land_work, its prompt line, its landing and the git socket; without it, none
|
||||
---
|
||||
duration_ms: 618.874624
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 7 - 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
|
||||
---
|
||||
duration_ms: 412.969873
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rea675e77cc9a","instance":"coder","turn":"454996a2-5763-466b-ac34-1a35df60907a","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: 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
|
||||
ok 8 - 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
|
||||
---
|
||||
duration_ms: 701.16635
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder
|
||||
ok 9 - a landing run that ended isn't started again for its decision, a spent decision starts nothing, and a new decision starts the holder
|
||||
---
|
||||
duration_ms: 629.761324
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: after a restart, the new host's first tick starts a holder whose decision is still held
|
||||
ok 10 - after a restart, the new host's first tick starts a holder whose decision is still held
|
||||
---
|
||||
duration_ms: 943.001139
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 11 - 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
|
||||
---
|
||||
duration_ms: 631.166574
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left
|
||||
ok 12 - a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left
|
||||
---
|
||||
duration_ms: 270.930737
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner that stops at once ends its launch with the runner's reason
|
||||
ok 13 - a runner that stops at once ends its launch with the runner's reason
|
||||
---
|
||||
duration_ms: 339.61276
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a Claude Code launch with no session credential refuses before it starts
|
||||
ok 14 - a Claude Code launch with no session credential refuses before it starts
|
||||
---
|
||||
duration_ms: 192.912776
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables
|
||||
ok 15 - a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables
|
||||
---
|
||||
duration_ms: 326.23852
|
||||
type: 'test'
|
||||
...
|
||||
# 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":[]}
|
||||
# Subtest: row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason
|
||||
ok 16 - row 65 a failed primary preflight launches the fallback on a fixture harness module, recording the route and the reason
|
||||
---
|
||||
duration_ms: 367.29797
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner killed from the host ends its launch as killed, not failed
|
||||
ok 17 - a runner killed from the host ends its launch as killed, not failed
|
||||
---
|
||||
duration_ms: 385.709039
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback
|
||||
ok 18 - a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback
|
||||
---
|
||||
duration_ms: 221.250023
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 19 - 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
|
||||
---
|
||||
duration_ms: 196.084738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason
|
||||
ok 20 - row 213 a creative instance's persona is read from <configDir>/personas: off its digest the launch fails with the mismatch as its reason
|
||||
---
|
||||
duration_ms: 262.645812
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts
|
||||
ok 21 - row 64 on Claude Code a role skill that isn't enabled refuses the same way, before anything starts
|
||||
---
|
||||
duration_ms: 192.972319
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r2d40ff6b8e4c","instance":"chief","turn":"fb22ae27-5633-49ee-8f68-c28e9216b756","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r2d40ff6b8e4c","instance":"chief","turn":"c1b15a96-c3e4-4937-ac09-5c7e34d31403","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r02b5676e3507","instance":"coder","turn":"0638932a-c3d1-405f-b6c9-f507dd774f5f","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold
|
||||
ok 22 - a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold
|
||||
---
|
||||
duration_ms: 1637.361775
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 23 - 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
|
||||
---
|
||||
duration_ms: 1055.418634
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 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
|
||||
ok 24 - 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
|
||||
---
|
||||
duration_ms: 4026.232693
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was
|
||||
ok 25 - bus start --no-launch leaves an earlier host's live session alone: no signal, no end, sessions.json as it was
|
||||
---
|
||||
duration_ms: 281.474074
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned
|
||||
ok 26 - bus start --no-launch refuses every launch: the PM launch and a session's request, each logged, nothing spawned
|
||||
---
|
||||
duration_ms: 205.160468
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bus start --no-launch starts no thread tick; the same host with launches runs it
|
||||
ok 27 - bus start --no-launch starts no thread tick; the same host with launches runs it
|
||||
---
|
||||
duration_ms: 1177.367351
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a malformed sessions.json refuses the host start with exit 3 and stays as it was
|
||||
ok 28 - a malformed sessions.json refuses the host start with exit 3 and stays as it was
|
||||
---
|
||||
duration_ms: 173.025482
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an over-long launch request is refused at once, not at the 10 s idle timeout
|
||||
ok 29 - an over-long launch request is refused at once, not at the 10 s idle timeout
|
||||
---
|
||||
duration_ms: 179.463604
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a launch client that never closes its side doesn't hold the host's close
|
||||
ok 30 - a launch client that never closes its side doesn't hold the host's close
|
||||
---
|
||||
duration_ms: 183.930813
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner that ignores SIGTERM is killed when the host closes
|
||||
ok 31 - a runner that ignores SIGTERM is killed when the host closes
|
||||
---
|
||||
duration_ms: 1356.296508
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: kill switch refuses chief and hire before launch work and a clear permits a later request
|
||||
ok 32 - kill switch refuses chief and hire before launch work and a clear permits a later request
|
||||
---
|
||||
duration_ms: 321.746898
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle
|
||||
ok 33 - kill switch stops an actual managed namespace and records the halt reason without rewriting its bundle
|
||||
---
|
||||
duration_ms: 329.710571
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a launch waiting across halt and resume cannot use its stale admission
|
||||
ok 34 - a launch waiting across halt and resume cannot use its stale admission
|
||||
---
|
||||
duration_ms: 190.011569
|
||||
type: 'test'
|
||||
...
|
||||
1..34
|
||||
# tests 34
|
||||
# suites 0
|
||||
# pass 34
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 26525.391292
|
||||
@@ -0,0 +1,113 @@
|
||||
TAP version 13
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd9fe94c6a93c","instance":"assistant","turn":"acdd17ee-d9c0-41c9-9b18-03f0e4d7ccf1","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r488a73e7e21c","instance":"assistant","turn":"f40d47d4-d3e4-4ed8-9155-e3d28385a4f0","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r62e991ccbe40","instance":"assistant","turn":"5a93737f-88ea-4a36-a8df-d5af7c5c727f","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rab07b97c6b59","instance":"assistant","turn":"c366ee9b-47bc-41eb-89a5-6cdac996498e","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it
|
||||
ok 1 - REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it
|
||||
---
|
||||
duration_ms: 5863.212229
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r8f921b27b736","instance":"assistant","turn":"960a3503-f2d2-4683-9b36-24dbfa43d9a8","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r2c17b223cf58","instance":"assistant","turn":"a2dec2ed-2ce7-4278-b023-d8a1eac619f0","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't
|
||||
ok 2 - REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't
|
||||
---
|
||||
duration_ms: 1699.456613
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"ra7fc0a5e5087","instance":"assistant","turn":"e201b1b5-2e0c-4893-869f-e3c822d486e9","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it
|
||||
ok 3 - REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it
|
||||
---
|
||||
duration_ms: 4443.468494
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r25b13eb6e839","instance":"assistant","turn":"4b84a129-4452-48a3-9c82-8e847b026b42","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r25b13eb6e839","instance":"assistant","turn":"ca697e50-5aa6-4ecf-ab5f-0180f39671d8","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it
|
||||
ok 4 - REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it
|
||||
---
|
||||
duration_ms: 2906.555821
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session
|
||||
ok 5 - REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session
|
||||
---
|
||||
duration_ms: 77.448744
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rc92eb2ad48fb","instance":"assistant","turn":"86c5dc34-0018-468b-945d-cdde7c07cc1f","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: REQ-LAUNCH-1 a thread run's session file has no landing, even when landHolders names its instance
|
||||
ok 6 - REQ-LAUNCH-1 a thread run's session file has no landing, even when landHolders names its instance
|
||||
---
|
||||
duration_ms: 373.463679
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message
|
||||
ok 7 - REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message
|
||||
---
|
||||
duration_ms: 220.418034
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing
|
||||
ok 8 - REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing
|
||||
---
|
||||
duration_ms: 218.661261
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread
|
||||
ok 9 - REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread
|
||||
---
|
||||
duration_ms: 77.033197
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a: fromSession refuses a creative instance outside a thread without a sandbox
|
||||
ok 10 - C2-09a: fromSession refuses a creative instance outside a thread without a sandbox
|
||||
---
|
||||
duration_ms: 74.007967
|
||||
type: 'test'
|
||||
...
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mayLaunch","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":0}
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mayLaunch","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":0}
|
||||
# Subtest: REQ-LIMIT-3 REQ-LIMIT-4 a thread start whose instance is at its token limit is refused, logged once with the limit and the count
|
||||
ok 11 - REQ-LIMIT-3 REQ-LIMIT-4 a thread start whose instance is at its token limit is refused, logged once with the limit and the count
|
||||
---
|
||||
duration_ms: 189.559346
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rb55b5fb42f65","instance":"assistant","turn":"1327e9e8-dbce-4d13-8d91-12224c10cc06","source":"@none","code":"baseline-unknown"}
|
||||
# limits: {"event":"limit-reached","business":"acme","check":"token-limit","export":"mustStop","subject":{"instance":"assistant","provider":"zai","model":"claude-sonnet-5-5","account":null},"path":["tokens","instances","assistant"],"limit":0,"count":0,"unknownTurns":1}
|
||||
# Subtest: REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn: the reply lands, and the end record names the limit
|
||||
ok 12 - REQ-LIMIT-4 a thread run at its token limit stops at the end of its turn: the reply lands, and the end record names the limit
|
||||
---
|
||||
duration_ms: 340.483797
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd4cf5ce21427","instance":"bean","turn":"27ddff31-caaa-4a9c-bda9-f36185b56dc9","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r890816a98bc2","instance":"chet","turn":"70137265-3ce6-434e-bd90-cef6fd12d283","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rd4cf5ce21427","instance":"bean","turn":"1d6ad2b2-d083-438a-b96f-e65ed3230da1","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
ok 13 - C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
---
|
||||
duration_ms: 743.366431
|
||||
type: 'test'
|
||||
...
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"rb4c5e063b74b","instance":"bean","turn":"66cf82d6-45bc-49ff-9916-e9a2092d9e64","source":"@none","code":"baseline-unknown"}
|
||||
# usage: {"event":"usage-unknown","business":"acme","run":"r6eef47e198ff","instance":"bean","turn":"357e8a93-e184-471e-803d-505682754bbc","source":"@none","code":"baseline-unknown"}
|
||||
# Subtest: C2-09a: terminating one creative thread does not signal an unselected peer of the same instance
|
||||
ok 14 - C2-09a: terminating one creative thread does not signal an unselected peer of the same instance
|
||||
---
|
||||
duration_ms: 646.331526
|
||||
type: 'test'
|
||||
...
|
||||
1..14
|
||||
# tests 14
|
||||
# suites 0
|
||||
# pass 14
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 17998.465895
|
||||
@@ -0,0 +1,94 @@
|
||||
TAP version 13
|
||||
# Subtest: chat browser: list/create named projects and threads, hostile labels inert and no implicit writes
|
||||
ok 1 - chat browser: list/create named projects and threads, hostile labels inert and no implicit writes
|
||||
---
|
||||
duration_ms: 706.684304
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: thread drafts, receipts and cursor history stay isolated; refresh never writes
|
||||
ok 2 - chat browser: thread drafts, receipts and cursor history stay isolated; refresh never writes
|
||||
---
|
||||
duration_ms: 699.638509
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: uncertain writes retain draft, ownership refusal clears it, read-only cannot send
|
||||
ok 3 - chat browser: uncertain writes retain draft, ownership refusal clears it, read-only cannot send
|
||||
---
|
||||
duration_ms: 667.019939
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a late read from A cannot paint B; sign-out clears private state and stops reads
|
||||
ok 4 - chat browser: a late read from A cannot paint B; sign-out clears private state and stops reads
|
||||
---
|
||||
duration_ms: 821.739159
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: page forward and deduplicate replies; pending and byte-limit submissions do not duplicate
|
||||
ok 5 - chat browser: page forward and deduplicate replies; pending and byte-limit submissions do not duplicate
|
||||
---
|
||||
duration_ms: 561.063862
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: scrolled history stays put, New messages and an own send return to the tail
|
||||
ok 6 - chat browser: scrolled history stays put, New messages and an own send return to the tail
|
||||
---
|
||||
duration_ms: 449.326852
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: automatic polling follows a reply without a POST or a lost draft
|
||||
ok 7 - chat browser: automatic polling follows a reply without a POST or a lost draft
|
||||
---
|
||||
duration_ms: 10598.338648
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: display stays bounded while every forward page remains reachable
|
||||
ok 8 - chat browser: display stays bounded while every forward page remains reachable
|
||||
---
|
||||
duration_ms: 688.844208
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a confirmed visible message replaces its pending receipt; malformed receipts stay unknown
|
||||
ok 9 - chat browser: a confirmed visible message replaces its pending receipt; malformed receipts stay unknown
|
||||
---
|
||||
duration_ms: 569.840106
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a refusal elsewhere forgets private chat drafts
|
||||
ok 10 - chat browser: a refusal elsewhere forgets private chat drafts
|
||||
---
|
||||
duration_ms: 578.081863
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat browser: a late project creation receipt cannot navigate away from another thread
|
||||
ok 11 - chat browser: a late project creation receipt cannot navigate away from another thread
|
||||
---
|
||||
duration_ms: 541.022347
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
ok 12 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 518.744602
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
ok 13 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 630.375708
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread
|
||||
ok 14 - C2-09a picker: a single instance is chosen explicitly but read-only mode cannot create a thread
|
||||
---
|
||||
duration_ms: 532.387548
|
||||
type: 'test'
|
||||
...
|
||||
1..14
|
||||
# tests 14
|
||||
# suites 0
|
||||
# pass 14
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 18670.357703
|
||||
@@ -0,0 +1,34 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 16.846446
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata uses the private tester listener own bus and no human transport
|
||||
ok 2 - C2-09a metadata uses the private tester listener own bus and no human transport
|
||||
---
|
||||
duration_ms: 2.896367
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields
|
||||
ok 3 - C2-09a metadata refuses missing or malformed reads and never echoes untrusted fields
|
||||
---
|
||||
duration_ms: 3.330037
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity
|
||||
ok 4 - C2-09a metadata stays behind the SSO session check and a GET never refreshes session activity
|
||||
---
|
||||
duration_ms: 2.085754
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
# tests 4
|
||||
# suites 0
|
||||
# pass 4
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 128.601956
|
||||
@@ -0,0 +1,160 @@
|
||||
TAP version 13
|
||||
# Subtest: chat reads map only fixed verbs, strict forward paging and pure GET
|
||||
ok 1 - chat reads map only fixed verbs, strict forward paging and pure GET
|
||||
---
|
||||
duration_ms: 22.1221
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat refuses malformed and repeated query/id values before transport
|
||||
ok 2 - chat refuses malformed and repeated query/id values before transport
|
||||
---
|
||||
duration_ms: 4.606275
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: one verified write, fixed identity/class and private log
|
||||
ok 3 - chat project.create: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 2.784213
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: each existing Console write fence makes zero bus calls
|
||||
ok 4 - chat project.create: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 6.747634
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat project.create: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 5 - chat project.create: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 3.56051
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: one verified write, fixed identity/class and private log
|
||||
ok 6 - chat thread.create: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 1.163659
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: each existing Console write fence makes zero bus calls
|
||||
ok 7 - chat thread.create: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 5.496457
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.create: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 8 - chat thread.create: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 3.893248
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: one verified write, fixed identity/class and private log
|
||||
ok 9 - chat thread.send: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 1.062409
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: each existing Console write fence makes zero bus calls
|
||||
ok 10 - chat thread.send: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 4.794857
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.send: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 11 - chat thread.send: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 2.739527
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: one verified write, fixed identity/class and private log
|
||||
ok 12 - chat thread.open: one verified write, fixed identity/class and private log
|
||||
---
|
||||
duration_ms: 0.96705
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: each existing Console write fence makes zero bus calls
|
||||
ok 13 - chat thread.open: each existing Console write fence makes zero bus calls
|
||||
---
|
||||
duration_ms: 6.409182
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat thread.open: refusal or lost/malformed receipt never retries or invents success
|
||||
ok 14 - chat thread.open: refusal or lost/malformed receipt never retries or invents success
|
||||
---
|
||||
duration_ms: 4.54952
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat createThread receipt requires an instance even when its id is valid
|
||||
ok 15 - chat createThread receipt requires an instance even when its id is valid
|
||||
---
|
||||
duration_ms: 1.948475
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat write receipts expose only the fields belonging to their operation
|
||||
ok 16 - chat write receipts expose only the fields belonging to their operation
|
||||
---
|
||||
duration_ms: 3.039253
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat validates names, body, project and strict empty open payload
|
||||
ok 17 - chat validates names, body, project and strict empty open payload
|
||||
---
|
||||
duration_ms: 3.332596
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat read failures redact ownership and refuse invalid transport arrays
|
||||
ok 18 - chat read failures redact ownership and refuse invalid transport arrays
|
||||
---
|
||||
duration_ms: 3.252877
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-USER-2 real broker: owned catalog, create/name/filter, isolated history and 403/404 without mutations
|
||||
ok 19 - REQ-USER-2 real broker: owned catalog, create/name/filter, isolated history and 403/404 without mutations
|
||||
---
|
||||
duration_ms: 84.521895
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat repeats every POST boundary even when called behind an admitted request
|
||||
ok 20 - chat repeats every POST boundary even when called behind an admitted request
|
||||
---
|
||||
duration_ms: 0.894693
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: configured Console process injects chat through its existing human transport
|
||||
ok 21 - configured Console process injects chat through its existing human transport
|
||||
---
|
||||
duration_ms: 130.200727
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chat assets, GET purity, method and unknown-route refusals are explicit
|
||||
ok 22 - chat assets, GET purity, method and unknown-route refusals are explicit
|
||||
---
|
||||
duration_ms: 11.59045
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the chat seam names the transport it is given: the human one and the tester one both pass, anything else is a TypeError
|
||||
ok 23 - the chat seam names the transport it is given: the human one and the tester one both pass, anything else is a TypeError
|
||||
---
|
||||
duration_ms: 0.423449
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a createThread forwards an explicit instance through the existing channel
|
||||
ok 24 - C2-09a createThread forwards an explicit instance through the existing channel
|
||||
---
|
||||
duration_ms: 3.442281
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
ok 25 - C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
---
|
||||
duration_ms: 2.896034
|
||||
type: 'test'
|
||||
...
|
||||
1..25
|
||||
# tests 25
|
||||
# suites 0
|
||||
# pass 25
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 425.227286
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"node": {
|
||||
"tests": 2509,
|
||||
"pass": 2507,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 2
|
||||
},
|
||||
"shells": [
|
||||
{
|
||||
"label": "test-auth",
|
||||
"passed": 15,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-conductor",
|
||||
"passed": 17,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-config",
|
||||
"passed": 55,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-discord",
|
||||
"passed": 81,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-extension-package",
|
||||
"passed": 18,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-foundation",
|
||||
"passed": 44,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-land-work",
|
||||
"passed": 86,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": []
|
||||
},
|
||||
{
|
||||
"label": "test-queue",
|
||||
"passed": 28,
|
||||
"failed": 0,
|
||||
"exit": 0,
|
||||
"skips": [
|
||||
"skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "test-release",
|
||||
"passed": 11,
|
||||
"failed": 3,
|
||||
"exit": 1,
|
||||
"skips": []
|
||||
}
|
||||
],
|
||||
"shellPassed": 355,
|
||||
"shellFailed": 3,
|
||||
"unrun": [
|
||||
"test-task",
|
||||
"24 mutants",
|
||||
"final reader audit"
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,916 @@
|
||||
TAP version 13
|
||||
# Subtest: sessionModel: the route is the instance's own vars, and a missing one refuses no-route by name
|
||||
ok 1 - sessionModel: the route is the instance's own vars, and a missing one refuses no-route by name
|
||||
---
|
||||
duration_ms: 33.874129
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory
|
||||
ok 2 - a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory
|
||||
---
|
||||
duration_ms: 8.467453
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools
|
||||
ok 3 - a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools
|
||||
---
|
||||
duration_ms: 3.96755
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a chief-of-staff bundle lists end_run, change_organization and set_name as typed and nothing untyped, for either harness
|
||||
ok 4 - a chief-of-staff bundle lists end_run, change_organization and set_name as typed and nothing untyped, for either harness
|
||||
---
|
||||
duration_ms: 5.695693
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the stop line names end_run for a role.end holder, and every other role keeps today's text
|
||||
ok 5 - the stop line names end_run for a role.end holder, and every other role keeps today's text
|
||||
---
|
||||
duration_ms: 14.125465
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a claude-code bundle adds the wrapped gate hook and the MCP config
|
||||
ok 6 - a claude-code bundle adds the wrapped gate hook and the MCP config
|
||||
---
|
||||
duration_ms: 4.987674
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt's built-in tools line is the harness's own names, as the manifest lists them
|
||||
ok 7 - the prompt's built-in tools line is the harness's own names, as the manifest lists them
|
||||
---
|
||||
duration_ms: 18.692534
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt names the project clones in the workspace, and none when there are none
|
||||
ok 8 - the prompt names the project clones in the workspace, and none when there are none
|
||||
---
|
||||
duration_ms: 14.927989
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review
|
||||
ok 9 - the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review
|
||||
---
|
||||
duration_ms: 15.928932
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt explains landing to a role with land_work, and to no other
|
||||
ok 10 - the prompt explains landing to a role with land_work, and to no other
|
||||
---
|
||||
duration_ms: 8.166314
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the prompt tells the pm to ask the chief of staff for sessions, and no other role
|
||||
ok 11 - the prompt tells the pm to ask the chief of staff for sessions, and no other role
|
||||
---
|
||||
duration_ms: 16.315049
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a bundle is written once: an existing file refuses
|
||||
ok 12 - a bundle is written once: an existing file refuses
|
||||
---
|
||||
duration_ms: 3.472529
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a path with a single quote can't go into the hook command
|
||||
ok 13 - a path with a single quote can't go into the hook command
|
||||
---
|
||||
duration_ms: 3.232429
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
ok 14 - web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
---
|
||||
duration_ms: 4.782236
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no web grant on pi: no web tool in the bundle, and the gate blocks a web call
|
||||
ok 15 - no web grant on pi: no web tool in the bundle, and the gate blocks a web call
|
||||
---
|
||||
duration_ms: 6.580906
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
ok 16 - web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool
|
||||
---
|
||||
duration_ms: 3.769295
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call
|
||||
ok 17 - no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call
|
||||
---
|
||||
duration_ms: 3.619003
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a granted session's gate lets the typed web tools through and still blocks the built-ins
|
||||
ok 18 - a granted session's gate lets the typed web tools through and still blocks the built-ins
|
||||
---
|
||||
duration_ms: 4.175596
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
ok 19 - search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
---
|
||||
duration_ms: 11.248706
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
ok 20 - search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing
|
||||
---
|
||||
duration_ms: 10.139734
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted
|
||||
ok 21 - search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted
|
||||
---
|
||||
duration_ms: 9.532167
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: search-source harness-builtin is refused for a granted pi role, which has no built-in web tool
|
||||
ok 22 - search-source harness-builtin is refused for a granted pi role, which has no built-in web tool
|
||||
---
|
||||
duration_ms: 3.6275
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: allow exits 0, a deny exits 2 with the reason on stderr
|
||||
ok 23 - allow exits 0, a deny exits 2 with the reason on stderr
|
||||
---
|
||||
duration_ms: 188.002461
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or wrong policy, or a bad event, exits 2
|
||||
ok 24 - a missing or wrong policy, or a bad event, exits 2
|
||||
---
|
||||
duration_ms: 103.629156
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bundle's wrapped command: a missing gate or node still blocks
|
||||
ok 25 - the bundle's wrapped command: a missing gate or node still blocks
|
||||
---
|
||||
duration_ms: 1105.742163
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 26 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 951.625174
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 27 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 542.468659
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 28 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 937.521882
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 29 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.926388
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 30 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 17.263685
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 31 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.895812
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
ok 32 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 880.142974
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 33 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.959808
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 34 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1769.308084
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 35 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 877.553016
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M2: the gate refuses write, edit and bash to every creative role on pi and claude-code
|
||||
ok 36 - M2: the gate refuses write, edit and bash to every creative role on pi and claude-code
|
||||
---
|
||||
duration_ms: 58.288959
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: M6: no creative session gets raise_decision; the assistant and the chief of staff keep it
|
||||
ok 37 - M6: no creative session gets raise_decision; the assistant and the chief of staff keep it
|
||||
---
|
||||
duration_ms: 25.28371
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web: research and companion get the broker's typed web tools, and a harness-builtin source refuses web-source-not-allowed
|
||||
ok 38 - web: research and companion get the broker's typed web tools, and a harness-builtin source refuses web-source-not-allowed
|
||||
---
|
||||
duration_ms: 32.627529
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: persona: the block sits between the contract and \#\# This session, fenced, with the name and digest
|
||||
ok 39 - persona: the block sits between the contract and \#\# This session, fenced, with the name and digest
|
||||
---
|
||||
duration_ms: 8.81196
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: persona: each unsafe or unpinned file refuses before the bundle directory is made
|
||||
ok 40 - persona: each unsafe or unpinned file refuses before the bundle directory is made
|
||||
---
|
||||
duration_ms: 29.064281
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: adapters pass the prompt file's absolute path; the persona and the prompt text never sit in argv
|
||||
ok 41 - adapters pass the prompt file's absolute path; the persona and the prompt text never sit in argv
|
||||
---
|
||||
duration_ms: 37.501659
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the pi adapter refuses a missing, unreadable or directory prompt file before pi starts
|
||||
ok 42 - the pi adapter refuses a missing, unreadable or directory prompt file before pi starts
|
||||
---
|
||||
duration_ms: 11.744855
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: policy tools and typed tools pass, anything else is blocked
|
||||
ok 43 - pi: policy tools and typed tools pass, anything else is blocked
|
||||
---
|
||||
duration_ms: 4.339988
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: builtins map from pi names, typed tools need the mcp prefix
|
||||
ok 44 - claude: builtins map from pi names, typed tools need the mcp prefix
|
||||
---
|
||||
duration_ms: 1.245674
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: file tool paths must resolve inside the workspace
|
||||
ok 45 - file tool paths must resolve inside the workspace
|
||||
---
|
||||
duration_ms: 1.977493
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi's own path normalisation can't be used to step out
|
||||
ok 46 - pi's own path normalisation can't be used to step out
|
||||
---
|
||||
duration_ms: 2.797769
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a symlink inside the workspace that points out is outside
|
||||
ok 47 - a symlink inside the workspace that points out is outside
|
||||
---
|
||||
duration_ms: 1.172457
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a dangling symlink is refused at any depth, in both harnesses
|
||||
ok 48 - a dangling symlink is refused at any depth, in both harnesses
|
||||
---
|
||||
duration_ms: 4.665439
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: read is checked under every spelling pi's read would open, in both harnesses
|
||||
ok 49 - read is checked under every spelling pi's read would open, in both harnesses
|
||||
---
|
||||
duration_ms: 25.330584
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: other spellings cover directories, dangling links and pi's cwd
|
||||
ok 50 - other spellings cover directories, dangling links and pi's cwd
|
||||
---
|
||||
duration_ms: 2.633565
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a relative path climbs from the workspace's real path, in both harnesses
|
||||
ok 51 - a relative path climbs from the workspace's real path, in both harnesses
|
||||
---
|
||||
duration_ms: 8.552688
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude path fields per tool
|
||||
ok 52 - claude path fields per tool
|
||||
---
|
||||
duration_ms: 1.078208
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: glob patterns stay inside the workspace
|
||||
ok 53 - glob patterns stay inside the workspace
|
||||
---
|
||||
duration_ms: 1.015431
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a path that can't be checked is blocked
|
||||
ok 54 - a path that can't be checked is blocked
|
||||
---
|
||||
duration_ms: 0.497114
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX
|
||||
ok 55 - fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX
|
||||
---
|
||||
duration_ms: 315.138858
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: fetch_review's have orders the working refs newest first within each clone, one clone after another
|
||||
ok 56 - fetch_review's have orders the working refs newest first within each clone, one clone after another
|
||||
---
|
||||
duration_ms: 149.700401
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period
|
||||
ok 57 - a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period
|
||||
---
|
||||
duration_ms: 1809.591642
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too
|
||||
ok 58 - once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too
|
||||
---
|
||||
duration_ms: 302.932534
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: land_work sends one land line and resolves the host's started answer
|
||||
ok 59 - land_work sends one land line and resolves the host's started answer
|
||||
---
|
||||
duration_ms: 4.001511
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: initialize, ping and tools/list
|
||||
ok 60 - initialize, ping and tools/list
|
||||
---
|
||||
duration_ms: 74.132597
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: tools/call goes through the tool socket; a refusal is an isError result
|
||||
ok 61 - tools/call goes through the tool socket; a refusal is an isError result
|
||||
---
|
||||
duration_ms: 62.808126
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: replies are compact JSON; over the cap a tool error names the size and the cap
|
||||
ok 62 - replies are compact JSON; over the cap a tool error names the size and the cap
|
||||
---
|
||||
duration_ms: 58.11207
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: unknown tools and methods are JSON-RPC errors and never reach the socket
|
||||
ok 63 - unknown tools and methods are JSON-RPC errors and never reach the socket
|
||||
---
|
||||
duration_ms: 39.258122
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing argument is a usage error
|
||||
ok 64 - a missing argument is a usage error
|
||||
---
|
||||
duration_ms: 34.820111
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: typed tools reach the socket, the gate blocks, agent_end writes the marker
|
||||
ok 65 - pi: typed tools reach the socket, the gate blocks, agent_end writes the marker
|
||||
---
|
||||
duration_ms: 606.423339
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks
|
||||
ok 66 - pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks
|
||||
---
|
||||
duration_ms: 480.797888
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a write through a dangling symlink is blocked, and nothing appears outside
|
||||
ok 67 - pi: a write through a dangling symlink is blocked, and nothing appears outside
|
||||
---
|
||||
duration_ms: 482.616253
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a read is refused when pi would open another spelling outside
|
||||
ok 68 - pi: a read is refused when pi would open another spelling outside
|
||||
---
|
||||
duration_ms: 487.073693
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a relative path climbs from the real path of a workspace behind a symlink
|
||||
ok 69 - pi: a relative path climbs from the real path of a workspace behind a symlink
|
||||
---
|
||||
duration_ms: 470.344115
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a relative path climbs from the real path of a dataRoot behind a symlink
|
||||
ok 70 - pi: a relative path climbs from the real path of a dataRoot behind a symlink
|
||||
---
|
||||
duration_ms: 433.687877
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: a missing extension refuses before any model call
|
||||
ok 71 - pi: a missing extension refuses before any model call
|
||||
---
|
||||
duration_ms: 6.469015
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: an extension without its configuration fails pi's start
|
||||
ok 72 - pi: an extension without its configuration fails pi's start
|
||||
---
|
||||
duration_ms: 388.371394
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 73 - pi: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1324.20464
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: pi: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 74 - pi: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 739.601215
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: raise_decision offers domain as technical or delivery only, optional, and says where a raise goes
|
||||
ok 75 - raise_decision offers domain as technical or delivery only, optional, and says where a raise goes
|
||||
---
|
||||
duration_ms: 22.046969
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: raise_decision forwards domain to decision.raise, and a call without it sends none
|
||||
ok 76 - raise_decision forwards domain to decision.raise, and a call without it sends none
|
||||
---
|
||||
duration_ms: 91.610922
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: founderCheck: founder variables, then a needed service without a usable token
|
||||
ok 77 - founderCheck: founder variables, then a needed service without a usable token
|
||||
---
|
||||
duration_ms: 2.121163
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest names the sender, class, reply and decision
|
||||
ok 78 - turnRequest names the sender, class, reply and decision
|
||||
---
|
||||
duration_ms: 0.320665
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest says a tester's message is a test and never Jason's instruction
|
||||
ok 79 - turnRequest says a tester's message is a test and never Jason's instruction
|
||||
---
|
||||
duration_ms: 0.414139
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest says a user's message is a granted user's and never the owner's instruction
|
||||
ok 80 - turnRequest says a user's message is a granted user's and never the owner's instruction
|
||||
---
|
||||
duration_ms: 0.292892
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: turnRequest shows the message's own sent time, a day old as well as new
|
||||
ok 81 - turnRequest shows the message's own sent time, a day old as well as new
|
||||
---
|
||||
duration_ms: 0.26369
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: stateBlock names the launch state with its time and event, and the open tasks with the cap
|
||||
ok 82 - stateBlock names the launch state with its time and event, and the open tasks with the cap
|
||||
---
|
||||
duration_ms: 0.458904
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0
|
||||
ok 83 - a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0
|
||||
---
|
||||
duration_ms: 276.929759
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: launches revoked and then restored: the turn's block reads allowed and gives the restore time
|
||||
ok 84 - launches revoked and then restored: the turn's block reads allowed and gives the restore time
|
||||
---
|
||||
duration_ms: 235.804005
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a task closed on the tracker is missing from the next turn's open list
|
||||
ok 85 - a task closed on the tracker is missing from the next turn's open list
|
||||
---
|
||||
duration_ms: 228.852949
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a message read a day after it was sent shows the time it was sent
|
||||
ok 86 - a message read a day after it was sent shows the time it was sent
|
||||
---
|
||||
duration_ms: 143.314714
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a decision the human resolves becomes a turn citing the decision and the answer
|
||||
ok 87 - a decision the human resolves becomes a turn citing the decision and the answer
|
||||
---
|
||||
duration_ms: 193.160152
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a failed state read fails the turn: no adapter runs, the sender hears why, the message is read
|
||||
ok 88 - a failed state read fails the turn: no adapter runs, the sender hears why, the message is read
|
||||
---
|
||||
duration_ms: 92.267731
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a SIGTERM before the claim stops the runner with exit 0 and no claim
|
||||
ok 89 - a SIGTERM before the claim stops the runner with exit 0 and no claim
|
||||
---
|
||||
duration_ms: 90.850268
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: typed tools carry the runner's capability; launch goes to the host's launch socket
|
||||
ok 90 - typed tools carry the runner's capability; launch goes to the host's launch socket
|
||||
---
|
||||
duration_ms: 363.843789
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: end_run, organization_revision and change_organization reach the broker with the tool's arguments, and refusals keep their codes
|
||||
ok 91 - end_run, organization_revision and change_organization reach the broker with the tool's arguments, and refusals keep their codes
|
||||
---
|
||||
duration_ms: 429.453211
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: set_name reaches the broker's name.set with the tool's arguments, and refusals keep their codes
|
||||
ok 92 - set_name reaches the broker's name.set with the tool's arguments, and refusals keep their codes
|
||||
---
|
||||
duration_ms: 173.960254
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a RESULT gets no automatic reply; failed turns reply with the reason
|
||||
ok 93 - a RESULT gets no automatic reply; failed turns reply with the reason
|
||||
---
|
||||
duration_ms: 1237.450404
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bus's launch notice is one turn with no reply, and is not taken again
|
||||
ok 94 - the bus's launch notice is one turn with no reply, and is not taken again
|
||||
---
|
||||
duration_ms: 271.363823
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: SIGTERM during a turn kills the turn's process group and still exits 0
|
||||
ok 95 - SIGTERM during a turn kills the turn's process group and still exits 0
|
||||
---
|
||||
duration_ms: 119.278583
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: founder credentials stop before the claim (20)
|
||||
ok 96 - founder credentials stop before the claim (20)
|
||||
---
|
||||
duration_ms: 154.532734
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a refused claim exits 21; an ended run's capability exits 22
|
||||
ok 97 - a refused claim exits 21; an ended run's capability exits 22
|
||||
---
|
||||
duration_ms: 156.994628
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the launch ending under a running session exits 22
|
||||
ok 98 - the launch ending under a running session exits 22
|
||||
---
|
||||
duration_ms: 129.961066
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a broker that stays unreachable exits 23 after brokerRetries polls
|
||||
ok 99 - a broker that stays unreachable exits 23 after brokerRetries polls
|
||||
---
|
||||
duration_ms: 229.871224
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a broker that is down at the claim exits 23, not 21
|
||||
ok 100 - a broker that is down at the claim exits 23, not 21
|
||||
---
|
||||
duration_ms: 71.761313
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no capability, or a malformed one, on stdin exits 2
|
||||
ok 101 - no capability, or a malformed one, on stdin exits 2
|
||||
---
|
||||
duration_ms: 189.814923
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a missing or malformed policy exits 2 before the claim
|
||||
ok 102 - a missing or malformed policy exits 2 before the claim
|
||||
---
|
||||
duration_ms: 115.720449
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LIMIT-4 runner brackets its actual harness turn before the reply and read receipt
|
||||
ok 103 - REQ-LIMIT-4 runner brackets its actual harness turn before the reply and read receipt
|
||||
---
|
||||
duration_ms: 166.881927
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: REQ-LIMIT-4 a runner at its limit stops at the end of its turn: RESULT and read first, then exit 22 and a limit-check revoke
|
||||
ok 104 - REQ-LIMIT-4 a runner at its limit stops at the end of its turn: RESULT and read first, then exit 22 and a limit-check revoke
|
||||
---
|
||||
duration_ms: 182.191191
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: landingRequest is the fixed template, with the decision and task ref and nothing else
|
||||
ok 105 - landingRequest is the fixed template, with the decision and task ref and nothing else
|
||||
---
|
||||
duration_ms: 0.167667
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each landing entry is one turn before any message, with the state block and the fixed request; it sends nothing and reads nothing
|
||||
ok 106 - each landing entry is one turn before any message, with the state block and the fixed request; it sends nothing and reads nothing
|
||||
---
|
||||
duration_ms: 201.176324
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an empty landing takes no landing turn: the message is turn 1
|
||||
ok 107 - an empty landing takes no landing turn: the message is turn 1
|
||||
---
|
||||
duration_ms: 218.477916
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages
|
||||
ok 108 - a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages
|
||||
---
|
||||
duration_ms: 584.911338
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a malformed landing exits 2 before the claim, with no turn
|
||||
ok 109 - a malformed landing exits 2 before the claim, with no turn
|
||||
---
|
||||
duration_ms: 557.606738
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 65 a session.json without a turnEnd of marker or exit, or a harnessEnv of strings, exits 2 before the claim
|
||||
ok 110 - row 65 a session.json without a turnEnd of marker or exit, or a harnessEnv of strings, exits 2 before the claim
|
||||
---
|
||||
duration_ms: 256.156715
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 65 harnessEnv reaches the adapter, and an exit harness needs no turn marker
|
||||
ok 111 - row 65 harnessEnv reaches the adapter, and an exit harness needs no turn marker
|
||||
---
|
||||
duration_ms: 164.97969
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 the adapter gets the run's unslop log, and a flagged reply's note rides that reply's RESULT, once
|
||||
ok 112 - row 66 the adapter gets the run's unslop log, and a flagged reply's note rides that reply's RESULT, once
|
||||
---
|
||||
duration_ms: 296.421186
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a turn with no reply holds its note for the next reply; a broken check is told once
|
||||
ok 113 - row 66 a turn with no reply holds its note for the next reply; a broken check is told once
|
||||
---
|
||||
duration_ms: 293.54634
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 unslopNotes keeps a note until sent(), reads only whole lines, and unslopCounts reads a log after the session
|
||||
ok 114 - row 66 unslopNotes keeps a note until sent(), reads only whole lines, and unslopCounts reads a log after the session
|
||||
---
|
||||
duration_ms: 1.554984
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a clipped answer with both note parts stays under the bus's body limit, and the note under 600
|
||||
ok 115 - row 66 a clipped answer with both note parts stays under the bus's body limit, and the note under 600
|
||||
---
|
||||
duration_ms: 163.649095
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: row 66 a refused send keeps the note: it rides the next RESULT the session sends
|
||||
ok 116 - row 66 a refused send keeps the note: it rides the next RESULT the session sends
|
||||
---
|
||||
duration_ms: 266.580145
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each repo role's prompt carries exactly its listed skills, each file as the bundle copy and the source
|
||||
ok 117 - each repo role's prompt carries exactly its listed skills, each file as the bundle copy and the source
|
||||
---
|
||||
duration_ms: 61.768064
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill's files go into the prompt in sorted path order, sub-directories included
|
||||
ok 118 - a skill's files go into the prompt in sorted path order, sub-directories included
|
||||
---
|
||||
duration_ms: 8.52293
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role with no skills gets no Skills section, no skills directory and an empty manifest list
|
||||
ok 119 - a role with no skills gets no Skills section, no skills directory and an empty manifest list
|
||||
---
|
||||
duration_ms: 9.561171
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an enabled skill the role doesn't list stays out of the prompt
|
||||
ok 120 - an enabled skill the role doesn't list stays out of the prompt
|
||||
---
|
||||
duration_ms: 9.546384
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the bundle copy outlives the source: deactivating a skill after the build leaves the run's copy
|
||||
ok 121 - the bundle copy outlives the source: deactivating a skill after the build leaves the run's copy
|
||||
---
|
||||
duration_ms: 4.333461
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a listed skill that isn't enabled refuses skill-not-enabled, naming the activate command
|
||||
ok 122 - a listed skill that isn't enabled refuses skill-not-enabled, naming the activate command
|
||||
---
|
||||
duration_ms: 8.795891
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill directory that isn't plain refuses: a symlinked skill, SKILL.md or sub-file, or a non-file entry
|
||||
ok 123 - a skill directory that isn't plain refuses: a symlinked skill, SKILL.md or sub-file, or a non-file entry
|
||||
---
|
||||
duration_ms: 2.555487
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a skill file that can't go into the prompt refuses: a bad name, non-UTF-8 bytes, or the end marker
|
||||
ok 124 - a skill file that can't go into the prompt refuses: a bad name, non-UTF-8 bytes, or the end marker
|
||||
---
|
||||
duration_ms: 5.208875
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role's skills over SKILL_BYTES together refuse, naming the skill that crossed it
|
||||
ok 125 - a role's skills over SKILL_BYTES together refuse, naming the skill that crossed it
|
||||
---
|
||||
duration_ms: 9.876759
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: each adapter passes the skills only in the prompt file, with skill discovery off
|
||||
ok 126 - each adapter passes the skills only in the prompt file, with skill discovery off
|
||||
---
|
||||
duration_ms: 43.788426
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: every role sees read_spec, record writer follows its grant, citation schemas stay strict
|
||||
ok 127 - every role sees read_spec, record writer follows its grant, citation schemas stay strict
|
||||
---
|
||||
duration_ms: 25.139634
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: typed socket forwards read content/history and agent record writes, and cannot write a spec
|
||||
ok 128 - typed socket forwards read content/history and agent record writes, and cannot write a spec
|
||||
---
|
||||
duration_ms: 144.347507
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the PM gets its task verbs and the reads, and no launch
|
||||
ok 129 - the PM gets its task verbs and the reads, and no launch
|
||||
---
|
||||
duration_ms: 13.582778
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: send_message offers the BLOCK class, beside the classes it already had
|
||||
ok 130 - send_message offers the BLOCK class, beside the classes it already had
|
||||
---
|
||||
duration_ms: 3.430334
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the chief of staff gets launch, send_message, end_run, hire, fire, change_organization and set_name, and no task verbs
|
||||
ok 131 - the chief of staff gets launch, send_message, end_run, hire, fire, change_organization and set_name, and no task verbs
|
||||
---
|
||||
duration_ms: 3.40306
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: hire and fire send instance.hire and instance.fire under role.hire and role.fire, only for a holder of the grant
|
||||
ok 132 - hire and fire send instance.hire and instance.fire under role.hire and role.fire, only for a holder of the grant
|
||||
---
|
||||
duration_ms: 23.265588
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: request_staff is the pm's alone: staff.request over message.send, roles and counts bounded
|
||||
ok 133 - request_staff is the pm's alone: staff.request over message.send, roles and counts bounded
|
||||
---
|
||||
duration_ms: 14.641248
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: end_run sends role and reason, no decision; change_organization sends revision and the organization keys
|
||||
ok 134 - end_run sends role and reason, no decision; change_organization sends revision and the organization keys
|
||||
---
|
||||
duration_ms: 2.502036
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: set_name sends instance and name to name.set under instance.name, only for a holder of that grant
|
||||
ok 135 - set_name sends instance and name to name.set under instance.name, only for a holder of that grant
|
||||
---
|
||||
duration_ms: 12.229717
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the organization keys change_organization takes are the broker's ORGANIZATION_KEYS and the settings' SETTINGS_KEYS
|
||||
ok 136 - the organization keys change_organization takes are the broker's ORGANIZATION_KEYS and the settings' SETTINGS_KEYS
|
||||
---
|
||||
duration_ms: 0.143959
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a role without role.end or organization.change gets none of the three tools, and each follows its own grant
|
||||
ok 137 - a role without role.end or organization.change gets none of the three tools, and each follows its own grant
|
||||
---
|
||||
duration_ms: 10.841024
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: no role's tools send instances or instances.set, and change_organization takes no instance write keys
|
||||
ok 138 - no role's tools send instances or instances.set, and change_organization takes no instance write keys
|
||||
---
|
||||
duration_ms: 10.300174
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch
|
||||
ok 139 - the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch
|
||||
---
|
||||
duration_ms: 2.183569
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: list_requirements reads the requirement ids, for a task.create holder with a tracker
|
||||
ok 140 - list_requirements reads the requirement ids, for a task.create holder with a tracker
|
||||
---
|
||||
duration_ms: 5.950375
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a coder gets no launch, no resolve_decision, and no task tools without a tracker
|
||||
ok 141 - a coder gets no launch, no resolve_decision, and no task tools without a tracker
|
||||
---
|
||||
duration_ms: 2.026542
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a coder with a tracker gets its own task tools and no task_reassign
|
||||
ok 142 - a coder with a tracker gets its own task tools and no task_reassign
|
||||
---
|
||||
duration_ms: 2.142864
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: launch only when the business's launch block names the instance as launcher
|
||||
ok 143 - launch only when the business's launch block names the instance as launcher
|
||||
---
|
||||
duration_ms: 3.8985
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an action outside the instance's authority has no tool
|
||||
ok 144 - an action outside the instance's authority has no tool
|
||||
---
|
||||
duration_ms: 2.256397
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM
|
||||
ok 145 - the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM
|
||||
---
|
||||
duration_ms: 8.449366
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: land_work is there only with land, after push_working, with the task and the decision
|
||||
ok 146 - land_work is there only with land, after push_working, with the task and the decision
|
||||
---
|
||||
duration_ms: 4.262077
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: callTool: one JSON line out, the result back, a refusal rejects
|
||||
ok 147 - callTool: one JSON line out, the result back, a refusal rejects
|
||||
---
|
||||
duration_ms: 16.711113
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: list_tasks takes the broker's filters and pages; get_task takes a task_ref
|
||||
ok 148 - list_tasks takes the broker's filters and pages; get_task takes a task_ref
|
||||
---
|
||||
duration_ms: 3.972724
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: callTool sends list_tasks done false unless the session names done; other tools as given
|
||||
ok 149 - callTool sends list_tasks done false unless the session names done; other tools as given
|
||||
---
|
||||
duration_ms: 3.063645
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: replyText: compact JSON up to the cap, an error naming the size and the cap over it
|
||||
ok 150 - replyText: compact JSON up to the cap, an error naming the size and the cap over it
|
||||
---
|
||||
duration_ms: 0.915587
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS
|
||||
ok 151 - web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS
|
||||
---
|
||||
duration_ms: 3.3941
|
||||
type: 'test'
|
||||
...
|
||||
1..151
|
||||
# tests 151
|
||||
# suites 0
|
||||
# pass 151
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 12043.554653
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,17 @@
|
||||
OK status with missing harness credential exits 3 and still lists accounts
|
||||
OK status reports harness credential (read-only) + mosaic accounts
|
||||
OK api key material never reaches output
|
||||
OK oauth token material never reaches output
|
||||
OK unparseable credential file exits 2
|
||||
OK symlinked credential file exits 4
|
||||
OK env-side credential names reported
|
||||
OK env var values never reach output
|
||||
OK accounts without an accounts dir reports none and creates nothing
|
||||
OK accounts lists files and marks the active one
|
||||
OK loose account perms flagged in listing
|
||||
OK agent --auth with missing account file refuses (exit 4)
|
||||
OK agent --auth with non-0600 account file refuses
|
||||
OK agent --auth with invalid account name refuses
|
||||
OK auth.sh without valid config refuses
|
||||
|
||||
selftest: 15 passed, 0 failed
|
||||
@@ -0,0 +1,23 @@
|
||||
On branch rocko/row219-on-07802dc57
|
||||
Your branch is up to date with 'origin/rocko/row219-on-07802dc57'.
|
||||
|
||||
nothing to commit, working tree clean
|
||||
OK dry-run: allowed change, exit 0, nothing committed (exit 0)
|
||||
OK dry-run committed nothing
|
||||
OK apply: allowed change exits 0 (exit 0)
|
||||
OK apply: attribution in commit subject
|
||||
OK apply: target tree clean after commit
|
||||
OK disallowed path refused (exit 1)
|
||||
OK disallowed path: target untouched
|
||||
OK syntax gate refused broken .mjs (exit 1)
|
||||
OK syntax gate: target untouched
|
||||
OK suite failure refused (exit 1)
|
||||
OK suite failure: target reverted to clean
|
||||
OK disabled policy refused (exit 2)
|
||||
OK disabled policy: target untouched
|
||||
OK failed run refused (exit 1)
|
||||
OK failed run: target untouched
|
||||
OK missing run exits 4 (exit 4)
|
||||
OK invalid policy exits 2 (exit 2)
|
||||
|
||||
selftest: 17 passed, 0 failed
|
||||
@@ -0,0 +1,57 @@
|
||||
OK absent adapter defaults to pi
|
||||
OK adapter mock validates (exit 0)
|
||||
OK unsupported adapter exits 2 (exit 2)
|
||||
OK env exports adapter
|
||||
OK bootstrap creates default when absent (exit 0)
|
||||
OK bootstrap wrote config file
|
||||
OK bootstrap is idempotent on existing config (exit 0)
|
||||
OK bootstrap did not rewrite existing config
|
||||
OK validate missing config exits 3 (exit 3)
|
||||
OK malformed JSON exits 2 (exit 2)
|
||||
OK unsupported configVersion exits 2 (exit 2)
|
||||
OK unknown top-level key exits 2 (exit 2)
|
||||
OK unknown execution key exits 2 (exit 2)
|
||||
OK unsupported backend exits 2 (exit 2)
|
||||
OK unsupported environment exits 2 (exit 2)
|
||||
OK relative dataRoot exits 2 (exit 2)
|
||||
OK non-canonical dataRoot exits 2 (exit 2)
|
||||
OK filesystem root dataRoot exits 2 (exit 2)
|
||||
OK home directory dataRoot exits 2 (exit 2)
|
||||
OK dataRoot containing config dir exits 2 (exit 2)
|
||||
OK control character in provider exits 2 (exit 2)
|
||||
OK symlinked config file exits 2 (exit 2)
|
||||
OK env exports resolve correctly
|
||||
OK valid console.sso loads and is in the output
|
||||
OK console.sso HS256 alg exits 2 naming the path (exit 2)
|
||||
OK console.sso alg none exits 2 naming the path (exit 2)
|
||||
OK console.sso missing slot field exits 2 naming the path (exit 2)
|
||||
OK console.sso slot name outside the pattern exits 2 naming the path (exit 2)
|
||||
OK unknown key under console exits 2 naming the path (exit 2)
|
||||
OK valid federation key loads and is in the output
|
||||
OK federation unknown sub-key exits 2 naming the key (exit 2)
|
||||
OK federation peer unknown sub-key exits 2 naming the key (exit 2)
|
||||
OK federation peer origin over http exits 2 naming the key (exit 2)
|
||||
OK federation peer origin with a path exits 2 naming the key (exit 2)
|
||||
OK federation peer origin with userinfo exits 2 naming the key (exit 2)
|
||||
OK federation peer id equal to self exits 2 naming the key (exit 2)
|
||||
OK federation peer label empty exits 2 naming the key (exit 2)
|
||||
OK federation not an object exits 2 naming the key (exit 2)
|
||||
OK federation self pattern exits 2 naming the key (exit 2)
|
||||
OK federation peers not an array exits 2 naming the key (exit 2)
|
||||
OK federation peer not an object exits 2 naming the key (exit 2)
|
||||
OK federation peer id pattern exits 2 naming the key (exit 2)
|
||||
OK federation peer label over 80 characters exits 2 naming the key (exit 2)
|
||||
OK federation duplicate peer id exits 2 naming the key (exit 2)
|
||||
OK federation peer origin with a trailing slash exits 2 naming the key (exit 2)
|
||||
OK federation self missing exits 2 naming the key (exit 2)
|
||||
OK federation peer id missing exits 2 naming the key (exit 2)
|
||||
OK federation peer label missing exits 2 naming the key (exit 2)
|
||||
OK config without federation loads and has no federation output
|
||||
OK config without console loads with unchanged output
|
||||
OK compactionReadBytes 8388608 loads and is in the output as written
|
||||
OK compactionReadBytes "x" loads and is in the output as written
|
||||
OK compactionStreams 2048 loads and is in the output as written
|
||||
OK compactionStreams "x" loads and is in the output as written
|
||||
OK failed validation modified nothing
|
||||
|
||||
selftest: 55 passed, 0 failed
|
||||
@@ -0,0 +1,85 @@
|
||||
toolchain: node v26.8.1
|
||||
|
||||
OK syntax: packages/discord/src/approvals.mjs
|
||||
OK syntax: packages/discord/src/authorize.mjs
|
||||
OK syntax: packages/discord/src/binding.mjs
|
||||
OK syntax: packages/discord/src/cli.mjs
|
||||
OK syntax: packages/discord/src/connector.mjs
|
||||
OK syntax: packages/discord/src/context.mjs
|
||||
OK syntax: packages/discord/src/engine-pi.mjs
|
||||
OK syntax: packages/discord/src/errors.mjs
|
||||
OK syntax: packages/discord/src/gateway.mjs
|
||||
OK syntax: packages/discord/src/git.mjs
|
||||
OK syntax: packages/discord/src/journal.mjs
|
||||
OK syntax: packages/discord/src/notify.mjs
|
||||
OK syntax: packages/discord/src/processing.mjs
|
||||
OK syntax: packages/discord/src/rest.mjs
|
||||
OK syntax: packages/discord/src/setspark.mjs
|
||||
OK syntax: packages/discord/src/tools.mjs
|
||||
OK syntax: packages/discord/src/web.mjs
|
||||
OK syntax: packages/discord/bin/git-credential.mjs
|
||||
OK syntax: packages/discord/extension/tools.mjs
|
||||
OK syntax: packages/discord/tests/approvals.test.mjs
|
||||
OK syntax: packages/discord/tests/authorize.test.mjs
|
||||
OK syntax: packages/discord/tests/binding.test.mjs
|
||||
OK syntax: packages/discord/tests/connector.test.mjs
|
||||
OK syntax: packages/discord/tests/context.test.mjs
|
||||
OK syntax: packages/discord/tests/copy-service.test.mjs
|
||||
OK syntax: packages/discord/tests/engine.test.mjs
|
||||
OK syntax: packages/discord/tests/fake-pi.mjs
|
||||
OK syntax: packages/discord/tests/gateway.test.mjs
|
||||
OK syntax: packages/discord/tests/git.test.mjs
|
||||
OK syntax: packages/discord/tests/helpers.mjs
|
||||
OK syntax: packages/discord/tests/journal.test.mjs
|
||||
OK syntax: packages/discord/tests/notify.test.mjs
|
||||
OK syntax: packages/discord/tests/offline-check.test.mjs
|
||||
OK syntax: packages/discord/tests/processing-stop.test.mjs
|
||||
OK syntax: packages/discord/tests/processing.test.mjs
|
||||
OK syntax: packages/discord/tests/recover.test.mjs
|
||||
OK syntax: packages/discord/tests/rest.test.mjs
|
||||
OK syntax: packages/discord/tests/setspark.test.mjs
|
||||
OK syntax: packages/discord/tests/tools.test.mjs
|
||||
OK syntax: packages/discord/tests/web.test.mjs
|
||||
OK syntax: packages/discord/fixtures/claim-worker.mjs
|
||||
OK syntax: packages/discord/fixtures/legacy-owner-worker.mjs
|
||||
OK syntax: scripts/discord.sh
|
||||
OK syntax: scripts/discord-service.sh
|
||||
OK packages/discord declares no dependencies
|
||||
OK no bot-token-shaped string in packages/discord
|
||||
OK fixture binding uses placeholder ids only
|
||||
OK fixture binding validates
|
||||
OK real pi with the extension exposes exactly list_dir, read_file, search and no built-in tool
|
||||
OK real pi with a writable root exposes exactly the three reads plus write_file and edit_file, and writes nothing at start
|
||||
OK real pi with a web key exposes the three reads plus web_fetch and web_search, and no write tool without a writable root
|
||||
OK real pi with a git root exposes the reads, writes and the four git verbs, commits nothing at start, and never shows the token
|
||||
OK real pi with protocol vault adds reserve_id to the git verbs
|
||||
OK real pi with a setspark key exposes the reads and the eight record verbs, no counters, and never shows the key
|
||||
OK real pi refuses a git key on a read-only root (fail closed)
|
||||
OK real pi with the pilot flags (--no-tools) exposes no tool at all
|
||||
OK real pi exits non-zero without MOSAIC_DISCORD_TOOLS: no session, no tools (fail closed)
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test packages/discord/tests/ (ℹ pass 192)
|
||||
OK scripts/discord.sh --help exits 0
|
||||
OK scripts/discord.sh check without a binding exits 4
|
||||
OK scripts/discord.sh recover without a binding exits 4
|
||||
OK scripts/discord.sh reload without a binding exits 4
|
||||
OK scripts/discord-service.sh without a command exits 4
|
||||
OK service unit renders with the repository path, a supervised run as the main process, exit 3 never retried, and reload as SIGHUP
|
||||
OK service install writes the rendered unit (0644) and leaves no temp file
|
||||
OK service install a second time reports unchanged
|
||||
OK systemd-analyze verify accepts the rendered unit
|
||||
OK service uninstall removes the unit file
|
||||
OK service install with an unknown flag exits 4
|
||||
OK service install with USER unset finishes and names the account for lingering
|
||||
OK pinned render runs copy CLI with copy cwd/repo and no checkout executable
|
||||
OK pinned install writes the rendered unit in a temporary unit directory
|
||||
OK pinned install refuses short prerequisite and writes no unit
|
||||
OK pinned install refuses missing prerequisite and writes no unit
|
||||
OK pinned install refuses cli prerequisite and writes no unit
|
||||
OK pinned install refuses pi prerequisite and writes no unit
|
||||
OK status names the copy from fake systemctl effective cwd
|
||||
OK checkout install explicitly recommends --copy
|
||||
OK wrapper check --offline passes local fixture and makes no network call
|
||||
OK wrapper run --offline refuses usage
|
||||
|
||||
discord suite: 81 passed, 0 failed
|
||||
@@ -0,0 +1,21 @@
|
||||
OK initial ordinary-file install
|
||||
OK installed tree matches canonical source
|
||||
OK installed tree has no symlinks
|
||||
OK check detects installation drift
|
||||
OK sync refuses to overwrite installation drift
|
||||
OK check detects an extra destination file
|
||||
OK check detects an extra destination directory
|
||||
OK check rejects a destination symlink
|
||||
OK sync accepts a canonical source update
|
||||
OK updated installation matches canonical source
|
||||
/mnt/storage/scratch/rocko-r219/scripts/test-extension-package.sh: line 14: 3698730 Killed "$@" > /dev/null 2>&1
|
||||
OK forced interruption kills the replacing process
|
||||
OK next invocation recovers old consistent installation
|
||||
OK interrupted replacement rolled back
|
||||
OK sync succeeds after interruption recovery
|
||||
OK unlocked stale lock file does not block
|
||||
OK active lock refuses a concurrent sync
|
||||
OK source symlink fails closed
|
||||
OK nested second entrypoint fails closed
|
||||
|
||||
extension package selftest: 18 passed, 0 failed
|
||||
@@ -0,0 +1,53 @@
|
||||
toolchain: node v26.8.1, python 3.12.8, jsonschema 4.26.0
|
||||
|
||||
OK syntax: scripts/foundation-inspect.mjs
|
||||
OK syntax: scripts/foundation/strict-json.mjs
|
||||
OK syntax: scripts/foundation/canonical.mjs
|
||||
OK syntax: scripts/foundation/resolve.mjs
|
||||
OK syntax: scripts/foundation/validate-record.mjs
|
||||
OK syntax: scripts/foundation/fixtures/build-fixtures.mjs
|
||||
OK syntax: scripts/foundation/canonical.test.mjs
|
||||
OK syntax: scripts/foundation/cli.test.mjs
|
||||
OK syntax: scripts/foundation/fixtures.test.mjs
|
||||
OK syntax: scripts/foundation/resolve.test.mjs
|
||||
OK syntax: scripts/foundation/strict-json.test.mjs
|
||||
OK syntax: scripts/foundation/verify-schema.py (ast only; no bytecode written)
|
||||
OK fixture generator runs
|
||||
OK checked-in fixtures/bundles equal a fresh generation
|
||||
OK checked-in fixtures/raw equal a fresh generation
|
||||
OK checked-in fixtures/index.json equal a fresh generation
|
||||
OK checked-in demo bundles equal a fresh generation
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test scripts/foundation/ (ℹ pass 80)
|
||||
OK differential schema oracle: PASS: differential schema oracle (finite corpus; compatibility evidence, not equivalence proof)
|
||||
platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999)
|
||||
node v26.8.1; corpus 1568 records (38 pinned fixtures, 478 unique bundle records, 1052 typeCase/mutation/lexical cases)
|
||||
schema column: agree-valid 540, agree-invalid 991, DISAGREEMENTS 0; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10
|
||||
profile column (schema-valid records only): profile-valid 510, profile-invalid 30
|
||||
profile refusals asserted: 30 schema-agreed-valid records refused only by the strict typed-string profile (rule profile-pattern-mismatch), 12 declared by name; 73 named probes verified against declared schema/profile columns
|
||||
OK oracle: zero schema-column disagreements with the pinned checker
|
||||
OK oracle: strict-only profile refusals are counted and asserted
|
||||
OK demo: permitted read preview exits 0 (exit 0)
|
||||
OK demo: permitted file.change preview exits 0 (exit 0)
|
||||
OK demo: assignment.change proposal is unresolved (exit 3) (exit 3)
|
||||
OK demo: revoked registration is refused (exit 3) (exit 3)
|
||||
OK demo: message is not authority (exit 3) (exit 3)
|
||||
OK usage: no arguments exits 2 (exit 2)
|
||||
OK io: missing file exits 4 (exit 4)
|
||||
OK io: directory exits 4 (exit 4)
|
||||
OK io: symlink exits 4 (O_NOFOLLOW) (exit 4)
|
||||
OK bound: oversize fixture exits 2 (exit 2)
|
||||
OK profile: one final LF in a typed selection id is refused before admission (exit 2) (exit 2)
|
||||
OK profile: two final LFs fail the schema pattern itself (exit 2) (exit 2)
|
||||
OK profile: escaped newlines in free-form text stay allowed (exit 0) (exit 0)
|
||||
OK profile refusal is invalid-request/profile-pattern-mismatch with selection and operation withheld, value not echoed
|
||||
OK text output starts with the disclaimer
|
||||
OK json output is valid JSON with result allowed and exactly the charter §7 fields
|
||||
OK json golden matches byte-for-byte
|
||||
OK sandboxed bundle run (env -i, PATH=/nonexistent) produced the unresolved proposal
|
||||
OK sandbox inventory (path/type/size/mode/uid/gid/inode/mtime/sha256) unchanged by runs
|
||||
OK canary never printed (bundle run and credential-file run)
|
||||
OK a non-bundle JSON file is refused at the shape gate, not read into output
|
||||
OK no field of the non-bundle file is echoed
|
||||
|
||||
selftest: 44 passed, 0 failed
|
||||
@@ -0,0 +1,88 @@
|
||||
OK args: exit 2, target-branch
|
||||
OK args: exit 2, target-branch
|
||||
OK args: exit 4
|
||||
OK args: exit 4
|
||||
OK args: exit 4
|
||||
OK --base next refuses before the config is read (got 2)
|
||||
OK a missing system config exits 3 (got 3)
|
||||
OK nobus: exit 3
|
||||
OK schema-table: exit 2, bus-schema
|
||||
OK schema-meta: exit 2, bus-schema
|
||||
OK openBus opens the database read-only
|
||||
OK other-business: exit 2, decision-not-found
|
||||
OK no-raise: exit 2, decision-not-found
|
||||
OK not-a-merge: exit 2, not-a-merge
|
||||
OK open: exit 2, not-resolved
|
||||
OK withdrawn: exit 2, not-resolved
|
||||
OK by-agent: exit 2, not-human
|
||||
OK via-webui: exit 2, not-human
|
||||
OK no-answer: exit 2, not-human
|
||||
OK answer-role: exit 2, not-human
|
||||
OK answer-run: exit 2, not-human
|
||||
OK answer-choice: exit 2, not-human
|
||||
OK two-answers: exit 2, not-human
|
||||
OK arbiter-cross: exit 2, not-human
|
||||
OK arbiter-cited: exit 2, not-human
|
||||
OK chose-no: exit 2, not-merge-option
|
||||
OK two-refs: exit 2, work-ref
|
||||
OK bad-ref: exit 2, work-ref
|
||||
OK task-ref-disagrees: exit 2, work-ref
|
||||
OK raise-task-disagrees: exit 2, work-ref
|
||||
OK target-main: exit 2, target-branch
|
||||
OK superseded-question: exit 2, superseded
|
||||
OK superseded-task: exit 2, superseded
|
||||
OK superseded-by: exit 2, superseded
|
||||
OK no-verdict: exit 2, no-verdict
|
||||
OK changes-later: exit 2, not-approved
|
||||
OK short-commit: exit 2, not-approved
|
||||
OK wrong-task-body: exit 2, not-approved
|
||||
OK args: exit 2, decision-not-found
|
||||
OK earlier-merge: exit 0
|
||||
OK ref-moved: exit 2, ref-moved
|
||||
OK root-top: exit 2, root-file
|
||||
OK root-newdir: exit 2, root-file
|
||||
OK root-src: exit 2, root-file
|
||||
OK unrelated: exit 2, base-conflict
|
||||
OK empty: exit 2, base-conflict
|
||||
OK an empty reviewed diff says so
|
||||
OK dirty-changed: exit 2, checkout-dirty
|
||||
OK dirty-staged: exit 2, checkout-dirty
|
||||
OK dirty-untracked: exit 2, checkout-dirty
|
||||
OK conflict: exit 2, base-conflict
|
||||
OK a refusal after the worktree is added leaves no worktree or scratch
|
||||
OK cleanup looks for the worktree's Docker network
|
||||
OK dirty-during: exit 2, checkout-dirty
|
||||
OK a reviewed path dirtied during the gate moves no ref
|
||||
OK drift: exit 2, patch-drift
|
||||
OK patch-drift leaves no worktree or scratch
|
||||
OK gate-pkg: exit 2, gate-failed
|
||||
OK gate-failed names the failing step's log, and it exists
|
||||
OK gate-failed leaves no worktree or scratch
|
||||
OK gate-script: exit 2, gate-failed
|
||||
OK a failing scripts/test-*.sh fails the gate
|
||||
OK a failed gate moves no ref
|
||||
OK nomods: exit 4
|
||||
OK a target without node_modules leaves no worktree or scratch
|
||||
OK moved: exit 2, base-moved
|
||||
OK base-moved keeps the base where it moved to
|
||||
OK dry: exit 0
|
||||
OK --dry-run writes no ref
|
||||
OK --dry-run prints the commit with --subject and --attribution
|
||||
OK --dry-run runs the gate
|
||||
OK --dry-run leaves no worktree or scratch
|
||||
OK land: exit 0
|
||||
OK the landing is one commit on the old base
|
||||
OK its diff is the reviewed diff by patch-id
|
||||
OK its tree is the dry run's
|
||||
OK the message has the option's subject, the citations and the attribution last
|
||||
OK it prints the line for the PM
|
||||
OK the checked-out base has the reviewed paths and keeps the unrelated edit
|
||||
OK only refs/heads/refactor exists in the target
|
||||
OK the work ref is unchanged
|
||||
OK the bus database is unchanged
|
||||
OK the gate ran each package suite but queue, and each scripts/test-*.sh
|
||||
OK the landing leaves no worktree or scratch
|
||||
OK the target's node_modules is still there, with its contents
|
||||
OK the worktree's Docker network is removed
|
||||
---
|
||||
land-work selftests: 86 passed, 0 failed
|
||||
@@ -0,0 +1,36 @@
|
||||
toolchain: node v26.8.1, git version 2.55.0
|
||||
|
||||
OK syntax: packages/queue/src/cli.mjs
|
||||
OK syntax: packages/queue/src/errors.mjs
|
||||
OK syntax: packages/queue/src/io.mjs
|
||||
OK syntax: packages/queue/src/lock.mjs
|
||||
OK syntax: packages/queue/src/queue.mjs
|
||||
OK syntax: packages/queue/src/review.mjs
|
||||
OK syntax: packages/queue/src/store.mjs
|
||||
OK syntax: packages/queue/tests/commit.test.mjs
|
||||
OK syntax: packages/queue/tests/data.test.mjs
|
||||
OK syntax: packages/queue/tests/dispatch.test.mjs
|
||||
OK syntax: packages/queue/tests/gate-owner.test.mjs
|
||||
OK syntax: packages/queue/tests/helpers.mjs
|
||||
OK syntax: packages/queue/tests/lock.test.mjs
|
||||
OK syntax: packages/queue/tests/migration.test.mjs
|
||||
OK syntax: packages/queue/tests/review.test.mjs
|
||||
OK syntax: packages/queue/tests/store.test.mjs
|
||||
OK syntax: packages/queue/tests/write.test.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/fake-gitea.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/kill-at.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/lock-child.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/mosaic-pre-a2.sh
|
||||
OK syntax: scripts/queue-commit.sh
|
||||
OK syntax: scripts/git-hooks/pre-commit
|
||||
OK syntax: scripts/mosaic
|
||||
OK queue-commit.sh, the guard and scripts/mosaic are executable
|
||||
OK packages/queue declares no dependencies
|
||||
ℹ tests 156
|
||||
ℹ pass 156
|
||||
ℹ fail 0
|
||||
OK node --test packages/queue/tests/
|
||||
OK scripts/mosaic queue help
|
||||
skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r219) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
|
||||
|
||||
queue suite: 28 passed, 0 failed
|
||||
@@ -0,0 +1,37 @@
|
||||
OK valid RELEASE resolves (exit 0)
|
||||
OK invalid RELEASE exits 1 (exit 1)
|
||||
OK missing RELEASE exits 1 (exit 1)
|
||||
OK valid RELEASE leaves image tag consistent with version
|
||||
OK status safe on empty state (exit 0)
|
||||
OK status created no pointer
|
||||
OK fault-injected activation refuses (exit 1)
|
||||
OK refused activation wrote no pointer
|
||||
OK refusal logged exactly once with valid fields
|
||||
FAIL healthy activation succeeds (exit 1, expected 0)
|
||||
node:fs:621
|
||||
return binding.readFileUtf8(path, stringToFlags(options.flag));
|
||||
^
|
||||
|
||||
Error: ENOENT: no such file or directory, open '/mnt/storage/scratch/tmp/rbunO3T/tmp.HQT7aH1NBB/data/state/active.json'
|
||||
at Object.readFileSync (node:fs:621:20)
|
||||
at [eval]:3:25
|
||||
at runScriptInThisContext (node:internal/vm:219:10)
|
||||
at node:internal/process/execution:485:12
|
||||
at [eval]-wrapper:6:24
|
||||
at runScriptInContext (node:internal/process/execution:483:60)
|
||||
at evalFunction (node:internal/process/execution:317:30)
|
||||
at evalTypeScript (node:internal/process/execution:329:3)
|
||||
at node:internal/main/eval_string:71:3 {
|
||||
errno: -2,
|
||||
code: 'ENOENT',
|
||||
syscall: 'open',
|
||||
path: '/mnt/storage/scratch/tmp/rbunO3T/tmp.HQT7aH1NBB/data/state/active.json'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
FAIL pointer written with valid fields
|
||||
FAIL repeat activation succeeds (log grows) (exit 1, expected 0)
|
||||
OK log is append-only across activations
|
||||
OK rollback without previous refuses (exit 1)
|
||||
|
||||
selftest: 11 passed, 3 failed
|
||||
@@ -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-mos1408';OUT.mkdir(exist_ok=True)
|
||||
OUT=PACKET/'run-2efd-mos1439';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():
|
||||
@@ -22,7 +22,8 @@ def sweep():
|
||||
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:]]
|
||||
if args[0]!='timeout':args=['timeout','-k','10',str(deadline),*args]
|
||||
verify();short=tempfile.mkdtemp(prefix='r',dir='/mnt/storage/scratch/tmp')
|
||||
verify();short=subprocess.check_output(['mktemp','-d','/mnt/storage/scratch/tmp/rXXXXXX'],text=True).strip()
|
||||
if not re.fullmatch(r'[A-Za-z0-9/.-]+',short):raise RuntimeError('unsafe TMPDIR charset')
|
||||
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)
|
||||
if docker:env.pop('DOCKER_HOST',None)
|
||||
@@ -45,9 +46,10 @@ def execute(label,args,cwd=ROOT,deadline=300,docker=False):
|
||||
finally:
|
||||
try:os.killpg(child.pid,signal.SIGTERM)
|
||||
except ProcessLookupError:pass
|
||||
timeout = timeout or rc in (124,137,-9)
|
||||
text=log.read_text(errors='replace')
|
||||
counts={k:int(m[-1]) if (m:=re.findall(r'^# '+k+r' (\d+)\s*$',text,re.M)) else None for k in ['tests','pass','fail','cancelled','skipped']}
|
||||
row=dict(label=label,args=args,start=begin,end=stamp(),seconds=round(time.monotonic()-t,3),exit=rc,timeout=timeout,counts=counts,skips=[l for l in text.splitlines() if re.search(r'^skip|# SKIP',l,re.I)],log=str(log.relative_to(ROOT)),tmpdir=short)
|
||||
row=dict(label=label,args=args,start=begin,end=stamp(),seconds=round(time.monotonic()-t,3),exit=rc,timeout=timeout,counts=counts,skips=[l for l in text.splitlines() if re.search(r'^skip\b|# SKIP\b',l,re.I)],log=str(log.relative_to(ROOT)),tmpdir=short)
|
||||
with (OUT/'results.jsonl').open('a') as f:f.write(json.dumps(row)+'\n')
|
||||
print('END',json.dumps(row),flush=True)
|
||||
if rc or timeout or re.search(r'^\s*not ok\b',text,re.M):raise RuntimeError('RED '+label+' '+str(log))
|
||||
@@ -55,7 +57,7 @@ def execute(label,args,cwd=ROOT,deadline=300,docker=False):
|
||||
singles=[line for line in (PACKET/'changed-paths.txt').read_text().splitlines() if '/tests/' in line]
|
||||
def stages():
|
||||
for path in singles:execute('single-'+Path(path).parent.parent.name+'-'+Path(path).stem,['node','--test',path],deadline=300)
|
||||
for package in ['bus','cli','webui']:
|
||||
for package in ['bus','cli','webui','harness']:
|
||||
files=sorted(glob.glob(str(ROOT/'packages'/package/'tests'/'*.test.mjs')))
|
||||
execute('suite-'+package,['node','--test',*files],cwd=ROOT/'packages'/package,deadline=1800)
|
||||
for path in sorted(ROOT.glob('scripts/test-*.sh')):
|
||||
@@ -95,4 +97,7 @@ if __name__=='__main__':
|
||||
finally:
|
||||
verify();(OUT/'cwd-sweep.json').write_text(json.dumps(sweep(),indent=2))
|
||||
# Remove only the owned fixture compose network, if any; never daemon/volumes.
|
||||
subprocess.run(['docker','network','rm','rocko-r219-gate_default'],stdout=(OUT/'network-cleanup.log').open('w'),stderr=subprocess.STDOUT)
|
||||
|
||||
with (OUT/'network-cleanup.log').open('w') as f:
|
||||
for network in ['rocko-r219-gate_default', ROOT.name+'_default']:
|
||||
subprocess.run(['docker','network','rm',network],stdout=f,stderr=subprocess.STDOUT)
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
{"head": "054da642f9b0680bd7743583e4c67266d7e14e2a", "manifest": "4a2271ddbd4212324f39e608c3a35a4ae834c045cb0d13a619715017ded0ffef", "start": "2026-10-23T10:12:57.648452+00:00"}
|
||||
@@ -0,0 +1,30 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
not ok 1 - C2-09a: creative bindLaunch without a thread refuses thread-required
|
||||
---
|
||||
duration_ms: 15.929586
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:645:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: 'Missing expected exception.'
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
code: 'thread-required'
|
||||
operator: 'throws'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:652:12)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 89.932343
|
||||
@@ -0,0 +1,36 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
not ok 1 - C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
---
|
||||
duration_ms: 19.275187
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:605:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'assistant'
|
||||
- 'writer0'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 'writer0'
|
||||
actual: 'assistant'
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:615:12)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 91.60992
|
||||
@@ -0,0 +1,30 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
not ok 1 - C2-09a: explicit missing, non-thread and malformed selectors create no thread or session
|
||||
---
|
||||
duration_ms: 17.510719
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:631:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: 'Missing expected exception.'
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
code: 'thread-instance-missing'
|
||||
operator: 'throws'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:635:12)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 89.201033
|
||||
@@ -0,0 +1,51 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
not ok 1 - C2-09a: explicit creative instances bind independent threads, default sessions and holders
|
||||
---
|
||||
duration_ms: 19.552932
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:605:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'storage-refused'
|
||||
- code: 'thread-instance-ambiguous'
|
||||
}
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
code: 'thread-instance-ambiguous'
|
||||
actual:
|
||||
error: 'storage-refused'
|
||||
stack: |-
|
||||
#refused (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/src/broker.mjs:4510:47)
|
||||
Broker.request (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/src/broker.mjs:4682:26)
|
||||
Object.call (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:56:44)
|
||||
assert.throws.code (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:612:27)
|
||||
getActual (node:assert:580:5)
|
||||
strict.throws (node:assert:728:24)
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:612:10)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
operator: 'throws'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/threads.test.mjs:612:10)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 94.246865
|
||||
@@ -0,0 +1,36 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
not ok 1 - C2-09a: naming an instance cannot bypass its collaborator grant or disclose an ungranted project
|
||||
---
|
||||
duration_ms: 18.98222
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/user-principal.test.mjs:399:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ null
|
||||
- 'access-refused'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 'access-refused'
|
||||
actual: ~
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/bus/tests/user-principal.test.mjs:405:10)
|
||||
Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
Test.run (node:internal/test_runner/test:1402:25)
|
||||
Test.start (node:internal/test_runner/test:1262:17)
|
||||
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 89.7564
|
||||
@@ -0,0 +1,29 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
not ok 1 - C2-09a: creative thread messages start distinct runs and keep each instance history separate
|
||||
---
|
||||
duration_ms: 197.010178
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-launch.test.mjs:463:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: 'creative thread launch refused: thread-not-allowed'
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 'refused'
|
||||
actual: 'refused'
|
||||
operator: 'notStrictEqual'
|
||||
stack: |-
|
||||
send (file:///mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-launch.test.mjs:480:12)
|
||||
async TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/cli/tests/thread-launch.test.mjs:486:21)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 321.200539
|
||||
@@ -0,0 +1,67 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
not ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 15.993582
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:34:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
[
|
||||
{
|
||||
instance: 'assistant',
|
||||
name: 'assistant'
|
||||
},
|
||||
...
|
||||
},
|
||||
+ {
|
||||
+ instance: 'pm',
|
||||
+ name: 'Hidden PM'
|
||||
+ }
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0:
|
||||
instance: 'assistant'
|
||||
name: 'assistant'
|
||||
1:
|
||||
instance: 'bean'
|
||||
name: 'Bean'
|
||||
2:
|
||||
instance: 'chet'
|
||||
name: 'Bean'
|
||||
actual:
|
||||
0:
|
||||
instance: 'assistant'
|
||||
name: 'assistant'
|
||||
1:
|
||||
instance: 'bean'
|
||||
name: 'Bean'
|
||||
2:
|
||||
instance: 'chet'
|
||||
name: 'Bean'
|
||||
3:
|
||||
instance: 'pm'
|
||||
name: 'Hidden PM'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:43:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 119.791147
|
||||
@@ -0,0 +1,67 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
not ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 16.209347
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:34:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
{
|
||||
instance: 'assistant',
|
||||
name: 'assistant'
|
||||
},
|
||||
{
|
||||
instance: 'bean',
|
||||
+ name: 'bean'
|
||||
- name: 'Bean'
|
||||
},
|
||||
{
|
||||
instance: 'chet',
|
||||
+ name: 'chet'
|
||||
- name: 'Bean'
|
||||
}
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0:
|
||||
instance: 'assistant'
|
||||
name: 'assistant'
|
||||
1:
|
||||
instance: 'bean'
|
||||
name: 'Bean'
|
||||
2:
|
||||
instance: 'chet'
|
||||
name: 'Bean'
|
||||
actual:
|
||||
0:
|
||||
instance: 'assistant'
|
||||
name: 'assistant'
|
||||
1:
|
||||
instance: 'bean'
|
||||
name: 'bean'
|
||||
2:
|
||||
instance: 'chet'
|
||||
name: 'chet'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:43:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 112.500283
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
not ok 1 - C2-09a malformed instance and extra thread fields refuse before the channel write
|
||||
---
|
||||
duration_ms: 17.897837
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat.test.mjs:347:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
null
|
||||
|
||||
503 !== 400
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 400
|
||||
actual: 503
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat.test.mjs:351:12)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 122.242476
|
||||
@@ -0,0 +1,54 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a createThread forwards an explicit instance through the existing channel
|
||||
not ok 1 - C2-09a createThread forwards an explicit instance through the existing channel
|
||||
---
|
||||
duration_ms: 18.423418
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat.test.mjs:339:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
[
|
||||
'thread.create',
|
||||
{
|
||||
- instance: 'bean',
|
||||
name: 'Bean work',
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0:
|
||||
0: 'thread.create'
|
||||
1:
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
name: 'Bean work'
|
||||
instance: 'bean'
|
||||
actual:
|
||||
0:
|
||||
0: 'thread.create'
|
||||
1:
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
name: 'Bean work'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat.test.mjs:344:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 120.076841
|
||||
@@ -0,0 +1,52 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
not ok 1 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 569.715562
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
body: {
|
||||
- instance: 'bean',
|
||||
name: 'Bean discussion',
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
},
|
||||
path: '/api/chat/threads',
|
||||
redirect: 'manual'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
path: '/api/chat/threads'
|
||||
body:
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
name: 'Bean discussion'
|
||||
instance: 'bean'
|
||||
redirect: 'manual'
|
||||
actual:
|
||||
path: '/api/chat/threads'
|
||||
body:
|
||||
project: '10000000-0000-4000-8000-000000000001'
|
||||
name: 'Bean discussion'
|
||||
redirect: 'manual'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:294:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 671.053636
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
not ok 1 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 605.200854
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
|
||||
'bean' !== ''
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: ''
|
||||
actual: 'bean'
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:274:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 710.854507
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
not ok 1 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 576.032383
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:297:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The input did not match the regular expression /read the thread instances/. Input:
|
||||
|
||||
'No thread instances are configured.'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
actual: 'No thread instances are configured.'
|
||||
operator: 'match'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:301:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 679.633888
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
not ok 1 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 568.713206
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The input did not match the regular expression /\(bean\)/. Input:
|
||||
|
||||
'<img src=x onerror="window.injected=1">\\u001b[31m\\u202eevil'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
actual: '<img src=x onerror="window.injected=1">\\u001b[31m\\u202eevil'
|
||||
operator: 'match'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:278:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 683.056698
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
not ok 1 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 66757.108414
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:297:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The input did not match the regular expression /no longer available/. Input:
|
||||
|
||||
''
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
actual: ''
|
||||
operator: 'match'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:313:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 66863.389451
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
not ok 1 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 607.794033
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:297:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
|
||||
'chet' !== ''
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: ''
|
||||
actual: 'chet'
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:312:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 709.649006
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
not ok 1 - C2-09a picker: no silent choice, duplicate hostile labels stay inert, selection survives refresh and reaches POST
|
||||
---
|
||||
duration_ms: 591.47268
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
|
||||
false !== true
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: true
|
||||
actual: false
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:276:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 697.367041
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
not ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 19.755478
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:34:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok([400, 405].includes(result.status))
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: true
|
||||
actual: false
|
||||
operator: '=='
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:49:12)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 123.785013
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
not ok 1 - C2-09a metadata uses the human listener bus, projects labels only and refuses unauthenticated reads
|
||||
---
|
||||
duration_ms: 19.259813
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:34:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok([400, 405].includes(result.status))
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: true
|
||||
actual: false
|
||||
operator: '=='
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-instances.test.mjs:49:12)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 122.394255
|
||||
@@ -0,0 +1,33 @@
|
||||
TAP version 13
|
||||
# Subtest: C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
not ok 1 - C2-09a picker: metadata failure, empty set and removed pick explain disabled state and recover without switching
|
||||
---
|
||||
duration_ms: 528.731905
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:297:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
The input did not match the regular expression /No thread instances/. Input:
|
||||
|
||||
'Reading thread instances…'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
actual: 'Reading thread instances…'
|
||||
operator: 'match'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r219-g3345/packages/webui/tests/chat-browser.test.mjs:305:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 630.644432
|
||||
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user