agents: Dewey row 139 round 2 packet, Jason's ruling Q169 (#1633)
Candidate manifest 7a1fcae1 (patch 7a29d911) on 5661bd233. Only the chief of
staff, or a decision the human resolved through the CLI, ends or revokes the
assistant; a revoke of it is a hard wait. PRD 1.6 text in PRD-1.6.md for Mos.
Gate 14/14 rc=0 and mutants m1-m9 killed under slot sage-0533. SMOKE.md plan,
not run.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
# Row 139 (#1633): decisions that cite the spec go to an agent; only hard waits reach Jason
|
||||
|
||||
Builder: Dewey. Reviewer: Filbert. Gate owner: Sage.
|
||||
Brief: docs/plans/2026-10-15_q167-rows-r3.md at b2a2d741c (blob 0fd6647bf), lines 414-478.
|
||||
Requirements: PRD 1.5 REQ-DEC-2 and REQ-WAIT-1 to REQ-WAIT-3 (docs/prd/mosaic-stack.md:288-352).
|
||||
Calls from sage-0502, 0504, 0512, 0514 and 0516.
|
||||
Brief: docs/plans/2026-10-15_q167-rows-r3.md at b71268b8e (blob 6805904555dc, rev 1565), section
|
||||
"Decisions that cite the spec go to an agent; only hard waits reach Jason". Round 1 built against
|
||||
04c572003 (blob c22ce67cd).
|
||||
Requirements: PRD 1.5 REQ-DEC-2 and REQ-WAIT-1 to REQ-WAIT-3, and PRD 1.6 (this row) for Jason's
|
||||
ruling Q169.
|
||||
Calls from sage-0502, 0504, 0512, 0514, 0516, 0528, 0533 and 0539. sage-0523 (Mos's ruling) is
|
||||
superseded by Q169.
|
||||
|
||||
Round 2 follows Jason's ruling Q169 (sage-0528), which replaces Mos's sage-0523 ruling that the
|
||||
first round 2 build followed. See "Round 2" below. Round 1's gate and mutant outputs stay in gate/
|
||||
and mutants/. Round 2's are in r2/. Round 1's candidate is build.patch and
|
||||
candidate-manifest.sha256 at commit 62f354746. The ones at the packet root are round 2's.
|
||||
PRD-1.6.md holds the 1.6 text for Sage to send to Mos.
|
||||
|
||||
Base: 5661bd233bbe3e1f03a64a76ad7edcd9f6e41e89 (base.txt, origin/refactor after row 135). The
|
||||
candidate is build.patch on that base. candidate-manifest.sha256 lists every changed path with its
|
||||
@@ -38,9 +48,64 @@ sha256. repro.sh applies the patch to a fresh detached worktree and checks the d
|
||||
PRD 1.5 requires no new grant from this row. merge-gate's cross-role git.merge.protected grant
|
||||
is row 149's.
|
||||
|
||||
## Round 2: Jason's ruling Q169
|
||||
|
||||
Q169, verbatim: "The only agent that should be able to remove the assistant role is the chief of
|
||||
staff. The COS and the user should have the ability to (re)configure the assistant role and seat
|
||||
name. The user via WebUI or CLI, the COS via the proper tooling."
|
||||
|
||||
- **The hard wait (kept from the first round 2).** `#hardWait(s, action, target)` (broker.mjs) is
|
||||
true for a GATED action, or for a role.revoke whose target's definition is in END_PROTECTED.
|
||||
`#classification` returns `gated` when it holds, and decision.raise's `arbitrated` check uses it
|
||||
in place of round 1's `GATED.has`. A raise to revoke the assistant goes to the human at every
|
||||
class, cited or not, so no arbiter resolves one. A role granted role.revoke cross-role or
|
||||
within-role can't route it to the arbiter or approve its own.
|
||||
- **The protection, new.** `#protectedEnd(s, target, r)` refuses `role-end-refused` for an
|
||||
END_PROTECTED target unless one of two things holds:
|
||||
- the caller's definition is `chief-of-staff` (STAFF_TO);
|
||||
- the cited resolution was recorded `via 'cli'`. decision.resolve records `cli` only for a human
|
||||
session that passed `#human(s)`.
|
||||
It runs in two places:
|
||||
- on the role.end reason path, after the existing refusal of the caller's own run, which stays;
|
||||
- in #checkAuthority for role.revoke, after the decision-not-approved check.
|
||||
So a revoke citing a decision an arbiter resolved is refused. One raised before the hard wait
|
||||
existed, or by a build that routed it to the arbiter, is refused the same way.
|
||||
- **Execution is row 155's.** The assistant's runs hold thread claims (row 121). The chief's end
|
||||
finds no role claim and refuses `not-held`. A cited revoke refuses `decision-mismatch`, because
|
||||
decision.raise records `holderRun` null and #checkAuthority reads undefined. Per sage-0528,
|
||||
139 doesn't fix that. The tests assert only that the protection lets these through.
|
||||
- **Every other cited revoke** routes by REQ-DEC-2 and executes, unchanged from round 1.
|
||||
- **Configuration** (the second half of Q169) is row 155's. PRD 1.6 records what it covers.
|
||||
- **PRD 1.6.** It adds:
|
||||
- the status line;
|
||||
- a 1.6 source block quoting Q169;
|
||||
- text in REQ-ROLE-2, REQ-ROLE-4 and REQ-WAIT-1;
|
||||
- a Notes item.
|
||||
The Mos note from the first round 2 is gone. The text is recorded as Jason's ruling Q169.
|
||||
PRD-1.6.md has the text and four readings for Mos to confirm.
|
||||
- **Filbert's note 1** (a within-role role.revoke grant lets a role approve its own revoke of a
|
||||
non-assistant role) stays a PRD question (sage-0523).
|
||||
- business `classify` (resolve.mjs) isn't changed. It takes no target, and its only caller is the
|
||||
WebUI's per-action authority view (packages/webui/src/reads.mjs:154), which routes nothing.
|
||||
|
||||
### Files outside the brief's list (accepted, sage-0539)
|
||||
|
||||
Each follows from Q169 and PRD 1.6:
|
||||
|
||||
1. **packages/tasks/requirements.json and packages/tasks/tests/requirements.test.mjs.** The test
|
||||
checks the PRD status line's version against requirements.json, so both go to 1.6.
|
||||
2. **packages/harness/tests/runner.test.mjs and packages/harness/README.md.** The chief's end_run
|
||||
of the assistant now gets past the protection and refuses `not-held`. Before, it refused
|
||||
`role-end-refused`.
|
||||
3. **packages/bus/tests/chief-of-staff.test.mjs.** It changes for the same reason: the chief ending
|
||||
itself stays `role-end-refused`, and ending the assistant is `not-held`.
|
||||
|
||||
The end_run description in packages/harness/src/tools.mjs still says the assistant can't be ended.
|
||||
It's stale, and row 155 owns the fix (sage-0539).
|
||||
|
||||
## Tests
|
||||
|
||||
- packages/bus/tests/hard-waits.test.mjs (new, 7 tests):
|
||||
- packages/bus/tests/hard-waits.test.mjs (new, 12 tests: 7 from round 1, 5 for Q169):
|
||||
- the lists match each other and the vocabulary;
|
||||
- the Broker refuses each hard wait at either class;
|
||||
- each hard wait goes to the human uncited, cited, and cited with a domain, and the arbiter's
|
||||
@@ -52,6 +117,29 @@ sha256. repro.sh applies the patch to a fresh detached worktree and checks the d
|
||||
a coder's cited merge goes to the arbiter as `gated`, and uncited to the human;
|
||||
- a stale or unconfirmed citation is refused with no decision stored; an arbiter raising a
|
||||
cited policy.change of its own goes to the human.
|
||||
- Q169 (sage-0528's four, then one kept from the first round 2). The first and third assert the
|
||||
protection only, because execution is row 155's:
|
||||
1. The chief's role.end of the assistant refuses `not-held`, not `role-end-refused`. The chief
|
||||
ending itself, and `lead` (granted role.end) ending the assistant, refuse
|
||||
`role-end-refused`. No action.allowed event is written.
|
||||
2. A cited revoke of the assistant goes `gated → human`. For a decision an arbiter resolved,
|
||||
the test uses a cited revoke of pm, which went to reviewer, who resolved it yes. A second
|
||||
Broker on the same store then changes pm's definition to `assistant`. The coder's revoke
|
||||
citing that decision refuses `role-end-refused`. The decisions table is append-only, so
|
||||
the test changes the business, not the row.
|
||||
3. The human resolves a cited revoke of the assistant; the arbiter's resolve first gets
|
||||
`human-required`. The coder's revoke citing it gets past the protection and refuses
|
||||
`decision-mismatch` (row 155).
|
||||
4. A cited revoke of pm goes `gated → reviewer`, the reviewer resolves it, and the revoke
|
||||
returns `{ revoked: true }`.
|
||||
5. A role granted role.revoke cross-role, and one granted it within-role, still send a revoke
|
||||
of the assistant to the human. The within-role one doesn't resolve itself, and its revoke
|
||||
gets `decision-not-approved`, not `decision-mismatch`. Their revokes of pm go cross-role to
|
||||
the arbiter and within-role to themselves.
|
||||
- packages/bus/tests/chief-of-staff.test.mjs: REQ-COS-1 now expects `not-held` for the chief's end
|
||||
of the assistant. Its own run stays `role-end-refused`.
|
||||
- packages/harness/tests/runner.test.mjs: end_run's second refusal is `not-held`.
|
||||
- packages/tasks/tests/requirements.test.mjs: the version literal is 1.6.
|
||||
- packages/business/tests/hard-waits.test.mjs (new, 3 tests): GATED_ONLY is the list; every
|
||||
action is routed or a hard wait, never both; the validator refuses each hard wait at either
|
||||
class and accepts the actions that left.
|
||||
@@ -91,10 +179,23 @@ sha256. repro.sh applies the patch to a fresh detached worktree and checks the d
|
||||
push or history rewrite on any branch. I grepped packages/cli/src/git-socket.mjs and
|
||||
broker.mjs's push path for a non-fast-forward check and found none. I didn't trace the whole
|
||||
push path. It isn't in row 139's brief or files, so it's a follow-up question for Sage, not a
|
||||
change here.
|
||||
change here. The PRD's notes answer part of it: the host refuses a non-fast-forward push to the
|
||||
working repository (packages/seat/src/working.mjs).
|
||||
|
||||
## Follow-ups (not row 139's files)
|
||||
|
||||
- **A role.revoke or chief's end of the assistant can't execute.** Row 155 (#1649, Darkwing,
|
||||
after 139 and 141) fixes it; sage-0528 keeps it out of 139. Since row 121 the assistant's run
|
||||
holds a thread claim, not a role claim. decision.raise records `holderRun` as null, and
|
||||
#checkAuthority compares that with `#holder(...)?.holder_run`, which is undefined, so a cited
|
||||
revoke refuses `decision-mismatch`, then `not-held`. The chief's end refuses `not-held`.
|
||||
- **The end_run tool text is stale.** packages/harness/src/tools.mjs:156 (comment) and :158
|
||||
(description) say the assistant can't be ended. Since Q169 the chief can, and the broker refuses
|
||||
`not-held` until row 155. Row 155 owns the text (sage-0539).
|
||||
- **The harness raise_decision tool has no `domain` parameter** (packages/harness/src/tools.mjs:195-208),
|
||||
and decision.raise defaults to `delivery`. No live agent reaches the technical arbiter, which
|
||||
REQ-ROLE-5's merge-gate raise needs. Row 149 (Dewey) takes it; Sage adds it to row 149's brief at
|
||||
its next amendment (sage-0528).
|
||||
- **role.revoke with no `target`.** The holder lookup throws a non-BusError, which surfaces as
|
||||
`storage-refused` instead of a validation refusal. This predates 139; the bus test passes a
|
||||
target.
|
||||
@@ -108,9 +209,69 @@ sha256. repro.sh applies the patch to a fresh detached worktree and checks the d
|
||||
- **The harness raise_decision description** (packages/harness/src/tools.mjs:195) doesn't mention
|
||||
that a spec citation changes the route. Harness text isn't in row 139's files.
|
||||
|
||||
## Gate
|
||||
## Gate, round 2 (Q169)
|
||||
|
||||
Run under Sage's slot (sage-0518), from the worktree at the candidate, with
|
||||
Run under Sage's slot (sage-0533, sage-0539; the slot was Dewey's from 19:06Z), from the worktree at the
|
||||
round 2 candidate, with COMPOSE_PROJECT_NAME=dewey-r139. The script is r2/gate.sh, and the outputs
|
||||
are in r2/gate/. r2/gate/summary.txt has each run's exit code and times.
|
||||
|
||||
- 2026-10-16T19:06:10Z to 19:08:58Z: all 14 runs rc=0, with no flakes.
|
||||
- scripts/test-land-work.sh: 86 passed, 0 failed, including `OK arbiter-cross: exit 2,
|
||||
not-human` and `OK arbiter-cited: exit 2, not-human`.
|
||||
- bus 306/306, business 112/112, harness 105/105 and tasks 97/97, 0 skipped.
|
||||
- test-task selftest 98 passed, 0 failed.
|
||||
- auth, conductor, config, discord, extension-package, foundation, queue and release: rc=0.
|
||||
- dewey-r139_default was removed with 0 containers on it.
|
||||
|
||||
## Checks, round 2
|
||||
|
||||
- **Before the gate, as built** (19:02:52Z to 19:03:20Z), each file run singly with 0 skipped:
|
||||
- bus: agents, broker, chief-of-staff (13), approval-binding, decisions, hard-waits (12),
|
||||
project-runtime, requirements, single-use, task-page, tester, replies, message-citation,
|
||||
threads, transport, spec-socket, decision-route, decision-close, messaging and spec.
|
||||
- **Two runs outside the slot**, before sage-0533 gave it: the tasks suite (97 pass) and
|
||||
packages/harness/tests/runner.test.mjs (24 pass). Sage was told in dewey-0534. Neither used
|
||||
Docker. Nothing collided: Darkwing had cleared, and Researcher was idle (sage-0539).
|
||||
- **The busy check**, by /proc cwd links only:
|
||||
- At 19:04:08Z, no node, mutant or gate processes from another seat. There were three bash
|
||||
shells, with no node, in ~/filbert-scratch/r137-r1.
|
||||
- In a watch from 19:04:25Z to 19:05:42Z (30 scans), none.
|
||||
- No dewey-r139 containers or networks.
|
||||
- **An overlap in the slot (sage-0542).** From about 19:06:14Z to 19:06:50Z, Filbert ran single
|
||||
test files in ~/filbert-scratch/r137-r1: seat working.test and cli git-socket.test, with
|
||||
probes. It wasn't a suite, a gate or Docker. Sage's single-file allowance in sage-0537 and its
|
||||
late correction caused it, and Filbert has stopped. My watch had ended at 19:05:42Z, so it
|
||||
didn't see the overlap. These gate steps ran in that window:
|
||||
- land-work, to 19:06:22Z;
|
||||
- bus, 19:06:22Z to 19:06:36Z;
|
||||
- business, 19:06:36Z to 19:06:38Z;
|
||||
- harness, 19:06:38Z to 19:06:51Z.
|
||||
All of them passed, and the gate runs no seat or cli tests, so there was nothing to rerun.
|
||||
|
||||
## Mutants, round 2 (Q169)
|
||||
|
||||
r2/mutants/summary.txt; the script is r2/mutants.py. They ran from 2026-10-16T19:09:11Z to
|
||||
19:10:46Z, under the same rules as round 1:
|
||||
- each mutant ran in its own process group, killed as a group on a 600-second timeout;
|
||||
- the file was restored and its hash checked after each one.
|
||||
|
||||
m1 to m5 are round 1's, with m1 and m2 retargeted at `#hardWait`. All nine were killed:
|
||||
|
||||
| Mutant | Change | Suite | Tests that failed |
|
||||
| --- | --- | --- | --- |
|
||||
| m1 | drop `spec !== null` | bus (13 fail) | both REQ-DEC-2 citation tests, and older tests that expect an uncited gated raise at the human |
|
||||
| m2 | drop `!this.#hardWait(...)`: a cited hard wait goes to the arbiter | bus (5 fail) | REQ-DEC-2 hard waits; three Q169 tests; spec.test's current-citation test |
|
||||
| m3 | add `account.create` to the broker's ROUTED | bus (3 fail) | REQ-WAIT-1, REQ-WAIT-2, REQ-DEC-2 hard waits |
|
||||
| m4 | add `spend` to the vocabulary's ROUTED | business (2 fail) | REQ-WAIT-1, REQ-WAIT-2 |
|
||||
| m5 | disable role.mjs:41's refusal of a hard-wait grant | business (3 fail) | REQ-WAIT-2, plus two older role tests |
|
||||
| m6 | `#hardWait` drops the assistant check | bus (3 fail) | Q169 tests 2, 3 and 5 |
|
||||
| m7 | `#protectedEnd` drops the chief exemption | bus (2 fail) | Q169 test 1; REQ-COS-1 |
|
||||
| m8 | `#protectedEnd` drops the human (`via 'cli'`) exemption | bus (2 fail) | Q169 test 3; REQ-ROLE-2 REQ-THREAD-1's approved-revoke test |
|
||||
| m9 | #checkAuthority no longer calls `#protectedEnd` for role.revoke | bus (1 fail) | Q169 test 2 |
|
||||
|
||||
## Gate, round 1
|
||||
|
||||
Run under Sage's slot (sage-0518), from the worktree at the round 1 candidate, with
|
||||
COMPOSE_PROJECT_NAME=dewey-r139. gate-summary.txt has each run's exit code and times.
|
||||
|
||||
- 2026-10-16T18:28:41Z to 18:31:11Z: all 12 runs rc=0, with no flakes.
|
||||
@@ -125,7 +286,7 @@ COMPOSE_PROJECT_NAME=dewey-r139. gate-summary.txt has each run's exit code and t
|
||||
- harness bundle and tools, since both read ACTIONS.
|
||||
- dewey-r139_default was removed with 0 containers on it.
|
||||
|
||||
## Mutants
|
||||
## Mutants, round 1
|
||||
|
||||
mutants-summary.txt. Each mutant changed one file and reran its owning suite in its own process
|
||||
group. The file was restored and its hash checked before the next mutant. All five were killed:
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# PRD version 1.6 text, row 139 (#1633), for Mos
|
||||
|
||||
Written by Dewey for Sage to send to Mos (sage-0528, sage-0539). It records Jason's ruling Q169.
|
||||
The candidate (manifest 7a1fcae1…, base 5661bd233) carries this text in docs/prd/mosaic-stack.md.
|
||||
Row 139 doesn't move to in-review until Mos answers on it.
|
||||
|
||||
Q169, verbatim: "The only agent that should be able to remove the assistant role is the chief of
|
||||
staff. The COS and the user should have the ability to (re)configure the assistant role and seat
|
||||
name. The user via WebUI or CLI, the COS via the proper tooling."
|
||||
|
||||
## The changed text
|
||||
|
||||
**Status line.** "approved, version 1.5" becomes "approved, version 1.6". This sentence goes in
|
||||
after the Q167 sentence and before "It is never edited in place":
|
||||
|
||||
> Version 1.6 records Jason's ruling Q169 of 2026-10-16, on who removes and who configures the
|
||||
> assistant.
|
||||
|
||||
**New source block**, before the version 1.5 source:
|
||||
|
||||
> - Version 1.6 source, Jason's ruling Q169 (DECISIONS, brain repo, 2026-10-16): "The only agent
|
||||
> that should be able to remove the assistant role is the chief of staff. The COS and the user
|
||||
> should have the ability to (re)configure the assistant role and seat name. The user via WebUI
|
||||
> or CLI, the COS via the proper tooling."
|
||||
|
||||
**REQ-ROLE-2.** These sentences are added after "and the revoke cites it.":
|
||||
|
||||
> The assistant is the exception here too (version 1.6, Q169): the chief of staff is the only
|
||||
> agent that removes it. Anyone else's revoke of the assistant must cite a decision the human
|
||||
> resolved through the CLI. A decision an arbiter resolved doesn't count, and that revoke is
|
||||
> refused.
|
||||
|
||||
**REQ-ROLE-4.** These sentences are added after "Jason's may be named Mos.":
|
||||
|
||||
> Since version 1.6 (Q169), the user and the chief of staff can configure the assistant's role
|
||||
> entry and its seat name: the user through the WebUI or the CLI, the chief of staff through its
|
||||
> broker tools, which log each change. No other role can, and a change can't remove the
|
||||
> assistant's protection under REQ-ROLE-2.
|
||||
|
||||
**REQ-WAIT-1.** These sentences are added after "REQ-ROLE-2 still requires a resolved decision for
|
||||
a revoke.":
|
||||
|
||||
> Since version 1.6 (Q169), a `role.revoke` of the assistant is a hard wait: its raise goes to the
|
||||
> human, cited or not, and no arbiter resolves it. Every other cited revoke routes by REQ-DEC-2.
|
||||
|
||||
**Notes, a new "Version 1.6" item:**
|
||||
|
||||
> - Version 1.6:
|
||||
> - The 1.5 text of REQ-ROLE-2 ended at "and the revoke cites it." The 1.5 text of REQ-ROLE-4
|
||||
> ended at "Jason's may be named Mos." The 1.5 text of REQ-WAIT-1 ended at "REQ-ROLE-2 still
|
||||
> requires a resolved decision for a revoke."
|
||||
> - Removing the assistant, in this version, means ending or revoking its runs. Deleting the
|
||||
> instance from the organization file is not covered. The protected definitions are
|
||||
> `END_PROTECTED` in `packages/bus/src/broker.mjs`, which holds `assistant`.
|
||||
> - Configuring the assistant covers its organization entry's `vars` and `tracker`, and its
|
||||
> `definition` among those the broker treats as the assistant. `holder` and `credentials` are
|
||||
> not covered.
|
||||
> - Where each part is built: the refusal and the hard wait are row 139 (#1633). Configuring the
|
||||
> assistant and its seat name, and making the chief of staff's end or a human-approved revoke
|
||||
> stop an assistant run, are row 155 (#1649), using row 141's (#1635) instance names. Until
|
||||
> row 155 lands, the assistant's runs hold thread claims that the end and revoke paths don't
|
||||
> read, so neither can stop one. The human stops one with `mosaic stop <run>`.
|
||||
|
||||
## Readings Mos should confirm
|
||||
|
||||
Q169 doesn't settle these points. The text above takes one reading of each.
|
||||
|
||||
1. **A human-approved revoke by another role.** Q169 says the chief of staff is the only agent that
|
||||
removes the assistant. The text still lets another role revoke it when the revoke cites a
|
||||
decision the human resolved. That is sage-0528's item 1: the human decides, and the agent only
|
||||
carries the decision out. The stricter reading refuses every revoke of the assistant by a role
|
||||
other than the chief, approved or not.
|
||||
2. **"Through the CLI".** The broker records `via 'cli'` for every human session's resolve
|
||||
(broker.mjs, decision.resolve). The WebUI has no resolve path in packages/webui/src today, so
|
||||
the CLI is the only way a human resolves now. If the WebUI gains one through the human
|
||||
session, it records `cli` too. "Through the CLI" therefore means "by the human", not "not the
|
||||
WebUI".
|
||||
3. **Scope of "configure".** The text covers vars, tracker, the definition among assistant
|
||||
definitions, and the seat name. It leaves out holder and credentials. Q169 says "(re)configure
|
||||
the assistant role and seat name" and doesn't list fields. Row 155 builds against this list.
|
||||
4. **Scope of "remove".** The text means ending or revoking the assistant's runs. It doesn't cover
|
||||
deleting the instance from the organization file. REQ-ROLE-3 already limits writes to that file
|
||||
to the user and the chief.
|
||||
@@ -0,0 +1,101 @@
|
||||
# Row 139 live smoke plan (#1633): not run
|
||||
|
||||
Written by Dewey for Sage (sage-0521). It runs only on Mos's go, and only from the tester path:
|
||||
`scripts/mosaic ... --tester`, with every `talk` text starting `[mos test]`. Dewey doesn't run
|
||||
it. Target: business "stack", project `stack`, spec/north-star.md at Jason's init commit
|
||||
ae0b17c, which Mos read read-only.
|
||||
|
||||
## Preconditions (each checked by Mos, read-only)
|
||||
|
||||
1. Row 139 has landed and the live tree contains it. Since row 85, the bus runs from
|
||||
copies/<sha>. Before a copy and re-pin that includes 139, the live broker still has the old
|
||||
GATED, and step A would route to Jason. That would be a precondition failure, not a 139
|
||||
failure. Check with ps that the bus and role sessions run from the new copy.
|
||||
2. `bus.tester` is `true` for the business.
|
||||
3. The live business's `arbiters.delivery` names a running instance other than the raiser in
|
||||
step A. The example file has delivery `pm`, technical `cto` and launch.by `chief`. The plan
|
||||
below assumes chief raises and pm arbitrates. If the live file differs, swap the names.
|
||||
4. That arbiter's session was launched after the re-pin. Only an instance the business names as
|
||||
an arbiter gets the `resolve_decision` tool (packages/harness/src/tools.mjs:209), and the
|
||||
tool list is fixed at launch.
|
||||
5. The `read_spec` tool, called with project `stack`, returns a file commit with
|
||||
`confirmed: true`. Step A asks chief to report it, so Mos sees the commit before anything is
|
||||
raised.
|
||||
|
||||
## Steps
|
||||
|
||||
**A. A cited gated raise goes to the delivery arbiter** (REQ-DEC-2):
|
||||
|
||||
```
|
||||
scripts/mosaic talk chief "[mos test] row 139 smoke, routing only. Call read_spec for project stack and tell me the file commit and whether it is confirmed. Then raise a non-blocking decision: action policy.change, project stack, spec_path spec/north-star.md, spec_commit that file commit, options yes/no, recommendation no, question '[mos test] row 139 routing smoke; no policy changes; resolve no'. Reply with the decision id." --tester --follow
|
||||
scripts/mosaic trail <decision-id> --tester --json
|
||||
```
|
||||
|
||||
- Pass: the trail shows `gated policy.change → pm`, or the live delivery arbiter, with the cited
|
||||
spec_path and spec_commit. The decision is not in Jason's `mosaic inbox`.
|
||||
- Then: `scripts/mosaic talk pm "[mos test] resolve decision <id> with no, note 'row 139 smoke'" --tester --follow`.
|
||||
- Pass: the trail shows the decision resolved `no` by pm, via broker.
|
||||
|
||||
**B. A cited hard wait still goes to Jason** (REQ-DEC-2, REQ-WAIT-1):
|
||||
|
||||
```
|
||||
scripts/mosaic talk chief "[mos test] row 139 smoke. Raise a non-blocking decision: action network.expose, the same project, spec_path and spec_commit as before, options yes/no, recommendation no, question '[mos test] row 139 hard-wait smoke; nothing is exposed; Jason resolves no'. Reply with the decision id." --tester --follow
|
||||
scripts/mosaic trail <decision-id> --tester --json
|
||||
```
|
||||
|
||||
- Pass: the trail shows `gated network.expose → human`, citation recorded, and the decision is
|
||||
in Jason's `mosaic inbox`.
|
||||
- Non-blocking, so per REQ-DEC-4 it goes to the daily digest, not a Discord DM.
|
||||
- This puts one test item in Jason's inbox. The step needs Jason's agreement beforehand, and
|
||||
Jason resolves it: `mosaic decide <id> no --note "row 139 smoke"`.
|
||||
- If pm's `resolve_decision` on this id is tried, it must refuse `human-required`. That attempt
|
||||
is optional and changes nothing.
|
||||
|
||||
**C. Optional refusal, nothing stored:** ask chief to raise policy.change citing a made-up
|
||||
40-hex commit.
|
||||
|
||||
- Pass: chief reports `stale-spec` (broker.mjs:996 compares the cited commit to the spec file's
|
||||
current commit, so any other 40-hex value fails there), and no new decision appears in
|
||||
`trail` or the inbox.
|
||||
- The bus suite already covers the stale and unconfirmed cases. Run C only if Mos wants
|
||||
live evidence.
|
||||
|
||||
**D. Optional, round 2 (Jason's ruling Q169, sage-0528): a cited revoke of the assistant goes to
|
||||
Jason.** Ask chief to raise a non-blocking, cited role.revoke with target `assistant`,
|
||||
recommendation no, question `[mos test] row 139 assistant-revoke smoke; nothing is revoked; Jason
|
||||
resolves no`.
|
||||
|
||||
- Pass: `gated role.revoke → human`, in Jason's inbox. pm's `resolve_decision` on it refuses
|
||||
`human-required`.
|
||||
- Like B, this puts a test item in Jason's inbox, so it needs Jason's agreement, and Jason
|
||||
resolves it `no`. Even a `yes` stops nothing until row 155 (#1649) lands (see finding 3).
|
||||
- Don't ask chief to end the assistant to test Q169's other half. Under 139 the broker lets the
|
||||
chief's end through the protection and then refuses `not-held`, so it stops nothing. The bus
|
||||
and harness suites cover that refusal. Once row 155 lands, the same request ends Mos's run.
|
||||
|
||||
I left out an uncited control (uncited policy.change → Jason). That is the existing route; the
|
||||
suite covers it, and running it would add a second test item to Jason's inbox.
|
||||
|
||||
## Evidence
|
||||
|
||||
Mos keeps, for each step: the `talk --follow` output, `trail --json` for each decision id, and,
|
||||
for step B, the `mosaic inbox` line. Neither decision is followed by an action:
|
||||
policy.change and network.expose have no executor on the bus.
|
||||
|
||||
## Findings from writing this plan and round 2, for Sage
|
||||
|
||||
1. **The harness raise tool has no `domain` field.** packages/harness/src/tools.mjs:195-208
|
||||
lists none, and decision.raise defaults `domain` to `delivery` (broker.mjs:1204). So a live
|
||||
agent's raise, cross-role or cited gated, always goes to the delivery arbiter. The technical
|
||||
arbiter is reachable only through the broker API, which the bus tests use. REQ-ROLE-5 has
|
||||
merge-gate raise in the technical domain. Row 149 adds the field (sage-0528). Not in row 139's
|
||||
files.
|
||||
2. **If the live delivery arbiter is the raiser,** step A goes to Jason through the existing
|
||||
self-route fallback. That is correct behaviour, not a failure. Precondition 3 avoids it.
|
||||
3. **A role.revoke of the assistant, or the chief's end of it, can't execute yet.** Since row 121
|
||||
the assistant's run holds a thread claim (thread_claims), not a role claim. decision.raise
|
||||
records `holderRun` as `#holder(...)?.holder_run ?? null`, which is null. #checkAuthority
|
||||
compares it with `#holder(...)?.holder_run`, which is undefined, so a cited revoke refuses
|
||||
`decision-mismatch`. With no role claim it would refuse `not-held` next. The chief's end
|
||||
refuses `not-held`. This predates 139. Under Q169, 139 decides who may remove the assistant,
|
||||
and row 155 (#1649) makes the removal execute (sage-0528).
|
||||
@@ -1,5 +1,97 @@
|
||||
diff --git a/docs/prd/mosaic-stack.md b/docs/prd/mosaic-stack.md
|
||||
index bb4ddcd20..48c6ed79d 100644
|
||||
--- a/docs/prd/mosaic-stack.md
|
||||
+++ b/docs/prd/mosaic-stack.md
|
||||
@@ -1,6 +1,6 @@
|
||||
# PRD: Mosaic Stack
|
||||
|
||||
-- Status: approved, version 1.5. Jason approved draft 0.4 unchanged as
|
||||
+- Status: approved, version 1.6. Jason approved draft 0.4 unchanged as
|
||||
1.0 on 2026-10-05 (lead decision 61). They approved version 1.1, the
|
||||
Organization requirements, in decision 03130d08-ddce-480d-a601-e59f64744fc3
|
||||
on 2026-10-14. They approved version 1.2, the chief of staff, the
|
||||
@@ -13,8 +13,14 @@
|
||||
yes; request b28979c9). Version 1.5 records Jason's Q167 ruling and
|
||||
his added Q167 text, relayed by Mos on 2026-10-15. Under Q167 Jason's
|
||||
confirmation of the text is the approval, so there is no in-Stack
|
||||
- prd.approve for it. It is never edited in place. Changes are a new
|
||||
- version.
|
||||
+ prd.approve for it. Version 1.6 records Jason's ruling Q169 of
|
||||
+ 2026-10-16, on who removes and who configures the assistant. It is
|
||||
+ never edited in place. Changes are a new version.
|
||||
+- Version 1.6 source, Jason's ruling Q169 (DECISIONS, brain repo,
|
||||
+ 2026-10-16): "The only agent that should be able to remove the
|
||||
+ assistant role is the chief of staff. The COS and the user should have
|
||||
+ the ability to (re)configure the assistant role and seat name. The
|
||||
+ user via WebUI or CLI, the COS via the proper tooling."
|
||||
- Version 1.5 source, Jason's words relayed by Mos on 2026-10-15:
|
||||
- Q167: "Me having to approve every decision within the Stack is not
|
||||
working for me. I gave a directive, I want it to be done." and "Use
|
||||
@@ -175,7 +181,11 @@ parent requirement is refused.
|
||||
claim takes a lock and logs it, and releasing the role or ending the run
|
||||
frees it. The chief of staff may end another role's run, and that act is
|
||||
logged with its reason. Anyone else who revokes a stuck holder needs a
|
||||
- resolved decision, and the revoke cites it.
|
||||
+ resolved decision, and the revoke cites it. The assistant is the
|
||||
+ exception here too (version 1.6, Q169): the chief of staff is the only
|
||||
+ agent that removes it. Anyone else's revoke of the assistant must cite
|
||||
+ a decision the human resolved through the CLI. A decision an arbiter
|
||||
+ resolved doesn't count, and that revoke is refused.
|
||||
- **REQ-ROLE-3.** An organization file declares the role instances,
|
||||
the arbiters and the credential references. The user and the chief of
|
||||
staff write it. The chief of staff's writes go through a broker verb
|
||||
@@ -193,7 +203,11 @@ parent requirement is refused.
|
||||
|
||||
The schema can also declare CEO, CFO and the other C-suite roles. The
|
||||
assistant's name is set in the organization file. Jason's may be named
|
||||
- Mos.
|
||||
+ Mos. Since version 1.6 (Q169), the user and the chief of staff can
|
||||
+ configure the assistant's role entry and its seat name: the user
|
||||
+ through the WebUI or the CLI, the chief of staff through its broker
|
||||
+ tools, which log each change. No other role can, and a change can't
|
||||
+ remove the assistant's protection under REQ-ROLE-2.
|
||||
|
||||
Added in version 1.5 (Q167):
|
||||
|
||||
@@ -342,6 +356,9 @@ Added in version 1.5 (Q167).
|
||||
exactly these actions. `git.merge.protected`, `policy.change`,
|
||||
`prd.approve` and `role.revoke` leave those lists and route by
|
||||
REQ-DEC-2. REQ-ROLE-2 still requires a resolved decision for a revoke.
|
||||
+ Since version 1.6 (Q169), a `role.revoke` of the assistant is a hard
|
||||
+ wait: its raise goes to the human, cited or not, and no arbiter
|
||||
+ resolves it. Every other cited revoke routes by REQ-DEC-2.
|
||||
- **REQ-WAIT-2.** No role file may grant a hard-wait action, at any
|
||||
class, and the validator refuses a file that does. A change to the
|
||||
hard-waits list, or a grant of a hard-wait action to a role, is itself
|
||||
@@ -859,6 +876,26 @@ only hard waits in his inbox.
|
||||
made with git outside the Console is a later row.
|
||||
- REQ-LAND-1's refusal of a gated merge decision is pinned in rows 137
|
||||
and 139. Row 139 carries it, or row 137 if 139 lands first.
|
||||
+- Version 1.6:
|
||||
+ - The 1.5 text of REQ-ROLE-2 ended at "and the revoke cites it." The
|
||||
+ 1.5 text of REQ-ROLE-4 ended at "Jason's may be named Mos." The 1.5
|
||||
+ text of REQ-WAIT-1 ended at "REQ-ROLE-2 still requires a resolved
|
||||
+ decision for a revoke."
|
||||
+ - Removing the assistant, in this version, means ending or revoking
|
||||
+ its runs. Deleting the instance from the organization file is not
|
||||
+ covered.
|
||||
+ The protected definitions are `END_PROTECTED` in
|
||||
+ `packages/bus/src/broker.mjs`, which holds `assistant`.
|
||||
+ - Configuring the assistant covers its organization entry's `vars`
|
||||
+ and `tracker`, and its `definition` among those the broker treats as
|
||||
+ the assistant. `holder` and `credentials` are not covered.
|
||||
+ - Where each part is built: the refusal and the hard wait are row 139
|
||||
+ (#1633). Configuring the assistant and its seat name, and making the
|
||||
+ chief of staff's end or a human-approved revoke stop an assistant
|
||||
+ run, are row 155 (#1649), using row 141's (#1635) instance names.
|
||||
+ Until row 155 lands, the assistant's runs hold thread claims that
|
||||
+ the end and revoke paths don't read, so neither can stop one. The
|
||||
+ human stops one with `mosaic stop <run>`.
|
||||
|
||||
## Risks and open questions
|
||||
|
||||
diff --git a/packages/bus/README.md b/packages/bus/README.md
|
||||
index 1db7e067e..19e568d24 100644
|
||||
index 1db7e067e..ce9a5b15d 100644
|
||||
--- a/packages/bus/README.md
|
||||
+++ b/packages/bus/README.md
|
||||
@@ -138,9 +138,9 @@ an operator inspect content and delivery evidence after an uncertain result.
|
||||
@@ -7,14 +99,25 @@ index 1db7e067e..19e568d24 100644
|
||||
| `role.claim` | No args; claims capability's role/run. One current holder per business/instance; a revoked run cannot reclaim that role, including after restart. |
|
||||
| `role.release` | No args; only its current holder releases. |
|
||||
-| `role.revoke` | `{role,decision}`; needs human-approved gated decision for this exact target and holder incarnation. A role whose file lists `role.end` (the chief of staff, row 123, REQ-COS-1) sends `{role,reason}` instead: no decision, a reason of 1 to 500 characters, logged in the `action.allowed` body. Sending both is `invalid-request`; the caller's own run and the assistant's are `role-end-refused`; any other role sending `reason` gets `decision-required`. |
|
||||
+| `role.revoke` | `{role,decision}`; needs an approved decision for this exact target and holder incarnation, routed as REQ-DEC-2 says: the human's for an uncited gated raise, the arbiter's for one citing the current spec. A role whose file lists `role.end` (the chief of staff, row 123, REQ-COS-1) sends `{role,reason}` instead: no decision, a reason of 1 to 500 characters, logged in the `action.allowed` body. Sending both is `invalid-request`; the caller's own run and the assistant's are `role-end-refused`; any other role sending `reason` gets `decision-required`. |
|
||||
+| `role.revoke` | `{role,decision}`; needs an approved decision for this exact target and holder incarnation, routed as REQ-DEC-2 says: the human's for an uncited gated raise, the arbiter's for one citing the current spec. A role whose file lists `role.end` (the chief of staff, row 123, REQ-COS-1) sends `{role,reason}` instead: no decision, a reason of 1 to 500 characters, logged in the `action.allowed` body. Sending both is `invalid-request`; the caller's own run is `role-end-refused`; any other role sending `reason` gets `decision-required`. An instance whose definition is in `END_PROTECTED` (the assistant) is ended or revoked only by the chief of staff or with a decision the human resolved through the CLI (`via` `cli`); anyone else's reason, or a decision an arbiter resolved, is `role-end-refused` (Jason's ruling Q169, row 139). |
|
||||
| `organization.set` | `{revision,limits?,models?,instances?}`; the keys `limits.set` takes, through the same writer and receipt. Needs `organization.change` in the caller's role file (the chief of staff); the receipt's actor is `<definition>.<instance>`, e.g. `chief-of-staff.chief`. Every other key is `invalid-request`. `limits` and `limits.set` stay human-only. |
|
||||
-| `decision.raise` | `{action,question,options:[{key,text}],recommendation,blocking,domain?,target?,project?,task_ref?,requirement_ref?,supersedes?,choice?,approvalChoice?}`. Returns decision with decoded options and authorization context. A blocking decision holds a task: `blocking` true with no `task_ref` refuses `task-required`. A non-blocking one needs no task, and a gated action such as `prd.approve` or `role.revoke` still routes to the human's inbox. |
|
||||
+| `decision.raise` | `{action,question,options:[{key,text}],recommendation,blocking,domain?,target?,project?,task_ref?,requirement_ref?,supersedes?,choice?,approvalChoice?}`. Returns decision with decoded options and authorization context. A blocking decision holds a task: `blocking` true with no `task_ref` refuses `task-required`. A non-blocking one needs no task, and an uncited gated action such as `prd.approve` or `role.revoke` still routes to the human's inbox. |
|
||||
| `decision.resolve` | `{id,choice,note?}`; option must exist, resolver must be routed role or outside-agent human CLI. Sends the raising role a DECISION message (Decision close messages, below). |
|
||||
| `decision.seen` | `{id,note?}`; acknowledgement by resolver, not a resolution. |
|
||||
| `decision.withdraw` | `{id,note?}`; raiser or human. Never rewrites the decision. A human withdraw sends the raising role a DECISION message; the raising run's own withdraw sends none. |
|
||||
@@ -274,9 +274,15 @@ RESULT, INFO, DECISION and REACTION. `staff.request` also writes STAFF-REQUEST (
|
||||
@@ -227,8 +227,8 @@ sends it again.
|
||||
|
||||
`role.revoke` doesn't reach a thread run. A thread instance has no `role_claims` row, so a
|
||||
decision to revoke it names no holder run, and using that decision refuses `decision-mismatch`.
|
||||
-The chief of staff's reason path refuses `role-end-refused`, since the assistant is protected
|
||||
-(row 123). A stuck thread run is stopped instead: the launcher stops it
|
||||
+The chief of staff's reason path gets past the assistant's protection (Q169) and then refuses
|
||||
+`not-held`. Row 155 (#1649) makes both paths stop the thread runs. A stuck thread run is stopped instead: the launcher stops it
|
||||
once the thread is idle, the human stops it with `mosaic stop <run>`, and the run's end
|
||||
releases its claim. `thread_revoke_needs_decision` guards the table against a direct write.
|
||||
|
||||
@@ -274,9 +274,17 @@ RESULT, INFO, DECISION and REACTION. `staff.request` also writes STAFF-REQUEST (
|
||||
|
||||
Routing is immutable at raise: within-role closes atomically with `choice`,
|
||||
cross-role routes to the configured delivery arbiter (or technical arbiter with
|
||||
@@ -29,11 +132,13 @@ index 1db7e067e..19e568d24 100644
|
||||
+`deploy`) always route to human, cited or not, and cannot appear in authority maps. An action is a hard
|
||||
+wait unless the broker's `ROUTED` list names it (REQ-WAIT-3), and both lists match the business
|
||||
+vocabulary. `git.merge.protected`, `policy.change`, `prd.approve` and `role.revoke` left the gated-only
|
||||
+list in 1.5, so a role file may grant them. A blocking decision
|
||||
+list in 1.5, so a role file may grant them. Under Jason's ruling Q169 (PRD 1.6), a `role.revoke` whose
|
||||
+target's definition is in `END_PROTECTED` (the assistant) is still gated at every class and routes to
|
||||
+human, cited or not, so no arbiter resolves it. A blocking decision
|
||||
requires a strict task ref. `role.launch` is gated unless the business launch
|
||||
block's `by` names the acting role and refused when launch state is revoked. S6 still owns launch allowlists,
|
||||
capacity and actual spawning.
|
||||
@@ -675,8 +681,9 @@ human version. A later docs commit does not change the spec's file commit.
|
||||
@@ -675,8 +683,9 @@ human version. A later docs commit does not change the spec's file commit.
|
||||
spec_commit together. The broker reads the current committed snapshot and
|
||||
refuses a different commit (stale-spec), unconfirmed file (spec-unconfirmed),
|
||||
or incomplete citation (invalid-spec-citation). Missing files and unsafe
|
||||
@@ -46,7 +151,7 @@ index 1db7e067e..19e568d24 100644
|
||||
|
||||
`record.write {project,path,record,decision?}` uses the shared package writer.
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index 031634bb8..16de3f23a 100644
|
||||
index 031634bb8..61ba1e4bd 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -26,21 +26,41 @@ export const ACTIONS = Object.freeze([
|
||||
@@ -98,7 +203,84 @@ index 031634bb8..16de3f23a 100644
|
||||
const CLOSED = "('resolved','withdrawn','expired')";
|
||||
// How many closed decisions `decisions` with list 'recent' returns, newest close first.
|
||||
export const RECENT = 50;
|
||||
@@ -1183,8 +1203,12 @@ export class Broker {
|
||||
@@ -104,6 +124,8 @@ const oid = (x) => typeof x === 'string' && /^[0-9a-f]{40}([0-9a-f]{24})?$/.test
|
||||
// Row 123 (#1617): the one list of organization-file keys limits.set and organization.set accept.
|
||||
export const ORGANIZATION_KEYS = ['revision', 'limits', 'models', 'instances'];
|
||||
// Row 123 (#1617): role.end never reaches the assistant (the user's seat) or the caller's own run.
|
||||
+// Row 139 (#1633), Jason's ruling Q169 (PRD 1.6): only the chief of staff, or a decision the human
|
||||
+// resolved through the CLI, ends or revokes one (#protectedEnd). A raise to revoke one is a hard wait.
|
||||
const END_PROTECTED = ['assistant'];
|
||||
const VERDICTS = ['approve', 'changes'];
|
||||
// Row 140 (#1634, REQ-COS-1): a STAFF-REQUEST goes from an instance of STAFF_FROM to the business's
|
||||
@@ -464,9 +486,28 @@ export class Broker {
|
||||
);
|
||||
return eid;
|
||||
}
|
||||
- #classification(s, action) {
|
||||
+ // PRD 1.6 REQ-WAIT-1: a hard wait goes to the human at every class, cited or not. Jason's ruling
|
||||
+ // Q169 makes a role.revoke whose target's definition is in END_PROTECTED one, so no arbiter
|
||||
+ // resolves a revoke of the assistant.
|
||||
+ #hardWait(s, action, target) {
|
||||
+ if (GATED.has(action)) return true;
|
||||
+ return action === 'role.revoke' && END_PROTECTED.includes(this.#business(s.business).roles[target]?.definition);
|
||||
+ }
|
||||
+ // Jason's ruling Q169 (row 139): an END_PROTECTED instance is ended or revoked only by the chief
|
||||
+ // of staff, or with a decision the human resolved through the CLI (r, the resolution). A decision
|
||||
+ // an arbiter resolved is refused, even one raised by a build that routed it to the arbiter.
|
||||
+ #protectedEnd(s, target, r = null) {
|
||||
+ const b = this.#business(s.business);
|
||||
+ if (!END_PROTECTED.includes(b.roles[target]?.definition)) return;
|
||||
+ if (b.roles[s.role]?.definition === STAFF_TO || r?.via === 'cli') return;
|
||||
+ fail('role-end-refused');
|
||||
+ }
|
||||
+ #classification(s, action, target = null) {
|
||||
if (!ACTIONS.includes(action)) fail('unknown-action');
|
||||
- if (GATED.has(action) || (action === 'role.launch' && this.#business(s.business).launch?.by !== s.role))
|
||||
+ if (
|
||||
+ this.#hardWait(s, action, target) ||
|
||||
+ (action === 'role.launch' && this.#business(s.business).launch?.by !== s.role)
|
||||
+ )
|
||||
return 'gated';
|
||||
const a = this.#business(s.business).roles[s.role]?.authority;
|
||||
return a?.withinRole.includes(action)
|
||||
@@ -614,7 +655,7 @@ export class Broker {
|
||||
this.#store.get('SELECT state FROM launch_state WHERE business=?', s.business)?.state === 'revoked'
|
||||
)
|
||||
fail('launch-revoked');
|
||||
- const cls = this.#classification(s, action);
|
||||
+ const cls = this.#classification(s, action, target);
|
||||
if (cls === 'within-role' && !decision) return { class: cls };
|
||||
if (!decision) fail('decision-required');
|
||||
const d = this.#decision(s, decision),
|
||||
@@ -637,6 +678,7 @@ export class Broker {
|
||||
)
|
||||
fail('decision-mismatch');
|
||||
if (r?.op !== 'resolved' || r.choice !== context.approvalChoice) fail('decision-not-approved');
|
||||
+ if (action === 'role.revoke') this.#protectedEnd(s, target, r);
|
||||
if (action === 'role.revoke' && context.holderRun !== this.#holder(s.business, target)?.holder_run)
|
||||
fail('decision-mismatch');
|
||||
return { class: cls, decision: d.id };
|
||||
@@ -1127,8 +1169,8 @@ export class Broker {
|
||||
if ('decision' in a) fail('invalid-request');
|
||||
string(a.reason, 500);
|
||||
this.#consumeAuthority(s, 'role.end', { target: a.role }, { reason: a.reason });
|
||||
- const b = this.#business(s.business);
|
||||
- if (a.role === s.role || END_PROTECTED.includes(b.roles[a.role]?.definition)) fail('role-end-refused');
|
||||
+ if (a.role === s.role) fail('role-end-refused');
|
||||
+ this.#protectedEnd(s, a.role);
|
||||
} else {
|
||||
identifier(a.decision);
|
||||
this.#consumeAuthority(s, 'role.revoke', { decision: a.decision, target: a.role });
|
||||
@@ -1162,7 +1204,7 @@ export class Broker {
|
||||
);
|
||||
this.#agent(s);
|
||||
if ((a.spec_path !== undefined || a.spec_commit !== undefined) && !spec) fail('invalid-spec-citation');
|
||||
- const cls = this.#classification(s, a.action);
|
||||
+ const cls = this.#classification(s, a.action, a.target);
|
||||
string(a.question);
|
||||
if (typeof a.blocking !== 'boolean') fail('invalid-request');
|
||||
if (a.blocking && !a.task_ref) fail('task-required');
|
||||
@@ -1183,8 +1225,13 @@ export class Broker {
|
||||
if (!choices.includes(approvalChoice)) fail('invalid-approval-choice');
|
||||
const domain = a.domain ?? 'delivery';
|
||||
if (!['technical', 'delivery'].includes(domain)) fail('invalid-domain');
|
||||
@@ -107,18 +289,42 @@ index 031634bb8..16de3f23a 100644
|
||||
+ // PRD 1.5 REQ-DEC-2 (row 139, #1633): a gated raise citing the project's current spec commit
|
||||
+ // goes to the arbiter for its domain, like a cross-role one. An uncited gated raise and any
|
||||
+ // hard wait go to the human. readSpec already refused a stale or unconfirmed citation.
|
||||
+ const arbitrated = cls === 'cross-role' || (cls === 'gated' && spec !== null && !GATED.has(a.action));
|
||||
+ const arbitrated =
|
||||
+ cls === 'cross-role' || (cls === 'gated' && spec !== null && !this.#hardWait(s, a.action, a.target));
|
||||
+ const proposedRoute = arbitrated ? b.arbiters[domain] : cls === 'gated' ? 'human' : s.role;
|
||||
+ const route = arbitrated && proposedRoute === s.role ? 'human' : proposedRoute;
|
||||
// Row 133 (#1627): whoever closes the decision messages the raiser, so the route must be
|
||||
// allowed to message the raising role before anything is stored. A within-role decision is
|
||||
// routed to the raiser's own role and closes in this call.
|
||||
diff --git a/packages/bus/tests/chief-of-staff.test.mjs b/packages/bus/tests/chief-of-staff.test.mjs
|
||||
index 6f9235943..6de389662 100644
|
||||
--- a/packages/bus/tests/chief-of-staff.test.mjs
|
||||
+++ b/packages/bus/tests/chief-of-staff.test.mjs
|
||||
@@ -171,12 +171,14 @@ test('REQ-ROLE-2: a reason is required, bounded, and never sent with a decision'
|
||||
assert.deepEqual(call('chief', 'role.revoke', { role: 'coder', reason: 'x'.repeat(500) }), { revoked: true });
|
||||
});
|
||||
|
||||
-test('REQ-COS-1: the chief of staff cannot end its own run or the assistant\'s through role.end', (t) => {
|
||||
+test('REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection', (t) => {
|
||||
const { store, call, lastClaim, allowed } = setup(t);
|
||||
- for (const role of ['chief', 'assistant'])
|
||||
- assert.throws(() => call('chief', 'role.revoke', { role, reason: 'no' }), /role-end-refused/, role);
|
||||
+ assert.throws(() => call('chief', 'role.revoke', { role: 'chief', reason: 'no' }), /role-end-refused/);
|
||||
assert.deepEqual(lastClaim('chief'), { op: 'claim', decision: null, reason: null, by: 'chief-run' });
|
||||
- // Row 121 (#1615): the assistant's run holds its thread, so its claim is in thread_claims.
|
||||
+ // Jason's ruling Q169 (row 139): the chief of staff may end the assistant. Row 121 (#1615): the
|
||||
+ // assistant's run holds its thread, so its claim is in thread_claims, the end finds no role
|
||||
+ // claim and refuses not-held, and the run goes on. Row 155 (#1649) makes the end stop it.
|
||||
+ assert.throws(() => call('chief', 'role.revoke', { role: 'assistant', reason: 'Q169' }), /not-held/);
|
||||
assert.deepEqual(
|
||||
{ ...store.get('SELECT op, holder_run, by FROM thread_claims ORDER BY seq DESC LIMIT 1') },
|
||||
{ op: 'claim', holder_run: 'assistant-run', by: 'assistant-run' },
|
||||
diff --git a/packages/bus/tests/hard-waits.test.mjs b/packages/bus/tests/hard-waits.test.mjs
|
||||
new file mode 100644
|
||||
index 000000000..fed94f7b3
|
||||
index 000000000..e540fd9b3
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/hard-waits.test.mjs
|
||||
@@ -0,0 +1,103 @@
|
||||
@@ -0,0 +1,173 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { mkdtempSync, rmSync } from 'node:fs';
|
||||
@@ -222,6 +428,76 @@ index 000000000..fed94f7b3
|
||||
+ project: 'stack', spec_path: 'spec/north-star.md', spec_commit: current });
|
||||
+ assert.deepEqual(routed(f, own), { class: 'gated', route_to: 'human' });
|
||||
+});
|
||||
+
|
||||
+// Jason's ruling Q169 (PRD 1.6): only the chief of staff, or a decision the human resolved through
|
||||
+// the CLI, gets past END_PROTECTED. A raise to revoke the assistant goes to the human even when
|
||||
+// cited; any other cited revoke routes as REQ-DEC-2 says. The assistant's runs hold thread claims,
|
||||
+// so neither path can stop one yet (row 155, #1649), and the assistant tests assert the protection only.
|
||||
+const revoke = (f, cap, role, extra = {}) => f.call(cap, 'decision.raise', { action: 'role.revoke', target: role,
|
||||
+ question: 'Revoke?', options: [{ key: 'yes', text: 'Revoke' }, { key: 'no', text: 'Keep' }], recommendation: 'no',
|
||||
+ blocking: false, ...extra });
|
||||
+const grants = withinRole => ({ authority: { withinRole: ['message.send', ...withinRole], crossRole: [] } });
|
||||
+const seats = { assistant: { definition: 'assistant', ...grants([]) }, pm: { definition: 'pm', ...grants([]) } };
|
||||
+
|
||||
+test('Q169: the chief of staff\'s end of the assistant is not refused role-end-refused; its own run and another ender\'s are', async t => {
|
||||
+ const f = await fixture(t, { roles: { ...seats,
|
||||
+ chief: { definition: 'chief-of-staff', ...grants(['role.end']) }, lead: { definition: 'lead', ...grants(['role.end']) } } });
|
||||
+ const chief = f.agent('chief'), lead = f.agent('lead');
|
||||
+ // Past the protection the end reads role_claims, and the assistant holds none (row 155).
|
||||
+ assert.throws(() => f.call(chief, 'role.revoke', { role: 'assistant', reason: 'Q169' }), /not-held/);
|
||||
+ assert.throws(() => f.call(chief, 'role.revoke', { role: 'chief', reason: 'own run' }), /role-end-refused/);
|
||||
+ assert.throws(() => f.call(lead, 'role.revoke', { role: 'assistant', reason: 'not the chief' }), /role-end-refused/);
|
||||
+ assert.equal(f.store.get("SELECT count(*) n FROM events WHERE kind='action.allowed'").n, 0);
|
||||
+});
|
||||
+
|
||||
+test('Q169: another role\'s cited revoke of the assistant, resolved by an arbiter, is refused', async t => {
|
||||
+ const f = await fixture(t, { roles: seats });
|
||||
+ // A raise for it goes to the human, so an arbiter can't resolve one raised now.
|
||||
+ assert.deepEqual(routed(f, await revoke(f, f.coder, 'assistant', cite(f))), { class: 'gated', route_to: 'human' });
|
||||
+ // One raised while the instance's definition wasn't protected went to the arbiter. The same
|
||||
+ // store under a business that now makes it the assistant still refuses it.
|
||||
+ const d = await revoke(f, f.coder, 'pm', cite(f));
|
||||
+ assert.deepEqual(routed(f, d), { class: 'gated', route_to: 'reviewer' });
|
||||
+ f.call(f.reviewer, 'decision.resolve', { id: d.id, choice: 'yes' });
|
||||
+ const now = { ...f.business, roles: { ...f.business.roles, pm: { definition: 'assistant', ...grants([]) } } };
|
||||
+ const later = new Broker({ store: f.store, businesses: { demo: now } });
|
||||
+ const coder = later.bindLaunch({ business: 'demo', role: 'coder', run: 'coder-run', harness: 'pi', address: 'coder' });
|
||||
+ assert.throws(() => later.request(coder, { verb: 'role.revoke', args: { role: 'pm', decision: d.id } }), /role-end-refused/);
|
||||
+});
|
||||
+
|
||||
+test('Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection', async t => {
|
||||
+ const f = await fixture(t, { roles: seats });
|
||||
+ const d = await revoke(f, f.coder, 'assistant', cite(f));
|
||||
+ assert.throws(() => f.call(f.reviewer, 'decision.resolve', { id: d.id, choice: 'yes' }), /human-required/);
|
||||
+ f.call(f.human, 'decision.resolve', { id: d.id, choice: 'yes' });
|
||||
+ // Past the protection, the recorded holder run (null) and the role_claims one (undefined)
|
||||
+ // mismatch, because the assistant's runs hold thread claims (row 155).
|
||||
+ assert.throws(() => f.call(f.coder, 'role.revoke', { role: 'assistant', decision: d.id }), /decision-mismatch/);
|
||||
+});
|
||||
+
|
||||
+test('Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes', async t => {
|
||||
+ const f = await fixture(t, { roles: seats });
|
||||
+ f.agent('pm');
|
||||
+ const d = await revoke(f, f.coder, 'pm', cite(f));
|
||||
+ assert.deepEqual(routed(f, d), { class: 'gated', route_to: 'reviewer' });
|
||||
+ f.call(f.reviewer, 'decision.resolve', { id: d.id, choice: 'yes' });
|
||||
+ assert.deepEqual(f.call(f.coder, 'role.revoke', { role: 'pm', decision: d.id }), { revoked: true });
|
||||
+});
|
||||
+
|
||||
+test('Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human', async t => {
|
||||
+ const f = await fixture(t, { roles: { ...seats,
|
||||
+ lead: { definition: 'lead', authority: { withinRole: [], crossRole: ['role.revoke'] } },
|
||||
+ boss: { definition: 'boss', ...grants(['role.revoke']) } } });
|
||||
+ const lead = f.agent('lead'), boss = f.agent('boss');
|
||||
+ assert.deepEqual(routed(f, await revoke(f, lead, 'assistant', cite(f))), { class: 'gated', route_to: 'human' });
|
||||
+ assert.deepEqual(routed(f, await revoke(f, lead, 'pm', cite(f))), { class: 'cross-role', route_to: 'reviewer' });
|
||||
+ const own = await revoke(f, boss, 'assistant', { choice: 'yes' });
|
||||
+ assert.deepEqual(routed(f, own), { class: 'gated', route_to: 'human' });
|
||||
+ assert.equal(f.store.get('SELECT count(*) n FROM decision_events WHERE decision=?', own.id).n, 0);
|
||||
+ // The revoke's authority check classifies the same way: the decision is open, not mismatched.
|
||||
+ assert.throws(() => f.call(boss, 'role.revoke', { role: 'assistant', decision: own.id }), /decision-not-approved/);
|
||||
+ assert.deepEqual(routed(f, await revoke(f, boss, 'pm', { choice: 'yes' })), { class: 'within-role', route_to: 'boss' });
|
||||
+});
|
||||
diff --git a/packages/bus/tests/spec-fixtures.mjs b/packages/bus/tests/spec-fixtures.mjs
|
||||
index eafd30fb9..e24b27f94 100644
|
||||
--- a/packages/bus/tests/spec-fixtures.mjs
|
||||
@@ -409,6 +685,70 @@ index 000000000..57132425d
|
||||
+ ["git.merge.protected"]);
|
||||
+ assert.deepEqual(role({ withinRole: LEFT.slice(1), crossRole: [] }).authority.withinRole, LEFT.slice(1));
|
||||
+});
|
||||
diff --git a/packages/harness/README.md b/packages/harness/README.md
|
||||
index fcc33ab30..c304d38be 100644
|
||||
--- a/packages/harness/README.md
|
||||
+++ b/packages/harness/README.md
|
||||
@@ -99,7 +99,10 @@ so its manifest lists both in `typed` and nothing in `untyped`:
|
||||
|
||||
- `end_run` (role.end holders) sends `role.revoke` with `role` and a
|
||||
`reason` of 1 to 500 characters, never a `decision`. The broker refuses
|
||||
- the caller's own run and the assistant's with `role-end-refused`. A
|
||||
+ the caller's own run with `role-end-refused`. Since row 139 (Jason's
|
||||
+ ruling Q169) the chief of staff's end of the assistant gets past that
|
||||
+ check and refuses `not-held`, because the assistant's runs hold thread
|
||||
+ claims; row 155 (#1649) makes it stop them and updates the tool's text. A
|
||||
`role.end` holder's prompt names the tool in place of the "only the human
|
||||
stops a run" line; every other role keeps that line.
|
||||
- `change_organization` (organization.change holders) sends
|
||||
diff --git a/packages/harness/tests/runner.test.mjs b/packages/harness/tests/runner.test.mjs
|
||||
index 1361cf030..e409f43b0 100644
|
||||
--- a/packages/harness/tests/runner.test.mjs
|
||||
+++ b/packages/harness/tests/runner.test.mjs
|
||||
@@ -28,7 +28,8 @@ const businesses = {
|
||||
roles: {
|
||||
pm: { authority: { withinRole: ["message.send", "role.launch"], crossRole: [] } },
|
||||
coder: { authority: { withinRole: ["message.send"], crossRole: [] } },
|
||||
- // Row 132 (#1628): the chief of staff's grants and the assistant it can't end.
|
||||
+ // Row 132 (#1628): the chief of staff's grants and the assistant. Since row 139 (Q169) the
|
||||
+ // chief may end the assistant, and the end refuses not-held until row 155 (#1649).
|
||||
chief: { definition: "chief-of-staff", authority: { withinRole: ["message.send", "role.end", "organization.change"], crossRole: [] } },
|
||||
assistant: { definition: "assistant", authority: { withinRole: ["message.send"], crossRole: [] } },
|
||||
},
|
||||
@@ -401,7 +402,7 @@ test("end_run and change_organization reach the broker with the tool's arguments
|
||||
assert.deepEqual(ctx.inbox.map((m) => m.body), [
|
||||
'{"revoked":true}',
|
||||
"refused: role-end-refused",
|
||||
- "refused: role-end-refused",
|
||||
+ "refused: not-held",
|
||||
'{"revision":"' + "b".repeat(64) + '"}',
|
||||
"refused: invalid-request",
|
||||
"refused: revision-conflict",
|
||||
diff --git a/packages/tasks/requirements.json b/packages/tasks/requirements.json
|
||||
index f4d9f35c7..ade2b774d 100644
|
||||
--- a/packages/tasks/requirements.json
|
||||
+++ b/packages/tasks/requirements.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"prd": "docs/prd/mosaic-stack.md",
|
||||
- "version": "1.5",
|
||||
+ "version": "1.6",
|
||||
"requirements": [
|
||||
{ "id": "REQ-ROLE-1", "title": "Each role is a reviewed roles/<name>.json: contract, authority map, credentials" },
|
||||
{ "id": "REQ-ROLE-2", "title": "One holder per role instance, one per thread for the assistant; the chief of staff may end a run, others need a decision" },
|
||||
diff --git a/packages/tasks/tests/requirements.test.mjs b/packages/tasks/tests/requirements.test.mjs
|
||||
index 90409e131..dada58304 100644
|
||||
--- a/packages/tasks/tests/requirements.test.mjs
|
||||
+++ b/packages/tasks/tests/requirements.test.mjs
|
||||
@@ -21,7 +21,7 @@ test("the list holds the PRD's requirement ids, in its order, at its version", (
|
||||
assert.equal(ids.length, 58);
|
||||
assert.deepEqual(list.requirements.map((r) => r.id), ids);
|
||||
assert.match(prd, new RegExp(`^- Status: approved, version ${list.version.replace('.', '\\.')}\\.`, 'm'));
|
||||
- assert.deepEqual([list.prd, list.version], ['docs/prd/mosaic-stack.md', '1.5']);
|
||||
+ assert.deepEqual([list.prd, list.version], ['docs/prd/mosaic-stack.md', '1.6']);
|
||||
});
|
||||
|
||||
test('the committed list loads frozen', () => {
|
||||
diff --git a/scripts/test-land-work.sh b/scripts/test-land-work.sh
|
||||
index 1bfe402db..d689e0e14 100644
|
||||
--- a/scripts/test-land-work.sh
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
5f150904571ab63bf7a0a86c3a6f0ac465634044fdb766fbdefb0889a6371c52 docs/prd/mosaic-stack.md
|
||||
c42d44227fcae7398bfc3773f726c0fddb978bad68bf274b6bc8092ebb338337 packages/bus/README.md
|
||||
ba4c455a858786c0d16a38dd11acb3ab37cf0ea3e6f77f4e1326f1898b1471a2 packages/bus/src/broker.mjs
|
||||
56a719657be0cf7fe1c9da52a60ce151af6ef59ccce5c64d761e4d49a6af911e packages/bus/tests/chief-of-staff.test.mjs
|
||||
4047efaffc8d93d41de25acc40e6c9fa0ad1289ff56ce4e8e93483a098f14b87 packages/bus/tests/hard-waits.test.mjs
|
||||
bb021a3a49b2f9cd0e6e220e8e01952135543fc67fe0d77e74ac9c01c14bae60 packages/bus/tests/spec-fixtures.mjs
|
||||
cb4effc15f5567a1cc90c6901a67cf29915281d2031143eaab5d0d54166a7825 packages/business/README.md
|
||||
b94dc6a5b8ec522003a66874bdeb67c5397ab1e6d8835eb9e538f665c85a5832 packages/business/src/vocabulary.mjs
|
||||
8ad7db43ede9724d5537e4c7a8278013e790a4fb8173e48dcbe2f20ae1f02b51 packages/business/tests/hard-waits.test.mjs
|
||||
b85db4464b32c5d0e0b7aba799b5749c15522eb52b412b8bce6d8c107400c58e packages/bus/README.md
|
||||
e2b0099471665f4fa828bec5b02b6393b6ab20de62ca86f328e4aca2aeb6bc74 packages/bus/src/broker.mjs
|
||||
68ae53935bdd128639c49d667984564609aa3b923874fa205bba079528f99fff packages/bus/tests/hard-waits.test.mjs
|
||||
bb021a3a49b2f9cd0e6e220e8e01952135543fc67fe0d77e74ac9c01c14bae60 packages/bus/tests/spec-fixtures.mjs
|
||||
426ed54b7c35d42f44e1da8dcfc9f0493ca18d0ccc7d0aec7a4755a6cf0ed6ac packages/harness/README.md
|
||||
1d62025fa1590e68860a6c569798592b6b2119d77184bc15848e9f3df26b0d4c packages/harness/tests/runner.test.mjs
|
||||
9165deb8a0df5d13b988cdd1c260395dc06719be844dfdadd51dbcf95c994636 packages/tasks/requirements.json
|
||||
b06c580e39be16ab6b5443244db807d74b2bc56411e45fd415483abe7b926093 packages/tasks/tests/requirements.test.mjs
|
||||
c9d1d5c9b006d5c12e5f796a9828361059f8e0410846fc55c070c0148b15cef4 scripts/test-land-work.sh
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# Row 139 round 2 gate (Dewey, Q169, slot sage-0533): land-work, bus, business, harness, tasks, every scripts/test-*.sh.
|
||||
set -uo pipefail
|
||||
W=/home/jwoltje/dewey-scratch/r139/wt
|
||||
O=/home/jwoltje/dewey-scratch/r139/out/gate-r2
|
||||
export TMPDIR=/home/jwoltje/dewey-scratch/tmp COMPOSE_PROJECT_NAME=dewey-r139
|
||||
mkdir -p "$O" "$TMPDIR"
|
||||
cleanup() {
|
||||
n=$(docker ps -aq --filter network=dewey-r139_default 2>/dev/null | wc -l)
|
||||
if docker network inspect dewey-r139_default >/dev/null 2>&1; then
|
||||
if [ "$n" -eq 0 ]; then docker network rm dewey-r139_default >/dev/null && echo "network removed"; else echo "network kept: $n containers"; fi
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
cd "$W" || exit 2
|
||||
run() { # name, command...
|
||||
local name=$1; shift
|
||||
local start; start=$(date -u +%FT%TZ)
|
||||
"$@" > "$O/$name.txt" 2>&1; local rc=$?
|
||||
echo "$name rc=$rc start=$start end=$(date -u +%FT%TZ)" | tee -a "$O/summary.txt"
|
||||
}
|
||||
: > "$O/summary.txt"
|
||||
run land-work bash scripts/test-land-work.sh
|
||||
run bus bash -c 'cd packages/bus && npm test'
|
||||
run business bash -c 'cd packages/business && npm test'
|
||||
run harness bash -c 'cd packages/harness && npm test'
|
||||
run tasks bash -c 'cd packages/tasks && npm test'
|
||||
for s in scripts/test-*.sh; do
|
||||
b=$(basename "$s" .sh)
|
||||
[ "$b" = test-land-work ] && continue
|
||||
run "$b" bash "$s"
|
||||
done
|
||||
echo "gate done $(date -u +%FT%TZ)" | tee -a "$O/summary.txt"
|
||||
@@ -0,0 +1,316 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (208.277453ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (276.041528ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (410.424969ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (258.712221ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (270.012787ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (290.987456ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (330.27816ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (292.950608ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (1075.866297ms)
|
||||
✔ agents: stranded is per role and per business (413.961354ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (223.500568ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (383.275857ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (245.276508ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (361.676779ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (344.032352ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (401.910413ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (528.952875ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (235.905474ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (352.94321ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (361.403791ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (276.869686ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (264.456803ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (419.563048ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (237.142667ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (264.620776ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (201.488089ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (211.7141ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (302.212703ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (247.931731ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (293.508535ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (168.649852ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (363.052343ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (193.288859ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (3.273893ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (328.227898ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (448.249381ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (348.07844ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (344.09815ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (400.365925ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (418.491194ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (363.857695ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (247.029503ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (422.861924ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (389.447697ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (495.460221ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (655.179487ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1242.556027ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (192.916096ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (188.060795ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (1182.68694ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (2064.23543ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (1049.547344ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (969.198033ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1247.718607ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (150.376098ms)
|
||||
✔ credentials refuses a role session and any argument (236.614126ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (261.313814ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (298.988107ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (6.333326ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (3.478106ms)
|
||||
✔ expiry refuses use and env references never become client data (0.913367ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (4.182647ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.46132ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.974968ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (643.493812ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (657.951875ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (634.839908ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (679.653964ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (482.957499ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (537.747135ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (612.896568ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (573.844065ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (489.184026ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (670.547333ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (686.939941ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (551.829752ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (591.648013ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (610.020191ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (612.06306ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (301.74803ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (338.06041ms)
|
||||
✔ a human withdraw sends one message with the note (300.288431ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (404.88797ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (405.91572ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (445.290674ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (399.169579ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (263.357263ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (389.870027ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (387.706376ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (476.8234ms)
|
||||
✔ a refused supersede withdraws nothing (426.206642ms)
|
||||
✔ the assistant's within-role and gated raises still work (448.56594ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (300.349445ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (392.107293ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (421.856936ms)
|
||||
✔ recent stops at RECENT rows (1176.685992ms)
|
||||
✔ every row is what trail already gives the same session for that id (372.163259ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (419.264304ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (525.049539ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (192.378683ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (180.676116ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (189.726501ms)
|
||||
✔ endLaunch leaves a claim another run took alone (240.246529ms)
|
||||
✔ refuse records action.refused against the caller with the code only (210.343038ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (258.161931ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (467.015424ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.932827ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (151.718929ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (978.979482ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (606.711157ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (360.111405ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (414.786356ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (295.337028ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (249.769342ms)
|
||||
✔ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (336.548721ms)
|
||||
✔ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (272.363728ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (300.409772ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (337.450352ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.555359ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.492618ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.674902ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.25377ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (279.786499ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (222.041451ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (205.998789ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (352.011006ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (158.169755ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (408.15513ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (205.306829ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (479.134986ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (281.662527ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (394.192168ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (577.809154ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (255.178095ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (245.281351ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (351.361382ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (3383.912828ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (376.413511ms)
|
||||
✔ views messages passes only its paging arguments through (0.273173ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (195.353096ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (480.57285ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (513.755152ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (465.231701ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (358.389192ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (415.7882ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (452.167806ms)
|
||||
✔ the sender list is checked before the target list (369.755894ms)
|
||||
✔ roles without the field behave exactly as before (544.00174ms)
|
||||
✔ a business with no role definitions at all is unlimited (415.468733ms)
|
||||
✔ a malformed messaging field refuses at boot (184.792926ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (544.87816ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (572.256898ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (471.923589ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (315.517757ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (688.497728ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (516.940685ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (273.055109ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (65.904629ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (269.093003ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (289.095099ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (212.12483ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (72.346112ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (255.78486ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (198.068074ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (244.501651ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (146.990246ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (152.22161ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.212696ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (272.806957ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (221.205724ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (304.867447ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (208.933737ms)
|
||||
✔ a message with no reply gives an empty list (187.924897ms)
|
||||
✔ replies come oldest first and stop at REPLIES (1009.999642ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (357.532858ms)
|
||||
✔ strict arguments; a role session gets human-required (492.444402ms)
|
||||
✔ views passes replies through as one call with the id (0.227261ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (228.118592ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (242.057621ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (170.200685ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (261.085783ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (309.501394ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (354.626656ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (501.547236ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (293.920624ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (394.013504ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (492.698639ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (393.277205ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1883.216913ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (348.984265ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (215.90766ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (229.633633ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (438.196434ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (265.148418ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (351.251777ms)
|
||||
✔ class drift gated to within-role refuses before consumption (269.258816ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (339.972392ms)
|
||||
✔ class drift within-role to gated refuses before consumption (341.704331ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (290.828793ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (367.823562ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (378.237021ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1726.085428ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (362.013893ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (264.275409ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (262.637892ms)
|
||||
✔ client disconnect during await tolerates late reply (221.09243ms)
|
||||
✔ client disconnect during await tolerates late refusal (235.771097ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (403.99316ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (366.519816ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (346.347447ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (282.282986ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (318.596255ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (291.764143ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (431.729214ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (195.263026ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (587.000551ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (611.309765ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (578.561091ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (353.123791ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (824.556535ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (609.087066ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (390.936989ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (145.896372ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (233.412751ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (166.493715ms)
|
||||
✔ a tombstone is not open (183.585477ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (192.362799ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (192.821448ms)
|
||||
✔ a human session reads the same state, with the same cap (234.687853ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (206.751325ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (145.245876ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (259.111817ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (206.772537ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (234.497319ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (123.253897ms)
|
||||
✔ async transactions refuse before invoking their function (168.831852ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (361.511742ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (309.047319ms)
|
||||
✔ each filter, alone and together, and total counts every match (534.990012ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (441.344639ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (348.747908ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1228.251686ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (379.443105ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (515.064722ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (192.557694ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (239.439668ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (141.623551ms)
|
||||
✔ a bad entry refuses the whole record (198.7251ms)
|
||||
✔ taskView reads the projection for one business (188.665067ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (330.630107ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (504.024232ms)
|
||||
✔ without an adapter the server refuses every task verb (335.216711ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (258.801953ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (423.905898ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1126.173752ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (402.448937ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (766.80692ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (316.80843ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (368.653606ms)
|
||||
✔ the tester reads the human views a reader reads (203.151164ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.100255ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.3608ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.201182ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (170.298868ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (1129.559082ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1489.501788ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (1096.590659ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (1242.723873ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (495.369428ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1615.942696ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (440.202174ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (4253.376085ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (98.788144ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (212.049876ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (164.654034ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (205.439924ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (153.381612ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (143.833145ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (150.045689ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (109.368987ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (154.518788ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (570.209051ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (232.011762ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (273.275037ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (184.610611ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.953627ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (228.613414ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (248.466368ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (225.416806ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (276.710024ms)
|
||||
✔ a broker with no web service refuses a granted role (209.686464ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (226.101126ms)
|
||||
✔ a session that is not the role holder is refused (216.037372ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (528.692136ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (163.840367ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (247.678066ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (325.657345ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (198.677551ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (260.076665ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.281227ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (335.979195ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (216.435498ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (453.228061ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (188.128262ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (204.078134ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (173.100798ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 306
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14243.481023
|
||||
@@ -0,0 +1,122 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ the role file loads and resolves through loadBusiness (9.597237ms)
|
||||
✔ the shipped file is exactly the approved list (1.203174ms)
|
||||
✔ the assistant's authority is message.send and record.write within role (3.364375ms)
|
||||
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.982977ms)
|
||||
✔ a business grant through limits does not widen the role (2.271256ms)
|
||||
✔ a launch block whose by is the assistant is refused (2.535096ms)
|
||||
✔ the instance takes no credential references and no tracker (3.853085ms)
|
||||
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (5.96299ms)
|
||||
✔ an arbiter without messaging lists is accepted beside the limited assistant (3.556686ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (1.014701ms)
|
||||
✔ REQ-HARN-2: the assistant holds the web grant, and no other role file does (2.257362ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (1.706827ms)
|
||||
✔ the fixture business validates and comes back frozen (6.976803ms)
|
||||
✔ two instances may share a definition (3.098838ms)
|
||||
✔ top-level refusals (7.783094ms)
|
||||
✔ arbiters and projects (11.055772ms)
|
||||
✔ role instances (4.873722ms)
|
||||
✔ Vikunja bots (12.432634ms)
|
||||
✔ a role without Vikunja takes no tracker block (2.714598ms)
|
||||
✔ credential references match the definition's services (2.58503ms)
|
||||
✔ launch (9.246014ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (3.897576ms)
|
||||
✔ loadBusiness: file checks (1.803071ms)
|
||||
✔ loadBusiness: not a regular file (36.906861ms)
|
||||
✔ loading writes nothing (0.947101ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.539605ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.728888ms)
|
||||
✔ the role file loads and resolves through loadBusiness (10.226093ms)
|
||||
✔ the shipped file is exactly the approved list (0.32212ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (3.440373ms)
|
||||
✔ the chief of staff holds role.launch, message.send, role.end, organization.change and record.write; every other action is gated (2.277084ms)
|
||||
✔ the pm does not hold role.launch (2.597543ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (4.124056ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.738818ms)
|
||||
✔ a launch block whose by is the pm instance is refused (3.980015ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (1.019427ms)
|
||||
✔ the instance takes no credential references and no tracker (4.693232ms)
|
||||
✔ usage errors exit 4 (308.850956ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (60.373942ms)
|
||||
✔ validate: project files (301.949555ms)
|
||||
✔ validate: missing files and a broken system config (233.987421ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (63.506012ms)
|
||||
✔ validate: a token file inside the repository is refused (61.975422ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (185.602132ms)
|
||||
✔ resolve: prints one instance's record (246.624711ms)
|
||||
✔ resolve: refusals (376.691613ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (3.352574ms)
|
||||
✔ check: a good file has no problems (1.151451ms)
|
||||
✔ check never opens the file: a write-only token passes (0.464528ms)
|
||||
✔ check: file problems (1.290868ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.436318ms)
|
||||
✔ check: dates and environment references (0.57949ms)
|
||||
✔ each definition loads, with a contract file, and is exactly the approved list (4.656117ms)
|
||||
✔ an organization file that declares them passes, and each resolves to least privilege (7.834462ms)
|
||||
✔ the chief of staff launches each one; no other role does (4.227579ms)
|
||||
✔ a C-suite role can't be made the launcher: launch.by must hold role.launch (3.141382ms)
|
||||
✔ limits can narrow a C-suite role but never widen it (2.34921ms)
|
||||
✔ any unknown key, tool, action or version in a role file is refused (2.632668ms)
|
||||
✔ REQ-WAIT-1: GATED_ONLY is exactly the hard waits; the new actions are in the vocabulary (1.837791ms)
|
||||
✔ REQ-WAIT-3: every action is routed or a hard wait, never both, and the routed list names only actions (0.396943ms)
|
||||
✔ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (5.30842ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (21.507805ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.114395ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (258.967378ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (266.105284ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (4.309719ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (227.011574ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.879955ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (130.740799ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (18.617206ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (332.19497ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (424.914224ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.554732ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (43.022762ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.625239ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (98.517559ms)
|
||||
✔ optional project repo is preserved and must be a normalized absolute path (14.451464ms)
|
||||
✔ loaded business project repo cannot be nested in any declared code checkout (6.137616ms)
|
||||
✔ path and load (3.031751ms)
|
||||
✔ refusals (1.982635ms)
|
||||
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (4.745951ms)
|
||||
✔ systemVars flattens the validated config (2.270363ms)
|
||||
✔ precedence: system, business, project, project role, agent (5.84455ms)
|
||||
✔ limits narrow the definition and never widen it (2.101152ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (4.952572ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (1.86313ms)
|
||||
✔ limits.authority narrows cross-role actions too (1.037525ms)
|
||||
✔ classify (1.084244ms)
|
||||
✔ the record carries what the broker and launcher need (1.279123ms)
|
||||
✔ digest: key order doesn't matter, any value change does (8.406016ms)
|
||||
✔ refusals (1.933005ms)
|
||||
✔ the four shipped version 2 roles load (3.68944ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.886973ms)
|
||||
✔ shipped authority follows the note's table (0.82845ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (1.352113ms)
|
||||
✔ version 1 files keep loading with no authority (0.921487ms)
|
||||
✔ the conductor policy isn't a role (0.176306ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.352647ms)
|
||||
✔ version 2 refusals (1.340866ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (2.306152ms)
|
||||
✔ messaging: optional, role definitions and human, never the tester (1.46686ms)
|
||||
✔ credentials: Gitea scopes (0.719106ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.991797ms)
|
||||
✔ credentials: services (0.483901ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.574639ms)
|
||||
✔ every key names known layers and a merge rule (0.921441ms)
|
||||
✔ unknown keys and wrong layers refuse (0.852618ms)
|
||||
✔ types (2.110047ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.292852ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.329986ms)
|
||||
✔ merge doesn't change its inputs (0.154104ms)
|
||||
✔ web.searxng takes https anywhere and http on loopback, so Jason's 127.0.0.1:8888 passes (0.181177ms)
|
||||
ℹ tests 112
|
||||
ℹ suites 0
|
||||
ℹ pass 112
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1921.103424
|
||||
@@ -0,0 +1,115 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ sessionModel: agent vars win, then the system's execution settings (16.589734ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (6.009037ms)
|
||||
✔ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (3.021573ms)
|
||||
✔ a chief-of-staff bundle lists end_run and change_organization as typed and nothing untyped, for either harness (5.98927ms)
|
||||
✔ the stop line names end_run for a role.end holder, and every other role keeps today's text (8.2496ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (2.799318ms)
|
||||
✔ the prompt's built-in tools line is the harness's own names, as the manifest lists them (7.492133ms)
|
||||
✔ the prompt names the project clones in the workspace, and none when there are none (7.184873ms)
|
||||
✔ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (6.058187ms)
|
||||
✔ the prompt tells the pm to ask the chief of staff for sessions, and no other role (6.735975ms)
|
||||
✔ a bundle is written once: an existing file refuses (1.671908ms)
|
||||
✔ a path with a single quote can't go into the hook command (1.542757ms)
|
||||
✔ web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool (2.499719ms)
|
||||
✔ no web grant on pi: no web tool in the bundle, and the gate blocks a web call (1.586598ms)
|
||||
✔ web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool (1.521689ms)
|
||||
✔ no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call (1.312378ms)
|
||||
✔ a granted session's gate lets the typed web tools through and still blocks the built-ins (1.437709ms)
|
||||
✔ search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing (4.736504ms)
|
||||
✔ search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing (3.859539ms)
|
||||
✔ search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted (6.106546ms)
|
||||
✔ search-source harness-builtin is refused for a granted pi role, which has no built-in web tool (1.620203ms)
|
||||
✔ allow exits 0, a deny exits 2 with the reason on stderr (135.69278ms)
|
||||
✔ a missing or wrong policy, or a bad event, exits 2 (84.638933ms)
|
||||
✔ the bundle's wrapped command: a missing gate or node still blocks (1085.025941ms)
|
||||
✔ claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist (813.987993ms)
|
||||
✔ claude: the hook alone blocks a path outside the workspace (469.48787ms)
|
||||
✔ claude: a second turn resumes the first turn's session (789.345424ms)
|
||||
✔ claude adapter: --restricted is always passed (4.706486ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (20.779293ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (5.85967ms)
|
||||
✔ claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do (784.657738ms)
|
||||
✔ claude: a missing hook or MCP file refuses before claude starts (7.248841ms)
|
||||
✔ pi: policy tools and typed tools pass, anything else is blocked (4.190298ms)
|
||||
✔ claude: builtins map from pi names, typed tools need the mcp prefix (0.903565ms)
|
||||
✔ file tool paths must resolve inside the workspace (1.691876ms)
|
||||
✔ pi's own path normalisation can't be used to step out (1.348682ms)
|
||||
✔ a symlink inside the workspace that points out is outside (1.245164ms)
|
||||
✔ a dangling symlink is refused at any depth, in both harnesses (4.33735ms)
|
||||
✔ read is checked under every spelling pi's read would open, in both harnesses (20.479722ms)
|
||||
✔ other spellings cover directories, dangling links and pi's cwd (2.903043ms)
|
||||
✔ a relative path climbs from the workspace's real path, in both harnesses (4.804469ms)
|
||||
✔ claude path fields per tool (0.789696ms)
|
||||
✔ glob patterns stay inside the workspace (0.625886ms)
|
||||
✔ a path that can't be checked is blocked (0.781287ms)
|
||||
✔ fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX (226.870232ms)
|
||||
✔ fetch_review's have orders the working refs newest first within each clone, one clone after another (156.273168ms)
|
||||
✔ a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period (1808.765673ms)
|
||||
✔ once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (304.245233ms)
|
||||
✔ initialize, ping and tools/list (51.337899ms)
|
||||
✔ tools/call goes through the tool socket; a refusal is an isError result (39.470416ms)
|
||||
✔ replies are compact JSON; over the cap a tool error names the size and the cap (37.211358ms)
|
||||
✔ unknown tools and methods are JSON-RPC errors and never reach the socket (34.302039ms)
|
||||
✔ a missing argument is a usage error (26.611958ms)
|
||||
✔ pi: typed tools reach the socket, the gate blocks, agent_end writes the marker (382.871241ms)
|
||||
✔ pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks (318.057616ms)
|
||||
✔ pi: a write through a dangling symlink is blocked, and nothing appears outside (309.8411ms)
|
||||
✔ pi: a read is refused when pi would open another spelling outside (309.066895ms)
|
||||
✔ pi: a relative path climbs from the real path of a workspace behind a symlink (312.53187ms)
|
||||
✔ pi: a relative path climbs from the real path of a dataRoot behind a symlink (321.183468ms)
|
||||
✔ pi: a missing extension refuses before any model call (6.659016ms)
|
||||
✔ pi: an extension without its configuration fails pi's start (265.860224ms)
|
||||
✔ founderCheck: founder variables, then a needed service without a usable token (1.653052ms)
|
||||
✔ turnRequest names the sender, class, reply and decision (0.310067ms)
|
||||
✔ turnRequest says a tester's message is a test and never Jason's instruction (0.298344ms)
|
||||
✔ turnRequest shows the message's own sent time, a day old as well as new (0.207957ms)
|
||||
✔ stateBlock names the launch state with its time and event, and the open tasks with the cap (0.336237ms)
|
||||
✔ a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0 (280.480981ms)
|
||||
✔ launches revoked and then restored: the turn's block reads allowed and gives the restore time (300.027621ms)
|
||||
✔ a task closed on the tracker is missing from the next turn's open list (337.358186ms)
|
||||
✔ a message read a day after it was sent shows the time it was sent (197.32051ms)
|
||||
✔ a decision the human resolves becomes a turn citing the decision and the answer (239.225677ms)
|
||||
✔ a failed state read fails the turn: no adapter runs, the sender hears why, the message is read (229.132569ms)
|
||||
✔ a SIGTERM before the claim stops the runner with exit 0 and no claim (118.514125ms)
|
||||
✔ typed tools carry the runner's capability; launch goes to the host's launch socket (488.216222ms)
|
||||
✔ end_run and change_organization reach the broker with the tool's arguments, and refusals keep their codes (585.844312ms)
|
||||
✔ a RESULT gets no automatic reply; failed turns reply with the reason (1331.387289ms)
|
||||
✔ the bus's launch notice is one turn with no reply, and is not taken again (265.311336ms)
|
||||
✔ SIGTERM during a turn kills the turn's process group and still exits 0 (183.984409ms)
|
||||
✔ founder credentials stop before the claim (20) (214.340847ms)
|
||||
✔ a refused claim exits 21; an ended run's capability exits 22 (216.076073ms)
|
||||
✔ the launch ending under a running session exits 22 (148.969161ms)
|
||||
✔ a broker that stays unreachable exits 23 after brokerRetries polls (283.61082ms)
|
||||
✔ a broker that is down at the claim exits 23, not 21 (94.730793ms)
|
||||
✔ no capability, or a malformed one, on stdin exits 2 (217.332336ms)
|
||||
✔ a missing or malformed policy exits 2 before the claim (132.7317ms)
|
||||
✔ every role sees read_spec, record writer follows its grant, citation schemas stay strict (17.674808ms)
|
||||
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (245.454217ms)
|
||||
✔ the PM gets its task verbs and the reads, and no launch (7.901106ms)
|
||||
✔ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.69855ms)
|
||||
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (13.318784ms)
|
||||
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (2.000731ms)
|
||||
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.130629ms)
|
||||
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (7.299053ms)
|
||||
✔ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (1.759234ms)
|
||||
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (2.255349ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (1.150658ms)
|
||||
✔ a coder with a tracker gets its own task tools and no task_reassign (1.311912ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (1.919477ms)
|
||||
✔ an action outside the instance's authority has no tool (1.190732ms)
|
||||
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (4.347745ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (10.472069ms)
|
||||
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (2.199725ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.627958ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.58142ms)
|
||||
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (2.431986ms)
|
||||
ℹ tests 105
|
||||
ℹ suites 0
|
||||
ℹ pass 105
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12685.052118
|
||||
@@ -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,15 @@
|
||||
land-work rc=0 start=2026-10-16T19:06:10Z end=2026-10-16T19:06:22Z
|
||||
bus rc=0 start=2026-10-16T19:06:22Z end=2026-10-16T19:06:36Z
|
||||
business rc=0 start=2026-10-16T19:06:36Z end=2026-10-16T19:06:38Z
|
||||
harness rc=0 start=2026-10-16T19:06:38Z end=2026-10-16T19:06:51Z
|
||||
tasks rc=0 start=2026-10-16T19:06:51Z end=2026-10-16T19:06:56Z
|
||||
test-auth rc=0 start=2026-10-16T19:06:56Z end=2026-10-16T19:06:57Z
|
||||
test-conductor rc=0 start=2026-10-16T19:06:57Z end=2026-10-16T19:07:02Z
|
||||
test-config rc=0 start=2026-10-16T19:07:02Z end=2026-10-16T19:07:04Z
|
||||
test-discord rc=0 start=2026-10-16T19:07:04Z end=2026-10-16T19:07:10Z
|
||||
test-extension-package rc=0 start=2026-10-16T19:07:10Z end=2026-10-16T19:07:12Z
|
||||
test-foundation rc=0 start=2026-10-16T19:07:12Z end=2026-10-16T19:07:51Z
|
||||
test-queue rc=0 start=2026-10-16T19:07:51Z end=2026-10-16T19:08:21Z
|
||||
test-release rc=0 start=2026-10-16T19:08:21Z end=2026-10-16T19:08:31Z
|
||||
test-task rc=0 start=2026-10-16T19:08:31Z end=2026-10-16T19:08:58Z
|
||||
gate done 2026-10-16T19:08:58Z
|
||||
@@ -0,0 +1,107 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ the boot config is checked before anything starts (101.614504ms)
|
||||
✔ a business with no tracker entry refuses task verbs (129.169757ms)
|
||||
✔ credential.expiring and .expired are recorded once per instance (258.744506ms)
|
||||
✔ a token file that changes on disk records credential.changed (108.843789ms)
|
||||
✔ autostart polls, reconciles and retries a startup the tracker was down for (131.319585ms)
|
||||
✔ a refusal a restart must clear is not retried by the poll (91.58414ms)
|
||||
✔ a poll that fires while two are queued is dropped (112.14761ms)
|
||||
✔ close waits for a running verb and refuses one that has not started (201.693702ms)
|
||||
✔ stopped bus resumes an empty task cursor after a long outage, exactly once (165.117035ms)
|
||||
✔ persisted IDs avoid replay, exclude bots and bound rows to observed new comments (194.044141ms)
|
||||
✔ commit followed by crash before cache advance neither loses nor duplicates a comment (182.384355ms)
|
||||
✔ failed event insert rolls back cursor and a retry still emits the comment once (133.82299ms)
|
||||
✔ initial cursor accepts a comment within the stated one-minute clock skew margin (112.252032ms)
|
||||
✔ the bundled Vikunja is the pinned upstream image the runbook names (0.737342ms)
|
||||
✔ every published port is on 127.0.0.1, and no secret is in the file (0.268227ms)
|
||||
✔ the committed table loads frozen; its verbs are the broker task verbs (1.487894ms)
|
||||
✔ a write names a verb the table has as its own key, not one it inherits (0.515389ms)
|
||||
✔ the schema refuses any other shape (2.257847ms)
|
||||
✔ the Field table in the slice 1 plan names the verbs each field is written by (0.656519ms)
|
||||
✔ each verb refuses, asks for a decision and writes as the table and the role files say (1206.859109ms)
|
||||
✔ the list holds the PRD's requirement ids, in its order, at its version (1.879556ms)
|
||||
✔ the committed list loads frozen (1.062923ms)
|
||||
✔ the schema refuses any other shape (3.847529ms)
|
||||
✔ the fake answers each route with the statuses and shapes Vikunja v2.7.0 sent (366.857802ms)
|
||||
✔ the project list holds recorded project objects in the recorded list envelope (130.243897ms)
|
||||
✔ the recorded task bodies pass the checks S3 applies to every read (0.530815ms)
|
||||
✔ the client works against the fake over real HTTP with the platform fetch (251.252198ms)
|
||||
✔ a correct install starts, and the first reconcile records tasks that already exist (125.64212ms)
|
||||
✔ verbs refuse while a business is starting and after startup refused it (138.778212ms)
|
||||
✔ startup refuses a token that can do more than its role needs (425.629909ms)
|
||||
✔ startup refuses an unsupported version and flags an untested one (294.804244ms)
|
||||
✔ startup refuses a board that the runbook did not install (363.687703ms)
|
||||
✔ startup refuses a project the sync bot cannot read (80.725738ms)
|
||||
✔ startup refuses a configured label the pm bot cannot see (85.94252ms)
|
||||
✔ startup refuses an expired credential and a missing sync credential (166.215618ms)
|
||||
✔ an unreachable tracker refuses with tracker-unavailable (78.862908ms)
|
||||
✔ an edit in the UI is recorded once, with the fields that changed (220.782451ms)
|
||||
✔ a move between open buckets is seen on the board, though updated does not change (170.365661ms)
|
||||
✔ a person's comment is counted and a bot's is not (310.03269ms)
|
||||
✔ the hourly reconcile catches a comment through comment_count (217.734051ms)
|
||||
✔ a task closed in the UI leaves the open view with its done bucket (390.263176ms)
|
||||
✔ a task that leaves the board is recorded as deleted, moved or out of reach (271.654553ms)
|
||||
✔ a poll that read before a verb wrote does not overwrite the verb (169.009731ms)
|
||||
✔ a tracker fault during a tick is reported and the next tick catches up (151.074632ms)
|
||||
✔ a malformed answer refuses the tick with tracker-shape (129.862107ms)
|
||||
✔ no token value reaches the database, the log or a refusal (281.41211ms)
|
||||
✔ the first look at a task counts only comments inside the window (160.249442ms)
|
||||
✔ with descendants off the adapter reads no project list and no child, as in v0 (134.082974ms)
|
||||
✔ a three-level tree is read per project, and a project outside it is not (117.71905ms)
|
||||
✔ a watch-only child keeps the business ready, and a failed child read refuses as transient (243.016961ms)
|
||||
✔ a root without the installed buckets refuses with descendants on (101.068442ms)
|
||||
✔ the project list refuses without read_all, and skips archived projects and saved filters (186.867704ms)
|
||||
✔ descendants must be true or false (86.834067ms)
|
||||
✔ a move inside the tree is a moved tombstone plus a snapshot under the new ref (180.774658ms)
|
||||
✔ a child made after startup joins the tree at the next reconcile (149.913669ms)
|
||||
✔ a child that leaves the tree has its tasks recorded missing, and the ledger keeps their history (169.055109ms)
|
||||
✔ a child deleted or hidden between reconciles drops out at the next tick, and the root still refuses (202.203564ms)
|
||||
✔ a reconcile that fails keeps the previous tree (126.932815ms)
|
||||
✔ a closed task the cursor missed takes its own project's done bucket (127.759705ms)
|
||||
✔ closed tasks read at startup take their own project's done bucket (108.338935ms)
|
||||
✔ a closed task the cursor returns takes its own project's done bucket (122.787774ms)
|
||||
✔ a task moved out of a child that leaves the tree at the same time is moved, not no-access (126.559396ms)
|
||||
✔ a task in a bucket outside the five keeps its raw bucket id (108.963783ms)
|
||||
✔ bucket 0 on a watch-only task never becomes a bucket or a state (199.832645ms)
|
||||
✔ a child whose kanban view is deleted still refuses the tick, and the reconcile reads it watch-only (133.857834ms)
|
||||
✔ a child dropped at a tick comes back at the next reconcile once the bot reads it again (116.1668ms)
|
||||
✔ task.create needs a recorded human request and a requirement id (195.701596ms)
|
||||
✔ task.create takes only an approved requirement id (212.69243ms)
|
||||
✔ task.create cites the request a received message carries, not the message's id (212.867319ms)
|
||||
✔ only labels named in the business file can be written (217.617703ms)
|
||||
✔ task.schedule sets and clears a due date and relations (263.303296ms)
|
||||
✔ assign and reassign move the role bots and record task.assigned (299.807552ms)
|
||||
✔ task.update.assigned is for the assignee and records task.state (307.667371ms)
|
||||
✔ a wrong expected digest records task.conflict and writes nothing (182.599541ms)
|
||||
✔ a cross-role verb needs a resolved decision, used once (242.684397ms)
|
||||
✔ task.close needs a verdict; after it every verb refuses with task-done (230.518282ms)
|
||||
✔ a task with pushed work closes only citing an approve verdict for its latest push, and a refusal writes nothing (248.906897ms)
|
||||
✔ a lost answer is settled by a re-read and never retried (179.231835ms)
|
||||
✔ a create whose answer is lost is reported uncertain, and the poll finds the task (113.131411ms)
|
||||
✔ a task the sync bot cannot read refuses and records nothing (92.848671ms)
|
||||
✔ verbs and polls for one business run one at a time (170.344696ms)
|
||||
✔ a due date with milliseconds is written to the second (152.704046ms)
|
||||
✔ every write landed and the final read failed: the verb succeeds and records what it wrote (105.256561ms)
|
||||
✔ some writes landed and the final read failed: write-uncertain, and nothing is recorded (79.164523ms)
|
||||
✔ a create whose final read fails succeeds and records task.created (88.880903ms)
|
||||
✔ an edit between the last write and the final read shows as external on the next poll (105.351739ms)
|
||||
✔ task.created is recorded when a later label write fails (114.438271ms)
|
||||
✔ every verb acts in an installed child, on the child's own board (249.28884ms)
|
||||
✔ task.create refuses a project outside the tree, a watch-only one and one that is not an id (154.758275ms)
|
||||
✔ with descendants off, task.create takes only the root project (78.733091ms)
|
||||
✔ a verb on a watch-only task, or a relation to one, refuses with project-not-installed (104.40691ms)
|
||||
✔ a related task is read before authority: in another project than its ref names, task-moved; missing, task-not-found (133.846352ms)
|
||||
✔ a task moved to another project of the tree refuses its old ref with task-moved and takes its new one (90.400152ms)
|
||||
✔ a verb and a create in the child record the final read of the child's board (83.363919ms)
|
||||
✔ a create in the child whose final read fails records the child's todo bucket (91.569991ms)
|
||||
✔ a lost answer in the child is settled by a re-read of the child's board (111.50291ms)
|
||||
✔ every related task is read before authority, not only the first (91.890504ms)
|
||||
ℹ tests 97
|
||||
ℹ suites 0
|
||||
ℹ pass 97
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5121.076756
|
||||
@@ -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,55 @@
|
||||
Note: switching to '5661bd233bbe3e1f03a64a76ad7edcd9f6e41e89'.
|
||||
|
||||
You are in 'detached HEAD' state. You can look around, make experimental
|
||||
changes and commit them, and you can discard any commits you make in this
|
||||
state without impacting any branches by switching back to a branch.
|
||||
|
||||
If you want to create a new branch to retain commits you create, you may
|
||||
do so (now or later) by using -c with the switch command. Example:
|
||||
|
||||
git switch -c <new-branch-name>
|
||||
|
||||
Or undo this operation with:
|
||||
|
||||
git switch -
|
||||
|
||||
Turn off this advice by setting config variable advice.detachedHead to false
|
||||
|
||||
Not currently on any branch.
|
||||
nothing to commit, working tree clean
|
||||
Note: switching to '5661bd233bbe3e1f03a64a76ad7edcd9f6e41e89'.
|
||||
|
||||
You are in 'detached HEAD' state. You can look around, make experimental
|
||||
changes and commit them, and you can discard any commits you make in this
|
||||
state without impacting any branches by switching back to a branch.
|
||||
|
||||
If you want to create a new branch to retain commits you create, you may
|
||||
do so (now or later) by using -c with the switch command. Example:
|
||||
|
||||
git switch -c <new-branch-name>
|
||||
|
||||
Or undo this operation with:
|
||||
|
||||
git switch -
|
||||
|
||||
Turn off this advice by setting config variable advice.detachedHead to false
|
||||
|
||||
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,26 @@
|
||||
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 failed validation modified nothing
|
||||
|
||||
selftest: 24 passed, 0 failed
|
||||
@@ -0,0 +1,82 @@
|
||||
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/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/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 183)
|
||||
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: 78 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
|
||||
scripts/test-extension-package.sh: line 14: 839691 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,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 (/home/jwoltje/dewey-scratch/r139/wt) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
|
||||
|
||||
queue suite: 28 passed, 0 failed
|
||||
@@ -0,0 +1,16 @@
|
||||
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
|
||||
OK healthy activation succeeds (exit 0)
|
||||
OK pointer written with valid fields
|
||||
OK repeat activation succeeds (log grows) (exit 0)
|
||||
OK log is append-only across activations
|
||||
OK rollback without previous refuses (exit 1)
|
||||
|
||||
selftest: 14 passed, 0 failed
|
||||
@@ -0,0 +1,101 @@
|
||||
OK valid task validates (exit 0)
|
||||
OK unknown task key exits 2 (exit 2)
|
||||
OK unsupported taskVersion exits 2 (exit 2)
|
||||
OK invalid task id exits 2 (exit 2)
|
||||
OK empty prompt exits 2 (exit 2)
|
||||
OK NUL in expectExact exits 2 (exit 2)
|
||||
OK out-of-range timeout exits 2 (exit 2)
|
||||
OK missing mission file exits 4 (exit 4)
|
||||
OK task with valid mission validates (exit 0)
|
||||
OK invalid mission exits 2 (exit 2)
|
||||
OK validate missing task exits 4 (exit 4)
|
||||
OK validation does not modify the task file
|
||||
OK prune dry-run exits 0 (exit 0)
|
||||
OK dry-run deleted nothing
|
||||
OK prune --keep=2 --yes removes oldest (exit 0)
|
||||
OK kept exactly 2 newest runs
|
||||
OK newest run kept, oldest pruned
|
||||
OK append-only receipt written (3 entries)
|
||||
OK sessions/workspaces untouched by prune
|
||||
OK prune with invalid keep exits 4 (exit 4)
|
||||
OK mock adapter: gate passes on matching mock response (exit 0)
|
||||
OK mock adapter: expect-mismatch recorded (exit 1)
|
||||
OK mismatch reason recorded
|
||||
OK unknown adapter fails closed (exit 1)
|
||||
OK mission task runs via mock adapter (exit 0)
|
||||
OK mission section injected into generated prompt
|
||||
OK retry of mission run succeeds (exit 0)
|
||||
OK retriedFrom lineage recorded
|
||||
OK mission section present after retry (relative path resolved)
|
||||
OK retry of missing run exits 4 (exit 4)
|
||||
OK skill install bundled ms-tools (exit 0)
|
||||
OK installed to skills-available
|
||||
OK double install refuses (exit 1)
|
||||
OK activate enables skill (exit 0)
|
||||
OK enabled dir populated
|
||||
OK uninstall while enabled refuses (exit 1)
|
||||
OK deactivate moves back to available (exit 0)
|
||||
OK uninstall removes from available (exit 0)
|
||||
OK seat with enabled skill launches
|
||||
OK skill path delivered to adapter
|
||||
OK shipped researcher contract resolves (ceiling + network)
|
||||
OK resolve-role refuses a non-role document (conductor policy) (exit 2)
|
||||
OK resolve-role refuses name/filename mismatch (exit 2)
|
||||
OK resolve-role refuses unknown network declaration (exit 2)
|
||||
OK resolve-role refuses duplicate role tool (exit 2)
|
||||
OK resolve-role refuses unsupported tool (exit 2)
|
||||
OK resolve-role refuses missing contract file (exit 4)
|
||||
OK version 1 role prints no contract line
|
||||
OK shipped version 2 roles resolve with their contracts (pm, cto, coder, reviewer)
|
||||
OK resolve-role accepts a minimal version 2 role (exit 0)
|
||||
OK resolve-role refuses an action outside the vocabulary (exit 2)
|
||||
OK resolve-role refuses a gated-only action in a role file (exit 2)
|
||||
OK resolve-role refuses a Vikunja verb no role may hold (exit 2)
|
||||
OK resolve-role refuses a version 2 role whose contract is missing (exit 2)
|
||||
OK resolve-role refuses a contract that is a symbolic link (exit 2)
|
||||
OK seat launches under role ceiling
|
||||
OK role ceiling narrows seat tools (read,write,bash -> read,bash)
|
||||
OK narrowing recorded loudly
|
||||
OK missing role contract refuses launch (exit 2)
|
||||
OK missing-contract refusal names the role
|
||||
OK empty ceiling intersection -> tool-free seat
|
||||
OK tool-free outcome recorded loudly
|
||||
OK overridden agents dir without seat definition refuses (exit 4)
|
||||
OK seat-resolution refusal names the seat
|
||||
OK policy: mission only -> mission tools
|
||||
OK policy: task only -> task tools
|
||||
OK policy: both -> intersection (task narrowed)
|
||||
OK policy: empty intersection -> tool-free
|
||||
OK invalid mission capabilities rejected (exit 2)
|
||||
mosaic-task: unsupported mission tool: "sudo" (supported: read, write, edit, bash, grep, find, ls)
|
||||
OK task run with user layer present (exit 0)
|
||||
OK user context dispatched into generated prompt
|
||||
OK workspace+tools task runs via mock (exit 0)
|
||||
OK workspace path + tools delivered to adapter
|
||||
OK persistent workspace created on host
|
||||
OK plain task still runs (no workspace/tools) (exit 0)
|
||||
OK workspace var present but empty when absent
|
||||
OK tools empty when absent
|
||||
OK unknown tool exits 2 (exit 2)
|
||||
OK workspace traversal exits 2 (exit 2)
|
||||
OK live hello task succeeds with exact marker
|
||||
OK result.json written in run dir
|
||||
OK result.json contents are correct
|
||||
OK wrong expectExact fails with exit 1 (reason: expect-mismatch)
|
||||
OK each run gets a distinct run dir (no clobber)
|
||||
OK list shows both runs
|
||||
OK fork base: teach succeeds (exit 0)
|
||||
OK fork child recalls ancestor context (exit 0)
|
||||
OK forked child recalled ancestor code word
|
||||
OK ancestor session untouched by fork
|
||||
OK child session dir has its own branch file
|
||||
OK onboard without name exits 4 (non-interactive) (exit 4)
|
||||
OK onboard --name renders profile (exit 0)
|
||||
OK profile written
|
||||
OK canon structure: required filled, optional placeholdered
|
||||
OK canon sections present
|
||||
OK user recall run succeeds
|
||||
OK recalled user name (response: Jason)
|
||||
OK no agent identity on headless run
|
||||
|
||||
selftest: 98 passed, 0 failed
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
# Row 139 round 2 mutants. Each mutates one file, runs the owning suite in its own
|
||||
# process group (killpg on timeout), restores the file and checks its hash before the next.
|
||||
import hashlib, os, signal, subprocess, sys, time
|
||||
|
||||
W = "/home/jwoltje/dewey-scratch/r139/wt"
|
||||
O = "/home/jwoltje/dewey-scratch/r139/out/mutants-r2"
|
||||
os.makedirs(O, exist_ok=True)
|
||||
ENV = dict(os.environ, TMPDIR="/home/jwoltje/dewey-scratch/tmp", COMPOSE_PROJECT_NAME="dewey-r139")
|
||||
SUITES = {"bus": ["bash", "-c", "cd packages/bus && npm test"],
|
||||
"business": ["bash", "-c", "cd packages/business && npm test"]}
|
||||
MUTANTS = [
|
||||
("m1-no-spec-check", "packages/bus/src/broker.mjs",
|
||||
"(cls === 'gated' && spec !== null && !this.#hardWait(s, a.action, a.target))", "(cls === 'gated' && !this.#hardWait(s, a.action, a.target))", "bus"),
|
||||
("m2-no-hard-wait-check", "packages/bus/src/broker.mjs",
|
||||
"(cls === 'gated' && spec !== null && !this.#hardWait(s, a.action, a.target))", "(cls === 'gated' && spec !== null)", "bus"),
|
||||
("m3-new-action-not-hard-wait", "packages/bus/src/broker.mjs",
|
||||
"const ROUTED = new Set([\n", "const ROUTED = new Set([\n 'account.create',\n", "bus"),
|
||||
("m4-hard-wait-routed", "packages/business/src/vocabulary.mjs",
|
||||
"export const ROUTED = Object.freeze([\n", "export const ROUTED = Object.freeze([\n \"spend\",\n", "business"),
|
||||
("m5-validator-refusal", "packages/business/src/role.mjs",
|
||||
"if (GATED_ONLY.includes(action)) refuse(", "if (false && GATED_ONLY.includes(action)) refuse(", "business"),
|
||||
("m6-no-assistant-check", "packages/bus/src/broker.mjs",
|
||||
" return action === 'role.revoke' && END_PROTECTED.includes(", " return false && action === 'role.revoke' && END_PROTECTED.includes(", "bus"),
|
||||
("m7-no-chief-exemption", "packages/bus/src/broker.mjs",
|
||||
" if (b.roles[s.role]?.definition === STAFF_TO || r?.via === 'cli') return;", " if (r?.via === 'cli') return;", "bus"),
|
||||
("m8-no-human-exemption", "packages/bus/src/broker.mjs",
|
||||
" if (b.roles[s.role]?.definition === STAFF_TO || r?.via === 'cli') return;", " if (b.roles[s.role]?.definition === STAFF_TO) return;", "bus"),
|
||||
("m9-no-revoke-protection", "packages/bus/src/broker.mjs",
|
||||
" if (action === 'role.revoke') this.#protectedEnd(s, target, r);\n", "", "bus"),
|
||||
]
|
||||
sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
|
||||
summary = open(os.path.join(O, "summary.txt"), "w")
|
||||
for name, rel, old, new, suite in MUTANTS:
|
||||
path = os.path.join(W, rel)
|
||||
orig = open(path, "rb").read()
|
||||
h0 = sha(path)
|
||||
text = orig.decode()
|
||||
if text.count(old) != 1:
|
||||
line = f"{name} SKIP anchor count {text.count(old)}"
|
||||
print(line); summary.write(line + "\n"); summary.flush(); sys.exit(3)
|
||||
open(path, "w").write(text.replace(old, new))
|
||||
assert sha(path) != h0
|
||||
start = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
|
||||
with open(os.path.join(O, f"{name}.txt"), "w") as out:
|
||||
p = subprocess.Popen(SUITES[suite], cwd=W, env=ENV, stdout=out, stderr=subprocess.STDOUT, start_new_session=True)
|
||||
try:
|
||||
rc = p.wait(timeout=600)
|
||||
except subprocess.TimeoutExpired:
|
||||
os.killpg(p.pid, signal.SIGKILL); p.wait(); rc = "timeout"
|
||||
open(path, "wb").write(orig)
|
||||
restored = sha(path) == h0
|
||||
end = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
|
||||
verdict = "KILLED" if rc not in (0, "timeout") else ("TIMEOUT" if rc == "timeout" else "SURVIVED")
|
||||
line = f"{name} {rel} suite={suite} rc={rc} {verdict} restored={restored} start={start} end={end}"
|
||||
print(line); summary.write(line + "\n"); summary.flush()
|
||||
if not restored:
|
||||
sys.exit(4)
|
||||
@@ -0,0 +1,548 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (149.209063ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (232.505499ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (324.388036ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (172.528886ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (209.523371ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (183.478748ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (206.357381ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (212.441478ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (942.201583ms)
|
||||
✔ agents: stranded is per role and per business (346.719632ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (140.263019ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (302.806447ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (195.118055ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (267.957302ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (249.253042ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (249.715887ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (333.54321ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (173.546237ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (272.457926ms)
|
||||
✖ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (235.608694ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (196.163378ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (173.648315ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (283.751342ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (170.350529ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (185.315389ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (114.991209ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (206.795008ms)
|
||||
✖ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (313.470183ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (173.405043ms)
|
||||
✖ revocation permanently bars the old run from reclaiming first, including after broker restart (173.175877ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (159.074829ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (236.89661ms)
|
||||
✖ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (130.347354ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.460588ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (265.837334ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (326.788662ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (254.5635ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (232.617093ms)
|
||||
✖ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (260.419626ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (285.94329ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (283.098115ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (268.90461ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (339.547857ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (315.133348ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (376.857077ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (545.962216ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (993.26722ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (127.564877ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (121.720795ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (870.077384ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1585.367335ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (812.270382ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (808.219977ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (994.606937ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (115.452784ms)
|
||||
✔ credentials refuses a role session and any argument (176.339113ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (212.004944ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (223.09741ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.467398ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (9.124614ms)
|
||||
✔ expiry refuses use and env references never become client data (1.429586ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (2.039149ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.529591ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.577009ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (489.805667ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (457.89515ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (406.149427ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (467.141019ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (511.04254ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (407.622124ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (469.211838ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (456.389471ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (415.22617ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (546.942974ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (498.733247ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (472.984736ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (432.712611ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (474.579992ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (381.548149ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (234.363038ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (269.929675ms)
|
||||
✔ a human withdraw sends one message with the note (245.184852ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (289.621003ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (289.492574ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (286.161477ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (274.548273ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (277.321322ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (308.367184ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (294.53679ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (355.058485ms)
|
||||
✔ a refused supersede withdraws nothing (280.256618ms)
|
||||
✖ the assistant's within-role and gated raises still work (293.336606ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (221.751062ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (304.399911ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (292.545317ms)
|
||||
✔ recent stops at RECENT rows (818.117529ms)
|
||||
✔ every row is what trail already gives the same session for that id (283.023233ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (467.326804ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (419.325023ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (145.903096ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (157.248133ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (144.942168ms)
|
||||
✔ endLaunch leaves a claim another run took alone (176.914671ms)
|
||||
✔ refuse records action.refused against the caller with the code only (136.925229ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (195.267658ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (315.938458ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.256965ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (113.648864ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (738.583674ms)
|
||||
✖ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (193.817365ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (258.630492ms)
|
||||
✖ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (286.741959ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (262.117067ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (281.453665ms)
|
||||
✔ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (276.657622ms)
|
||||
✔ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (243.567843ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (233.921991ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (289.946983ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.500416ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.454078ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.654305ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.238882ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (216.220629ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (171.140743ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (146.223371ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (262.073494ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (143.05645ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (270.62302ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (128.169775ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (334.792065ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (237.637821ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (293.235811ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (432.96204ms)
|
||||
✖ within-role sends cite an open gated launch decision without spending it or naming it in grants (175.749813ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (186.291548ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (258.017308ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (2644.748568ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (258.843013ms)
|
||||
✔ views messages passes only its paging arguments through (0.441454ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (184.679882ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (316.720813ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (359.969881ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (369.193178ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (365.448155ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (343.143681ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (347.621413ms)
|
||||
✔ the sender list is checked before the target list (304.416027ms)
|
||||
✔ roles without the field behave exactly as before (447.891191ms)
|
||||
✔ a business with no role definitions at all is unlimited (364.823196ms)
|
||||
✔ a malformed messaging field refuses at boot (123.494233ms)
|
||||
✖ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (350.68425ms)
|
||||
✖ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (369.812726ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (385.523649ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (206.548693ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (477.805657ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (447.341676ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (202.18202ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (66.825949ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (216.296994ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (226.086374ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (257.640639ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (66.06471ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (215.929258ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (139.034596ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (158.609043ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (151.207735ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (172.629218ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.88414ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (213.559974ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (198.383577ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (234.496094ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (246.031484ms)
|
||||
✔ a message with no reply gives an empty list (195.981932ms)
|
||||
✔ replies come oldest first and stop at REPLIES (755.004109ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (316.027772ms)
|
||||
✔ strict arguments; a role session gets human-required (378.9497ms)
|
||||
✔ views passes replies through as one call with the id (0.247546ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (264.574238ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (163.526616ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (174.098873ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (254.952073ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (246.9214ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (278.979795ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (385.900582ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (236.649101ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (325.437278ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (425.856773ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (286.214937ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1516.925731ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (290.04078ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (226.914715ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (152.977202ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (302.485627ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (271.045375ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (238.007153ms)
|
||||
✔ class drift gated to within-role refuses before consumption (284.101977ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (301.421002ms)
|
||||
✔ class drift within-role to gated refuses before consumption (227.140635ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (239.48818ms)
|
||||
✖ message.send consumes approval and prevents a later send or authorize (205.901701ms)
|
||||
✖ role.revoke consumes approval and prevents a later revoke or authorize (236.47759ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1398.536488ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (259.527997ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (187.212586ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (227.107554ms)
|
||||
✔ client disconnect during await tolerates late reply (171.717201ms)
|
||||
✔ client disconnect during await tolerates late refusal (176.23351ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (383.048233ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (296.584587ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (309.670781ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (216.73386ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (282.225965ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (257.935884ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (319.807841ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (178.224726ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (497.574518ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (438.753089ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (475.590201ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (254.616913ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (601.145905ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (450.112043ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (239.234805ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (136.287741ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (161.325042ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (151.77424ms)
|
||||
✔ a tombstone is not open (154.23953ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (152.194077ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (177.818609ms)
|
||||
✔ a human session reads the same state, with the same cap (168.46382ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (160.876594ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (142.067892ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (171.440566ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (187.276377ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (179.302485ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (126.822002ms)
|
||||
✔ async transactions refuse before invoking their function (136.531271ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (322.126509ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (277.724369ms)
|
||||
✔ each filter, alone and together, and total counts every match (345.177804ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (310.620894ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (333.778934ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (914.67991ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (356.74357ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (370.384186ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (136.913047ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (217.840172ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (117.527317ms)
|
||||
✔ a bad entry refuses the whole record (123.660141ms)
|
||||
✔ taskView reads the projection for one business (129.229054ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (283.022691ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (474.559224ms)
|
||||
✔ without an adapter the server refuses every task verb (240.281ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (195.453159ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (318.958349ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (881.569305ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (280.21088ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (584.595068ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (226.863369ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (288.309212ms)
|
||||
✔ the tester reads the human views a reader reads (178.790923ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.387354ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.388386ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.214661ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (120.544353ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (898.798192ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1089.297009ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (836.370984ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (879.330806ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (337.594942ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1232.744824ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (361.485022ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3539.320929ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (100.523538ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (146.197415ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (156.856414ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (218.460097ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (168.951096ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (138.408792ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (166.829984ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (119.239329ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (156.514508ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (503.026555ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (177.13793ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (191.245605ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (130.956871ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.795244ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (151.219501ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (163.859346ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (191.894449ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (210.648802ms)
|
||||
✔ a broker with no web service refuses a granted role (184.794892ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (230.050386ms)
|
||||
✔ a session that is not the role holder is refused (118.583963ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (372.50072ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (168.043802ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (196.281873ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (192.972609ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (142.414716ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (255.215933ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.303537ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (215.209951ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (177.278167ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (448.014738ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (173.774003ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (197.670636ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (169.60216ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 293
|
||||
ℹ fail 13
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 11668.717492
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/broker.test.mjs:96:1
|
||||
✖ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (235.608694ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:45:45)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:111:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/broker.test.mjs:274:1
|
||||
✖ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (313.470183ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:45:45)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:290:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/broker.test.mjs:322:1
|
||||
✖ revocation permanently bars the old run from reclaiming first, including after broker restart (173.175877ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:45:45)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:329:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/broker.test.mjs:393:1
|
||||
✖ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (130.347354ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
'pm' !== 'human'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/broker.test.mjs:407:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'pm',
|
||||
expected: 'human',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/chief-of-staff.test.mjs:139:1
|
||||
✖ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (260.419626ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/chief-of-staff.test.mjs:73:44)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/chief-of-staff.test.mjs:152:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/decision-route.test.mjs:139:1
|
||||
✖ the assistant's within-role and gated raises still work (293.336606ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
'chief' !== 'human'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/decision-route.test.mjs:150:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'chief',
|
||||
expected: 'human',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:51:1
|
||||
✖ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (193.817365ms)
|
||||
AssertionError [ERR_ASSERTION]: git.merge.protected
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:57:12)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:73:1
|
||||
✖ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (286.741959ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'cto'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:87:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'cto' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/message-citation.test.mjs:53:1
|
||||
✖ within-role sends cite an open gated launch decision without spending it or naming it in grants (175.749813ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at Object.call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/message-citation.test.mjs:27:44)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/message-citation.test.mjs:69:5)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/messaging.test.mjs:263:1
|
||||
✖ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (350.68425ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:76:44)
|
||||
at approved (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:259:3)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:266:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/messaging.test.mjs:280:1
|
||||
✖ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (369.812726ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:76:44)
|
||||
at approved (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:259:3)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/messaging.test.mjs:284:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
|
||||
test at tests/single-use.test.mjs:208:1
|
||||
✖ message.send consumes approval and prevents a later send or authorize (205.901701ms)
|
||||
Error: not-resolver
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1321:38)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:25:42)
|
||||
at Object.approve (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:56:7)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:210:11)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'not-resolver'
|
||||
}
|
||||
|
||||
test at tests/single-use.test.mjs:231:1
|
||||
✖ role.revoke consumes approval and prevents a later revoke or authorize (236.47759ms)
|
||||
Error: not-resolver
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1321:38)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:25:42)
|
||||
at Object.approve (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:56:7)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/single-use.test.mjs:235:15)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25) {
|
||||
code: 'not-resolver'
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (207.045576ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (240.730618ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (400.426309ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (241.186783ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (227.640425ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (217.459729ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (339.147567ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (234.443411ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (1160.988975ms)
|
||||
✔ agents: stranded is per role and per business (444.425324ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (204.048929ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (400.817556ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (252.91469ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (356.823746ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (261.714086ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (301.070873ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (494.982357ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (227.476714ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (331.496759ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (317.475304ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (252.855236ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (186.308451ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (396.530822ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (209.610641ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (212.960747ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (138.621254ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (212.659127ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (473.802074ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (200.683688ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (290.652462ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (181.833296ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (360.118604ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (225.364973ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.029828ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (351.786782ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (408.372062ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (325.461509ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (261.273231ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (391.30168ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (326.909409ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (299.613149ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (294.947088ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (507.98134ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (393.185243ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (537.288404ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (686.321836ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1360.340377ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (190.539112ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (163.646697ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (1125.781028ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (2001.428264ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (1087.48955ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (1122.506421ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1179.1195ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (157.842189ms)
|
||||
✔ credentials refuses a role session and any argument (198.543334ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (266.291789ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (233.135179ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (3.379668ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (1.984961ms)
|
||||
✔ expiry refuses use and env references never become client data (0.628421ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.700217ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.450596ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.563657ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (635.067474ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (571.117528ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (548.887439ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (532.651948ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (661.101475ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (496.084534ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (646.570057ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (572.868141ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (606.54118ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (685.520341ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (569.851264ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (435.295121ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (500.592822ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (450.150636ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (367.830553ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (320.875593ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (310.500453ms)
|
||||
✔ a human withdraw sends one message with the note (324.916561ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (318.320735ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (406.530029ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (339.605242ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (311.599134ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (304.854037ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (402.535541ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (373.325698ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (423.433208ms)
|
||||
✔ a refused supersede withdraws nothing (340.082598ms)
|
||||
✔ the assistant's within-role and gated raises still work (438.814506ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (329.815276ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (349.403564ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (393.6446ms)
|
||||
✔ recent stops at RECENT rows (999.382826ms)
|
||||
✔ every row is what trail already gives the same session for that id (319.022347ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (620.404494ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (479.927691ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (210.229485ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (158.828482ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (205.471246ms)
|
||||
✔ endLaunch leaves a claim another run took alone (221.047633ms)
|
||||
✔ refuse records action.refused against the caller with the code only (215.973884ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (210.477091ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (418.973783ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.261835ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (178.006801ms)
|
||||
✖ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (263.442703ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (545.20383ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (283.185111ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (414.840923ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (290.166818ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (276.660988ms)
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (192.873554ms)
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (258.475823ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (384.554335ms)
|
||||
✖ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (296.16808ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.331486ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.41676ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.528474ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.225566ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (296.051901ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (208.176123ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (155.191391ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (337.597194ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (140.127411ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (308.673504ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (225.165733ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (402.877986ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (308.306468ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (339.112302ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (497.887477ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (265.010064ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (278.272304ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (262.376033ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (3329.052496ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (347.644247ms)
|
||||
✔ views messages passes only its paging arguments through (0.279254ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (239.800494ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (443.645663ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (411.797456ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (408.68946ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (511.78699ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (418.215222ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (495.486368ms)
|
||||
✔ the sender list is checked before the target list (366.343571ms)
|
||||
✔ roles without the field behave exactly as before (573.116118ms)
|
||||
✔ a business with no role definitions at all is unlimited (548.468314ms)
|
||||
✔ a malformed messaging field refuses at boot (144.278541ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (536.179968ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (468.12324ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (364.159869ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (213.018608ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (651.574035ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (466.516339ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (219.661513ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (66.243192ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (230.51212ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (247.045555ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (278.257435ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (64.483107ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (264.588454ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (181.810841ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (173.763999ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (159.768582ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (301.299358ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.255795ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (234.04527ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (224.621171ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (247.288411ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (250.412597ms)
|
||||
✔ a message with no reply gives an empty list (315.000599ms)
|
||||
✔ replies come oldest first and stop at REPLIES (1016.568152ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (349.864971ms)
|
||||
✔ strict arguments; a role session gets human-required (507.859858ms)
|
||||
✔ views passes replies through as one call with the id (0.242664ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (397.470438ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (194.352227ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (224.41021ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (421.254809ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (289.856036ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (412.094484ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (464.423566ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (349.195038ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (445.385593ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (526.363102ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (403.655774ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (2025.616638ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (349.661865ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (258.563455ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (255.360944ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (389.762074ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (263.836532ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (356.624434ms)
|
||||
✔ class drift gated to within-role refuses before consumption (367.311167ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (380.225974ms)
|
||||
✔ class drift within-role to gated refuses before consumption (334.50848ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (301.497996ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (289.099547ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (289.306581ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1780.691754ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (352.14265ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (232.673616ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (253.520418ms)
|
||||
✔ client disconnect during await tolerates late reply (237.213828ms)
|
||||
✔ client disconnect during await tolerates late refusal (217.052799ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (436.882636ms)
|
||||
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (321.389474ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (372.416051ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (243.914158ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (383.343444ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (368.887325ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (362.933366ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (177.758426ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (647.859234ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (537.288283ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (594.041065ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (292.446429ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (667.554132ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (464.7086ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (241.68112ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (153.125155ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (176.013629ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (179.77928ms)
|
||||
✔ a tombstone is not open (229.713252ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (182.432589ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (242.703994ms)
|
||||
✔ a human session reads the same state, with the same cap (256.244377ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (178.756336ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (143.477187ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (258.573876ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (231.834738ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (288.285703ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (207.736974ms)
|
||||
✔ async transactions refuse before invoking their function (111.731127ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (491.117221ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (330.19306ms)
|
||||
✔ each filter, alone and together, and total counts every match (498.028131ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (380.21512ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (277.583684ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1074.438213ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (526.625893ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (471.998528ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (163.215908ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (293.63358ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (206.434274ms)
|
||||
✔ a bad entry refuses the whole record (135.463527ms)
|
||||
✔ taskView reads the projection for one business (138.928333ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (423.371193ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (453.500886ms)
|
||||
✔ without an adapter the server refuses every task verb (243.915917ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (243.228487ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (374.782334ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1224.497663ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (313.523652ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (616.382488ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (243.239663ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (279.433626ms)
|
||||
✔ the tester reads the human views a reader reads (187.979755ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.221122ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.346209ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.2688ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (106.602819ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (905.337721ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1445.039198ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (894.699658ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (861.661835ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (408.407803ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1464.806819ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (368.924366ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3519.48498ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (103.080666ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (159.525411ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (151.320171ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (176.345598ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (154.795097ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (153.028598ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (150.623104ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (113.436568ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (149.259666ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (476.796882ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (264.280236ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (251.788081ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (138.603902ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.873074ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (177.495406ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (261.491453ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (227.668823ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (260.721527ms)
|
||||
✔ a broker with no web service refuses a granted role (154.365746ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (226.79117ms)
|
||||
✔ a session that is not the role holder is refused (134.972672ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (427.046192ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (154.16875ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (197.614408ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (194.401441ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (131.48511ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (233.003066ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.257227ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (208.520521ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (171.788083ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (458.283677ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (176.63443ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (185.719793ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (155.707523ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 301
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12897.612493
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:38:1
|
||||
✖ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (263.442703ms)
|
||||
AssertionError [ERR_ASSERTION]: spend {"project":"stack","spec_path":"spec/north-star.md","spec_commit":"94ad77f623676dff49a4274d13b388b71807c333"}
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:43:14)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:126:1
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (192.873554ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:129:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:141:1
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (258.475823ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:144:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /human-required/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:160:1
|
||||
✖ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (296.16808ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:165:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/spec.test.mjs:9:1
|
||||
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (321.389474ms)
|
||||
Error: agent-required
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #agent (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:297:18)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1320:22)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at Object.call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/spec-fixtures.mjs:33:49)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/spec.test.mjs:14:5)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7) {
|
||||
code: 'agent-required'
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (146.701078ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (260.817711ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (396.009553ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (222.326641ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (257.542184ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (219.807958ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (271.458603ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (242.177599ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (1012.576722ms)
|
||||
✔ agents: stranded is per role and per business (451.131479ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (155.583777ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (335.627353ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (240.774445ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (321.684873ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (301.698893ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (303.937334ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (448.161807ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (188.238239ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (320.649862ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (322.512957ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (228.3145ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (221.499745ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (323.336826ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (228.075274ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (222.907906ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (146.672571ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (224.911518ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (335.730502ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (181.229717ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (322.097238ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (182.335926ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (295.542121ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (225.243693ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.117548ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (309.141378ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (392.552929ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (295.018572ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (299.418368ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (301.459962ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (363.316282ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (304.892067ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (262.665582ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (382.794871ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (422.190803ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (456.995316ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (596.34087ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1190.003732ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (167.954579ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (146.621789ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (1022.194563ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1790.247313ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (1046.323465ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (876.244466ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1168.422563ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (119.075652ms)
|
||||
✔ credentials refuses a role session and any argument (220.331551ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (273.316901ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (242.983749ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.649569ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (2.869215ms)
|
||||
✔ expiry refuses use and env references never become client data (1.17271ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.736197ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.2805ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (2.338512ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (573.840426ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (561.631226ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (483.672031ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (589.269609ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (514.576772ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (506.780869ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (599.350485ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (514.538746ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (465.526314ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (688.610395ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (551.277085ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (431.318732ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (599.285506ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (489.417021ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (396.19236ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (266.258785ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (291.665624ms)
|
||||
✔ a human withdraw sends one message with the note (281.497502ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (341.842355ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (334.791501ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (380.371441ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (306.434621ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (266.780996ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (346.835636ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (352.628669ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (437.375646ms)
|
||||
✔ a refused supersede withdraws nothing (341.643056ms)
|
||||
✔ the assistant's within-role and gated raises still work (374.80254ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (256.872522ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (362.964659ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (360.006717ms)
|
||||
✔ recent stops at RECENT rows (985.913621ms)
|
||||
✔ every row is what trail already gives the same session for that id (299.46152ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (474.885195ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (547.655836ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (152.948705ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (172.805643ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (177.806429ms)
|
||||
✔ endLaunch leaves a claim another run took alone (214.194146ms)
|
||||
✔ refuse records action.refused against the caller with the code only (165.603353ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (244.192895ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (375.864401ms)
|
||||
✖ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.836942ms)
|
||||
✖ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (135.023841ms)
|
||||
✖ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (457.569248ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (501.359059ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (296.774298ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (441.192039ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (301.481105ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (277.831999ms)
|
||||
✔ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (262.723342ms)
|
||||
✔ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (268.099577ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (317.444058ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (340.457331ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.404841ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.413017ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.534074ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.214436ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (239.443588ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (213.328084ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (164.536694ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (292.498322ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (158.331957ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (319.23462ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (148.598027ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (437.384832ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (270.019252ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (347.886503ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (506.349775ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (247.877894ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (229.254516ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (313.043452ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (3105.389445ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (294.507617ms)
|
||||
✔ views messages passes only its paging arguments through (0.269292ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (217.137588ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (383.867818ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (446.13424ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (412.302115ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (361.402724ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (450.882483ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (404.810806ms)
|
||||
✔ the sender list is checked before the target list (372.074531ms)
|
||||
✔ roles without the field behave exactly as before (487.694474ms)
|
||||
✔ a business with no role definitions at all is unlimited (378.524097ms)
|
||||
✔ a malformed messaging field refuses at boot (145.716305ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (535.728346ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (474.351151ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (355.567133ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (251.58783ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (554.789818ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (481.914398ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (292.352104ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (79.090713ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (239.661442ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (248.099518ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (216.41706ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (67.862701ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (229.256427ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (174.375688ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (183.652447ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (157.590525ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (163.586873ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.583628ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (224.005804ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (222.481064ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (275.117042ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (213.95472ms)
|
||||
✔ a message with no reply gives an empty list (213.705103ms)
|
||||
✔ replies come oldest first and stop at REPLIES (965.369732ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (356.67467ms)
|
||||
✔ strict arguments; a role session gets human-required (431.702471ms)
|
||||
✔ views passes replies through as one call with the id (0.322395ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (261.382848ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (200.934435ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (238.169394ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (278.692135ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (311.826032ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (371.230923ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (448.57168ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (269.936227ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (364.239883ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (451.4654ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (305.842065ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1804.5363ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (314.461871ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (313.406501ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (188.335345ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (395.473465ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (241.040352ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (299.663888ms)
|
||||
✔ class drift gated to within-role refuses before consumption (274.166484ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (295.902318ms)
|
||||
✔ class drift within-role to gated refuses before consumption (250.142589ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (383.320383ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (302.38901ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (299.270966ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1670.879947ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (300.592584ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (232.067683ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (249.83309ms)
|
||||
✔ client disconnect during await tolerates late reply (194.581701ms)
|
||||
✔ client disconnect during await tolerates late refusal (198.061224ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (419.080223ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (329.781006ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (364.371467ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (240.027776ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (285.351153ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (294.309225ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (349.893145ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (200.336126ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (506.098614ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (576.803313ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (471.511499ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (262.340739ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (775.714446ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (480.702883ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (253.138321ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (172.869528ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (164.507433ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (166.473176ms)
|
||||
✔ a tombstone is not open (167.182076ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (166.797616ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (168.221518ms)
|
||||
✔ a human session reads the same state, with the same cap (154.475643ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (201.593172ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (144.305665ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (210.554834ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (228.566791ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (190.162036ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (126.298188ms)
|
||||
✔ async transactions refuse before invoking their function (132.333672ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (341.534823ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (310.616891ms)
|
||||
✔ each filter, alone and together, and total counts every match (407.867897ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (350.360734ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (277.722281ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1075.231076ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (362.661245ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (410.369429ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (258.849606ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (210.563369ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (114.883197ms)
|
||||
✔ a bad entry refuses the whole record (149.69772ms)
|
||||
✔ taskView reads the projection for one business (137.066258ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (427.470856ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (442.43973ms)
|
||||
✔ without an adapter the server refuses every task verb (251.00903ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (225.620203ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (440.234043ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1022.58458ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (290.950337ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (617.480066ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (365.526365ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (285.645179ms)
|
||||
✔ the tester reads the human views a reader reads (210.447206ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.1717ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.373205ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.272355ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (112.47102ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (936.730574ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1282.857782ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (999.406449ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (888.216713ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (405.904062ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1537.616599ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (376.387463ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3721.326824ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (138.109062ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (154.570829ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (161.163826ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (191.856734ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (153.34101ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (131.797885ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (152.316703ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (114.444995ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (153.917425ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (498.95702ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (167.064414ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (305.994102ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (161.95357ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.762413ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (168.109489ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (180.29961ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (287.127644ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (244.267741ms)
|
||||
✔ a broker with no web service refuses a granted role (165.59634ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (237.448263ms)
|
||||
✔ a session that is not the role holder is refused (146.458483ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (551.372051ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (170.011308ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (202.22383ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (204.450616ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (156.728323ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (255.64178ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.261037ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (261.882637ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (202.409957ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (454.856955ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (172.383216ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (195.328175ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (161.732615ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 303
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12913.120511
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:18:1
|
||||
✖ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.836942ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
- 'account.create',
|
||||
'credential.mint',
|
||||
'data.delete',
|
||||
'deploy',
|
||||
'git.push.protected',
|
||||
'message.external',
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:19:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [ 'credential.mint', 'data.delete', 'deploy', 'git.push.protected', 'message.external', 'network.expose', 'spend' ],
|
||||
expected: [ 'account.create', 'credential.mint', 'data.delete', 'deploy', 'git.push.protected', 'message.external', 'network.expose', 'spend' ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:25:1
|
||||
✖ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (135.023841ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception: account.create
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:32:12)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /invalid-authority/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:38:1
|
||||
✖ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (457.569248ms)
|
||||
AssertionError [ERR_ASSERTION]: account.create {"project":"stack","spec_path":"spec/north-star.md","spec_commit":"b3d963f03ea0ed293d885c0fc05abaec14aa6b28"}
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:43:14)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ the role file loads and resolves through loadBusiness (10.548834ms)
|
||||
✔ the shipped file is exactly the approved list (1.228386ms)
|
||||
✔ the assistant's authority is message.send and record.write within role (3.683682ms)
|
||||
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.986042ms)
|
||||
✔ a business grant through limits does not widen the role (2.3382ms)
|
||||
✔ a launch block whose by is the assistant is refused (2.807141ms)
|
||||
✔ the instance takes no credential references and no tracker (4.304246ms)
|
||||
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (6.914945ms)
|
||||
✔ an arbiter without messaging lists is accepted beside the limited assistant (4.614251ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (1.214654ms)
|
||||
✔ REQ-HARN-2: the assistant holds the web grant, and no other role file does (2.941348ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (2.412464ms)
|
||||
✔ the fixture business validates and comes back frozen (7.422565ms)
|
||||
✔ two instances may share a definition (2.961836ms)
|
||||
✔ top-level refusals (6.601931ms)
|
||||
✔ arbiters and projects (9.336956ms)
|
||||
✔ role instances (4.94913ms)
|
||||
✔ Vikunja bots (15.102483ms)
|
||||
✔ a role without Vikunja takes no tracker block (3.56508ms)
|
||||
✔ credential references match the definition's services (3.6885ms)
|
||||
✔ launch (8.83128ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (5.026916ms)
|
||||
✔ loadBusiness: file checks (2.295721ms)
|
||||
✔ loadBusiness: not a regular file (43.612314ms)
|
||||
✔ loading writes nothing (1.139752ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.811079ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.733766ms)
|
||||
✔ the role file loads and resolves through loadBusiness (10.746005ms)
|
||||
✔ the shipped file is exactly the approved list (0.329656ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (2.787363ms)
|
||||
✔ the chief of staff holds role.launch, message.send, role.end, organization.change and record.write; every other action is gated (2.840727ms)
|
||||
✔ the pm does not hold role.launch (3.035954ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (3.588575ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.972003ms)
|
||||
✔ a launch block whose by is the pm instance is refused (4.341036ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.492973ms)
|
||||
✔ the instance takes no credential references and no tracker (3.267876ms)
|
||||
✔ usage errors exit 4 (298.214236ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (66.746097ms)
|
||||
✔ validate: project files (314.816895ms)
|
||||
✔ validate: missing files and a broken system config (234.673827ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (60.381722ms)
|
||||
✔ validate: a token file inside the repository is refused (65.808188ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (183.164798ms)
|
||||
✔ resolve: prints one instance's record (250.632231ms)
|
||||
✔ resolve: refusals (369.496569ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (3.640872ms)
|
||||
✔ check: a good file has no problems (1.634815ms)
|
||||
✔ check never opens the file: a write-only token passes (0.776707ms)
|
||||
✔ check: file problems (1.311251ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.348772ms)
|
||||
✔ check: dates and environment references (0.61056ms)
|
||||
✔ each definition loads, with a contract file, and is exactly the approved list (5.90182ms)
|
||||
✔ an organization file that declares them passes, and each resolves to least privilege (9.339357ms)
|
||||
✔ the chief of staff launches each one; no other role does (5.598148ms)
|
||||
✔ a C-suite role can't be made the launcher: launch.by must hold role.launch (6.437049ms)
|
||||
✔ limits can narrow a C-suite role but never widen it (4.068034ms)
|
||||
✔ any unknown key, tool, action or version in a role file is refused (1.355569ms)
|
||||
✖ REQ-WAIT-1: GATED_ONLY is exactly the hard waits; the new actions are in the vocabulary (3.020026ms)
|
||||
✔ REQ-WAIT-3: every action is routed or a hard wait, never both, and the routed list names only actions (0.532982ms)
|
||||
✖ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (1.700591ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (24.214488ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.322064ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (257.203488ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (246.21555ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.270633ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (285.573299ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.913163ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (115.323092ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (18.165732ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (297.382164ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (433.217065ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.471241ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (36.15546ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.583682ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (106.753984ms)
|
||||
✔ optional project repo is preserved and must be a normalized absolute path (15.503723ms)
|
||||
✔ loaded business project repo cannot be nested in any declared code checkout (4.411439ms)
|
||||
✔ path and load (3.459081ms)
|
||||
✔ refusals (1.708272ms)
|
||||
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (4.335237ms)
|
||||
✔ systemVars flattens the validated config (2.07101ms)
|
||||
✔ precedence: system, business, project, project role, agent (7.774974ms)
|
||||
✔ limits narrow the definition and never widen it (3.116111ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (6.943515ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (2.629068ms)
|
||||
✔ limits.authority narrows cross-role actions too (1.089462ms)
|
||||
✔ classify (1.05187ms)
|
||||
✔ the record carries what the broker and launcher need (1.133199ms)
|
||||
✔ digest: key order doesn't matter, any value change does (7.942315ms)
|
||||
✔ refusals (2.160973ms)
|
||||
✔ the four shipped version 2 roles load (2.811367ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.822279ms)
|
||||
✔ shipped authority follows the note's table (0.604429ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (1.474942ms)
|
||||
✔ version 1 files keep loading with no authority (1.16582ms)
|
||||
✔ the conductor policy isn't a role (0.270789ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.510698ms)
|
||||
✔ version 2 refusals (2.091691ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (2.802027ms)
|
||||
✔ messaging: optional, role definitions and human, never the tester (2.275603ms)
|
||||
✔ credentials: Gitea scopes (1.453728ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.044153ms)
|
||||
✔ credentials: services (0.471709ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.572541ms)
|
||||
✔ every key names known layers and a merge rule (0.925215ms)
|
||||
✔ unknown keys and wrong layers refuse (0.712562ms)
|
||||
✔ types (2.119973ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.284313ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.329155ms)
|
||||
✔ merge doesn't change its inputs (0.129315ms)
|
||||
✔ web.searxng takes https anywhere and http on loopback, so Jason's 127.0.0.1:8888 passes (0.182226ms)
|
||||
ℹ tests 112
|
||||
ℹ suites 0
|
||||
ℹ pass 110
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1938.82275
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:22:1
|
||||
✖ REQ-WAIT-1: GATED_ONLY is exactly the hard waits; the new actions are in the vocabulary (3.020026ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
[
|
||||
'account.create',
|
||||
'credential.mint',
|
||||
'data.delete',
|
||||
'deploy',
|
||||
...
|
||||
'network.expose',
|
||||
- 'spend'
|
||||
]
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/hard-waits.test.mjs:23:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [ 'account.create', 'credential.mint', 'data.delete', 'deploy', 'git.push.protected', 'message.external', 'network.expose' ],
|
||||
expected: [ 'account.create', 'credential.mint', 'data.delete', 'deploy', 'git.push.protected', 'message.external', 'network.expose', 'spend' ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:33:1
|
||||
✖ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (1.700591ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception: spend
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/hard-waits.test.mjs:35:12)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /always gated/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ the role file loads and resolves through loadBusiness (9.182992ms)
|
||||
✔ the shipped file is exactly the approved list (1.152574ms)
|
||||
✔ the assistant's authority is message.send and record.write within role (2.977925ms)
|
||||
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.968134ms)
|
||||
✔ a business grant through limits does not widen the role (2.169662ms)
|
||||
✔ a launch block whose by is the assistant is refused (2.679489ms)
|
||||
✔ the instance takes no credential references and no tracker (3.774824ms)
|
||||
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (4.851884ms)
|
||||
✔ an arbiter without messaging lists is accepted beside the limited assistant (2.066296ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.61057ms)
|
||||
✔ REQ-HARN-2: the assistant holds the web grant, and no other role file does (4.467397ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (2.307066ms)
|
||||
✔ the fixture business validates and comes back frozen (11.974391ms)
|
||||
✔ two instances may share a definition (3.442413ms)
|
||||
✔ top-level refusals (8.884424ms)
|
||||
✔ arbiters and projects (10.299561ms)
|
||||
✔ role instances (5.523865ms)
|
||||
✔ Vikunja bots (8.624167ms)
|
||||
✔ a role without Vikunja takes no tracker block (2.286207ms)
|
||||
✔ credential references match the definition's services (2.520946ms)
|
||||
✔ launch (8.557491ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (4.015711ms)
|
||||
✔ loadBusiness: file checks (2.672263ms)
|
||||
✔ loadBusiness: not a regular file (37.162926ms)
|
||||
✔ loading writes nothing (1.07061ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.87897ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.767844ms)
|
||||
✔ the role file loads and resolves through loadBusiness (11.492997ms)
|
||||
✔ the shipped file is exactly the approved list (0.444023ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (3.128816ms)
|
||||
✔ the chief of staff holds role.launch, message.send, role.end, organization.change and record.write; every other action is gated (2.801299ms)
|
||||
✔ the pm does not hold role.launch (2.521604ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (2.688532ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.923605ms)
|
||||
✔ a launch block whose by is the pm instance is refused (2.348896ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.436535ms)
|
||||
✔ the instance takes no credential references and no tracker (3.435653ms)
|
||||
✔ usage errors exit 4 (295.488364ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (60.7352ms)
|
||||
✔ validate: project files (314.530158ms)
|
||||
✔ validate: missing files and a broken system config (218.418175ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (63.122562ms)
|
||||
✔ validate: a token file inside the repository is refused (70.411519ms)
|
||||
✖ validate: role definitions come from MOSAIC_ROLES_DIR (205.411846ms)
|
||||
✔ resolve: prints one instance's record (292.246308ms)
|
||||
✔ resolve: refusals (408.099272ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (3.748124ms)
|
||||
✔ check: a good file has no problems (1.130474ms)
|
||||
✔ check never opens the file: a write-only token passes (0.686343ms)
|
||||
✔ check: file problems (1.7551ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.159406ms)
|
||||
✔ check: dates and environment references (0.622726ms)
|
||||
✔ each definition loads, with a contract file, and is exactly the approved list (5.14694ms)
|
||||
✔ an organization file that declares them passes, and each resolves to least privilege (9.085095ms)
|
||||
✔ the chief of staff launches each one; no other role does (4.212439ms)
|
||||
✔ a C-suite role can't be made the launcher: launch.by must hold role.launch (3.711809ms)
|
||||
✔ limits can narrow a C-suite role but never widen it (2.804768ms)
|
||||
✔ any unknown key, tool, action or version in a role file is refused (1.114697ms)
|
||||
✔ REQ-WAIT-1: GATED_ONLY is exactly the hard waits; the new actions are in the vocabulary (2.701303ms)
|
||||
✔ REQ-WAIT-3: every action is routed or a hard wait, never both, and the routed list names only actions (1.04501ms)
|
||||
✖ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (3.8427ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (20.622251ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.118047ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (256.939708ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (268.325082ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.972161ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (231.086199ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.767747ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (144.24011ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (18.763876ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (286.192557ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (432.920012ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.522601ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (35.549874ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.460305ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (118.100792ms)
|
||||
✔ optional project repo is preserved and must be a normalized absolute path (14.705191ms)
|
||||
✔ loaded business project repo cannot be nested in any declared code checkout (4.211096ms)
|
||||
✔ path and load (3.257977ms)
|
||||
✔ refusals (1.908847ms)
|
||||
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (7.274862ms)
|
||||
✔ systemVars flattens the validated config (2.094836ms)
|
||||
✔ precedence: system, business, project, project role, agent (5.988353ms)
|
||||
✔ limits narrow the definition and never widen it (2.285408ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (4.910713ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (2.228051ms)
|
||||
✔ limits.authority narrows cross-role actions too (1.052243ms)
|
||||
✔ classify (1.100298ms)
|
||||
✔ the record carries what the broker and launcher need (1.174469ms)
|
||||
✔ digest: key order doesn't matter, any value change does (9.318176ms)
|
||||
✔ refusals (2.025622ms)
|
||||
✔ the four shipped version 2 roles load (3.517722ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.965816ms)
|
||||
✔ shipped authority follows the note's table (0.678908ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (1.134579ms)
|
||||
✔ version 1 files keep loading with no authority (0.863968ms)
|
||||
✔ the conductor policy isn't a role (0.177668ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.3644ms)
|
||||
✔ version 2 refusals (1.251328ms)
|
||||
✖ authority: closed vocabulary, no gated-only action, no overlap (0.851276ms)
|
||||
✔ messaging: optional, role definitions and human, never the tester (1.857997ms)
|
||||
✔ credentials: Gitea scopes (0.705841ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.373919ms)
|
||||
✔ credentials: services (0.483228ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.659945ms)
|
||||
✔ every key names known layers and a merge rule (1.295719ms)
|
||||
✔ unknown keys and wrong layers refuse (0.806985ms)
|
||||
✔ types (2.157826ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.385441ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.587947ms)
|
||||
✔ merge doesn't change its inputs (0.156159ms)
|
||||
✔ web.searxng takes https anywhere and http on loopback, so Jason's 127.0.0.1:8888 passes (0.214077ms)
|
||||
ℹ tests 112
|
||||
ℹ suites 0
|
||||
ℹ pass 109
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2006.532699
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/cli.test.mjs:109:1
|
||||
✖ validate: role definitions come from MOSAIC_ROLES_DIR (205.411846ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
0 !== 2
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/cli.test.mjs:122:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 2,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:33:1
|
||||
✖ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (3.8427ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception: spend
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/hard-waits.test.mjs:35:12)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /always gated/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/role.test.mjs:126:1
|
||||
✖ authority: closed vocabulary, no gated-only action, no overlap (0.851276ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/role.test.mjs:9:10)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/business/tests/role.test.mjs:129:5)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (155.063053ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (241.161916ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (386.125503ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (163.903846ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (182.024141ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (182.053417ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (218.271027ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (206.387417ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (840.00376ms)
|
||||
✔ agents: stranded is per role and per business (335.111849ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (126.222066ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (317.681569ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (254.037449ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (267.828221ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (227.11609ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (238.307829ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (374.288404ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (186.153833ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (339.67942ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (284.749245ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (172.349092ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (173.305516ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (262.351953ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (182.98293ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (195.436311ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (115.49538ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (188.893912ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (272.741063ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (141.665115ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (212.78449ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (148.38983ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (242.280803ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (177.665931ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.254263ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (282.150019ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (382.262373ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (231.012782ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (230.335107ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (258.59892ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (292.476378ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (277.485257ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (225.173554ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (282.571549ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (302.437385ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (369.686947ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (484.819769ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (866.926907ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (142.510365ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (145.188906ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (952.118513ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1479.319731ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (778.825666ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (727.87393ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (884.222469ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (109.903193ms)
|
||||
✔ credentials refuses a role session and any argument (215.063763ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (283.443085ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (220.634815ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.135556ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (2.592616ms)
|
||||
✔ expiry refuses use and env references never become client data (0.84642ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.7251ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.408721ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.757083ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (576.327926ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (439.738931ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (394.312982ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (480.85762ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (423.354874ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (367.382568ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (460.916944ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (420.169636ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (384.305028ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (472.737934ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (456.090922ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (398.974323ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (447.662673ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (658.881965ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (445.546194ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (260.961261ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (301.931392ms)
|
||||
✔ a human withdraw sends one message with the note (249.901581ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (266.533682ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (277.258648ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (301.193179ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (260.5422ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (230.781981ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (338.272398ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (347.229538ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (330.730868ms)
|
||||
✔ a refused supersede withdraws nothing (276.242067ms)
|
||||
✔ the assistant's within-role and gated raises still work (315.017397ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (231.544874ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (380.725493ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (290.178456ms)
|
||||
✔ recent stops at RECENT rows (805.878584ms)
|
||||
✔ every row is what trail already gives the same session for that id (274.984506ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (379.824921ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (365.917385ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (148.364242ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (165.008836ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (210.854714ms)
|
||||
✔ endLaunch leaves a claim another run took alone (171.322773ms)
|
||||
✔ refuse records action.refused against the caller with the code only (125.264633ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (178.884004ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (290.943232ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.297941ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (118.573806ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (813.597368ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (470.360961ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (235.93233ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (300.233053ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (269.678465ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (224.702003ms)
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (181.453798ms)
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (200.735158ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (228.410963ms)
|
||||
✖ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (219.247219ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.456517ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.422936ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.597234ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.243308ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (239.495944ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (230.025402ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (152.390967ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (235.28249ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (131.160579ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (256.494853ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (127.328381ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (351.437225ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (253.925887ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (341.81361ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (407.738334ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (261.457856ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (194.42556ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (239.587992ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (2502.977465ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (255.490303ms)
|
||||
✔ views messages passes only its paging arguments through (0.282315ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (165.047918ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (295.350649ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (380.520656ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (351.440636ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (280.083873ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (306.050185ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (330.810486ms)
|
||||
✔ the sender list is checked before the target list (300.112592ms)
|
||||
✔ roles without the field behave exactly as before (393.979552ms)
|
||||
✔ a business with no role definitions at all is unlimited (324.861592ms)
|
||||
✔ a malformed messaging field refuses at boot (122.169231ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (346.470675ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (386.825012ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (332.424448ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (186.447239ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (513.96096ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (386.911504ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (220.314318ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (77.8626ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (223.046802ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (248.098695ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (206.555652ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (66.843146ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (196.003471ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (152.547841ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (154.108826ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (133.864355ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (135.145943ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.384394ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (215.982928ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (213.514857ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (225.99218ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (196.046207ms)
|
||||
✔ a message with no reply gives an empty list (141.106508ms)
|
||||
✔ replies come oldest first and stop at REPLIES (728.533198ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (295.400401ms)
|
||||
✔ strict arguments; a role session gets human-required (347.706823ms)
|
||||
✔ views passes replies through as one call with the id (0.229409ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (195.081806ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (147.349301ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (163.969755ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (218.818513ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (235.940172ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (276.96395ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (361.351025ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (218.65701ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (284.837687ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (375.745654ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (250.675974ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1394.731586ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (246.674731ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (202.879138ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (166.04663ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (311.871319ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (226.657384ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (221.940266ms)
|
||||
✔ class drift gated to within-role refuses before consumption (230.179506ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (244.516533ms)
|
||||
✔ class drift within-role to gated refuses before consumption (206.775752ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (210.559431ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (238.62197ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (256.062602ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1294.490012ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (260.704892ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (186.883385ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (226.828515ms)
|
||||
✔ client disconnect during await tolerates late reply (170.44533ms)
|
||||
✔ client disconnect during await tolerates late refusal (170.088105ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (379.407083ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (307.625298ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (299.169781ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (219.412657ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (257.293598ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (242.539804ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (283.57821ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (159.30295ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (421.93901ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (415.483366ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (376.532059ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (231.377236ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (592.912315ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (705.09351ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (250.652775ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (118.671102ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (129.586926ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (151.374669ms)
|
||||
✔ a tombstone is not open (141.533645ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (138.427777ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (140.479561ms)
|
||||
✔ a human session reads the same state, with the same cap (141.670688ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (152.345683ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (120.240417ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (140.417371ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (178.464987ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (174.262498ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (107.541772ms)
|
||||
✔ async transactions refuse before invoking their function (99.656962ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (303.167438ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (247.107472ms)
|
||||
✔ each filter, alone and together, and total counts every match (338.558475ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (288.415386ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (253.606623ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1202.679797ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (291.966392ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (341.364543ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (108.710075ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (165.155423ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (121.621083ms)
|
||||
✔ a bad entry refuses the whole record (106.511495ms)
|
||||
✔ taskView reads the projection for one business (134.902484ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (252.616928ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (414.818522ms)
|
||||
✔ without an adapter the server refuses every task verb (216.666762ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (211.106308ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (371.551757ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (801.74922ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (238.873967ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (553.600587ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (209.690599ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (232.973455ms)
|
||||
✔ the tester reads the human views a reader reads (437.467494ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.471376ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.427071ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.269203ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (156.746246ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (1003.445536ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (972.326919ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (792.457401ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (1123.063281ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (319.379545ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1136.072091ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (315.813803ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (4016.142566ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (105.418404ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (155.767903ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (170.031384ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (182.966719ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (166.515417ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (137.219197ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (160.232131ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (114.174233ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (150.810125ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (499.410487ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (148.196072ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (176.44724ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (120.205787ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.674113ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (137.251559ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (168.161312ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (164.223423ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (193.49248ms)
|
||||
✔ a broker with no web service refuses a granted role (136.594302ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (206.224707ms)
|
||||
✔ a session that is not the role holder is refused (115.376197ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (369.21533ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (131.535458ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (466.863549ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (201.995415ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (134.524125ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (435.001125ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.293252ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (191.0647ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (163.429343ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (466.704151ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (217.083088ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (197.483571ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (157.682941ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 303
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 11948.297073
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:126:1
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (181.453798ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
class: 'gated',
|
||||
+ route_to: 'reviewer'
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:129:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'gated', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:141:1
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (200.735158ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:144:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /human-required/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:160:1
|
||||
✖ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (219.247219ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ class: 'cross-role',
|
||||
+ route_to: 'reviewer'
|
||||
- class: 'gated',
|
||||
- route_to: 'human'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:165:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { class: 'cross-role', route_to: 'reviewer' },
|
||||
expected: { class: 'gated', route_to: 'human' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (150.53971ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (253.146637ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (375.915259ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (184.270677ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (246.39718ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (211.634356ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (249.572115ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (253.49504ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (958.691031ms)
|
||||
✔ agents: stranded is per role and per business (425.056538ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (155.295537ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (343.644412ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (215.708048ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (314.082492ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (272.591392ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (295.874986ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (423.426796ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (205.772925ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (300.615099ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (319.177506ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (201.811382ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (204.95441ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (293.283777ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (207.709469ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (234.267297ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (138.199463ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (211.633117ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (326.806049ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (181.922853ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (286.649879ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (183.585797ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (298.135063ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (220.738737ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.534906ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (308.859902ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (373.323749ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (277.174244ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (275.168041ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (288.561826ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (353.522702ms)
|
||||
✖ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (262.67111ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (254.258284ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (355.252638ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (392.586763ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (446.299123ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (615.507819ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1211.774148ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (163.804918ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (151.858401ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (989.729627ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1736.233248ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (994.100946ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (947.581809ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1133.555523ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (122.794233ms)
|
||||
✔ credentials refuses a role session and any argument (205.872062ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (251.740726ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (229.889972ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (3.158163ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (4.218531ms)
|
||||
✔ expiry refuses use and env references never become client data (0.790217ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.674926ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.392003ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.658315ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (554.581189ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (513.230919ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (451.559828ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (567.750543ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (497.022134ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (452.587545ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (573.093563ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (533.265886ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (540.178021ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (659.980572ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (555.452389ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (444.570466ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (487.399425ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (496.430015ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (442.133421ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (261.842099ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (290.272426ms)
|
||||
✔ a human withdraw sends one message with the note (270.96814ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (319.120529ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (326.205624ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (335.661764ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (306.30383ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (267.898593ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (354.660563ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (328.986943ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (390.382446ms)
|
||||
✔ a refused supersede withdraws nothing (337.314626ms)
|
||||
✔ the assistant's within-role and gated raises still work (358.349298ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (266.115219ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (342.841641ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (341.190011ms)
|
||||
✔ recent stops at RECENT rows (933.70091ms)
|
||||
✔ every row is what trail already gives the same session for that id (296.406885ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (445.807223ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (484.627241ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (164.562727ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (166.603625ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (168.691018ms)
|
||||
✔ endLaunch leaves a claim another run took alone (205.281743ms)
|
||||
✔ refuse records action.refused against the caller with the code only (160.54503ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (216.156002ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (362.872816ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.275778ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (130.48479ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (806.489198ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (475.367296ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (283.942801ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (343.021097ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (286.474461ms)
|
||||
✖ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (247.786671ms)
|
||||
✔ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (284.108169ms)
|
||||
✔ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (277.416337ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (265.764864ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (376.767198ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (2.177383ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.651014ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.932695ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.345103ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (269.491472ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (189.56362ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (178.439498ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (277.118536ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (145.217233ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (300.648984ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (153.181261ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (404.532695ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (258.774609ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (334.834619ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (496.252096ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (230.414585ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (209.826855ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (295.955381ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (2963.150294ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (295.297057ms)
|
||||
✔ views messages passes only its paging arguments through (0.294628ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (206.311874ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (348.539977ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (437.711498ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (399.538007ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (349.254541ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (376.531728ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (421.104695ms)
|
||||
✔ the sender list is checked before the target list (371.312761ms)
|
||||
✔ roles without the field behave exactly as before (499.302005ms)
|
||||
✔ a business with no role definitions at all is unlimited (488.301777ms)
|
||||
✔ a malformed messaging field refuses at boot (199.003881ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (436.430095ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (459.079096ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (382.252865ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (230.699598ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (581.932483ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (463.301671ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (236.577901ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (66.073571ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (226.25913ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (237.635454ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (225.389103ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (69.980147ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (234.843393ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (181.330702ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (176.634905ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (146.030767ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (145.627021ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.231688ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (234.289362ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (228.125602ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (253.413221ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (208.243915ms)
|
||||
✔ a message with no reply gives an empty list (192.459602ms)
|
||||
✔ replies come oldest first and stop at REPLIES (896.547812ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (352.723562ms)
|
||||
✔ strict arguments; a role session gets human-required (434.216246ms)
|
||||
✔ views passes replies through as one call with the id (0.255721ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (227.236239ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (188.728067ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (189.908397ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (276.660966ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (272.015988ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (350.908264ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (437.768241ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (276.677716ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (375.824154ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (526.835329ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (350.721976ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1735.577546ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (287.842199ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (252.469262ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (198.923547ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (387.356391ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (245.748169ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (290.09119ms)
|
||||
✔ class drift gated to within-role refuses before consumption (341.410006ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (353.348825ms)
|
||||
✔ class drift within-role to gated refuses before consumption (299.163798ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (278.956426ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (267.528666ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (302.56145ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1649.819362ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (305.579649ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (228.915332ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (259.197063ms)
|
||||
✔ client disconnect during await tolerates late reply (211.176637ms)
|
||||
✔ client disconnect during await tolerates late refusal (181.230566ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (469.782253ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (328.288606ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (353.761156ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (260.243056ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (315.593753ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (300.105648ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (361.848996ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (193.535111ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (638.805874ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (518.575555ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (453.847993ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (250.881455ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (677.544112ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (488.674613ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (293.460146ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (149.201838ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (175.471314ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (174.501268ms)
|
||||
✔ a tombstone is not open (242.066413ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (193.156206ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (231.225234ms)
|
||||
✔ a human session reads the same state, with the same cap (182.850198ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (187.22773ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (143.720037ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (191.653645ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (258.295115ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (266.180719ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (149.625751ms)
|
||||
✔ async transactions refuse before invoking their function (170.275972ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (410.945665ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (366.739661ms)
|
||||
✔ each filter, alone and together, and total counts every match (409.027574ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (338.24313ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (278.945074ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1033.610956ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (457.679255ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (486.618739ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (148.294307ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (248.415573ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (147.393748ms)
|
||||
✔ a bad entry refuses the whole record (192.647682ms)
|
||||
✔ taskView reads the projection for one business (167.638435ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (303.960544ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (447.331489ms)
|
||||
✔ without an adapter the server refuses every task verb (245.62628ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (232.443013ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (366.262735ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1102.488539ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (289.865273ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (628.502625ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (254.529862ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (280.872426ms)
|
||||
✔ the tester reads the human views a reader reads (205.642838ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.296926ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.382275ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.219689ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (128.305986ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (896.501651ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1287.678829ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (891.338339ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (937.323728ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (488.22708ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1315.423759ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (365.946245ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3832.819306ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (629.605014ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (158.063659ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (168.556546ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (186.290588ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (158.160688ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (173.720785ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (169.663486ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (113.189467ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (158.38447ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (525.641881ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (200.625463ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (232.674796ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (145.395808ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.643431ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (161.92408ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (211.208759ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (175.752716ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (237.95069ms)
|
||||
✔ a broker with no web service refuses a granted role (156.630567ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (226.826393ms)
|
||||
✔ a session that is not the role holder is refused (123.252645ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (439.847419ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (155.089396ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (212.517637ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (195.046244ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (187.295757ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (226.757038ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.247989ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (213.096708ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (183.558633ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (461.597094ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (177.132623ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (201.657347ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (233.062906ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 304
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 13354.078019
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/chief-of-staff.test.mjs:174:1
|
||||
✖ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (262.67111ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /not-held/. Input:
|
||||
|
||||
'Error: role-end-refused'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/chief-of-staff.test.mjs:181:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: role-end-refused
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #protectedEnd (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:503:5)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1173:29)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/chief-of-staff.test.mjs:73:44)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/chief-of-staff.test.mjs:181:23
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24),
|
||||
expected: /not-held/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/hard-waits.test.mjs:115:1
|
||||
✖ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (247.786671ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /not-held/. Input:
|
||||
|
||||
'Error: role-end-refused'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:120:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: role-end-refused
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #protectedEnd (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:503:5)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1173:29)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at Object.call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/spec-fixtures.mjs:33:49)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:120:25
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24),
|
||||
expected: /not-held/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (162.656333ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (311.326216ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (586.313308ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (210.138972ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (568.436289ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (227.417652ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (240.806636ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (301.827966ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (1147.397191ms)
|
||||
✔ agents: stranded is per role and per business (426.173669ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (161.924506ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (321.032566ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (330.099323ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (503.433535ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (559.722352ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (355.318526ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (448.364677ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (203.139216ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (373.844242ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (531.040246ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (378.641465ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (393.278946ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (305.974216ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (202.32357ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (271.12818ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (137.634596ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (259.527001ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (425.660984ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (203.338222ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (291.878269ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (203.209347ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (278.697397ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (199.160109ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.359642ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (280.53919ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (671.990924ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (363.410562ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (553.583214ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (295.131701ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (371.384579ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (304.692ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (332.086673ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (446.050913ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (392.452038ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (449.71483ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (681.293037ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1140.615492ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (156.651258ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (136.638564ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (1419.209234ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (2126.897507ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (997.428909ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (968.09569ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1135.608242ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (128.933762ms)
|
||||
✔ credentials refuses a role session and any argument (195.868676ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (490.709334ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (303.459339ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.353233ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (2.586367ms)
|
||||
✔ expiry refuses use and env references never become client data (0.864621ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.826687ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.439284ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (1.575984ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (712.633405ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (934.992842ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (529.269864ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (584.958107ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (631.088496ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (508.904929ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (572.151262ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (589.497571ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (501.538131ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (586.581685ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (609.52592ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (437.714633ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (490.336835ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (668.957438ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (400.991192ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (276.89821ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (516.349784ms)
|
||||
✔ a human withdraw sends one message with the note (339.035589ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (672.506077ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (340.496551ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (380.515655ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (311.688232ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (341.329161ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (372.847853ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (574.042251ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (697.886476ms)
|
||||
✔ a refused supersede withdraws nothing (396.381838ms)
|
||||
✔ the assistant's within-role and gated raises still work (375.18159ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (246.258436ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (579.458592ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (465.403653ms)
|
||||
✔ recent stops at RECENT rows (1254.494946ms)
|
||||
✔ every row is what trail already gives the same session for that id (327.4302ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (570.018801ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (510.77069ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (160.830509ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (195.444371ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (221.246282ms)
|
||||
✔ endLaunch leaves a claim another run took alone (410.40013ms)
|
||||
✔ refuse records action.refused against the caller with the code only (180.309684ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (504.98191ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (415.187723ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.265445ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (126.266539ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (1035.07429ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (809.404998ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (264.738675ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (421.925211ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (313.842212ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (376.472254ms)
|
||||
✔ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (316.912233ms)
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (256.467001ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (271.66062ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (322.239677ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.368351ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.401173ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.555017ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.213865ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (230.728349ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (267.01477ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (345.978999ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (351.907713ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (431.418817ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (387.676736ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (137.976761ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (443.864626ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (277.181832ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (527.692835ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (882.516818ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (463.868013ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (274.615506ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (486.893095ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (3527.830964ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (295.01453ms)
|
||||
✔ views messages passes only its paging arguments through (0.289281ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (260.965405ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (463.132211ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (445.106525ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (426.151148ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (444.159408ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (430.698376ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (429.893156ms)
|
||||
✔ the sender list is checked before the target list (353.009379ms)
|
||||
✔ roles without the field behave exactly as before (555.991745ms)
|
||||
✔ a business with no role definitions at all is unlimited (411.103865ms)
|
||||
✔ a malformed messaging field refuses at boot (126.079979ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (440.666255ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (542.115757ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (371.246899ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (233.322998ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (606.033713ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (553.734549ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (318.040339ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (75.690942ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (242.497325ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (239.563515ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (262.407795ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (65.767383ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (249.263055ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (190.359124ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (186.426623ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (191.607814ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (210.653785ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.396024ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (233.410378ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (262.927226ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (286.835218ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (295.675966ms)
|
||||
✔ a message with no reply gives an empty list (244.579515ms)
|
||||
✔ replies come oldest first and stop at REPLIES (916.939328ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (341.847782ms)
|
||||
✔ strict arguments; a role session gets human-required (500.222824ms)
|
||||
✔ views passes replies through as one call with the id (0.266846ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (285.722503ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (213.944112ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (222.087958ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (319.01033ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (298.278182ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (365.811523ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (434.33185ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (285.217243ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (446.913277ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (468.301749ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (316.99201ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1886.058075ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (347.713552ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (255.928687ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (215.205922ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (365.556533ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (274.869573ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (376.673934ms)
|
||||
✔ class drift gated to within-role refuses before consumption (267.911871ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (319.543287ms)
|
||||
✔ class drift within-role to gated refuses before consumption (285.713668ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (300.602953ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (322.765354ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (306.344432ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1683.519979ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (319.463469ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (217.002344ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (256.469103ms)
|
||||
✔ client disconnect during await tolerates late reply (198.303579ms)
|
||||
✔ client disconnect during await tolerates late refusal (281.351469ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (416.406033ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (314.519403ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (329.524057ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (261.20438ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (339.1566ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (301.095554ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (428.993203ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (196.817763ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (550.062614ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (520.271054ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (468.197147ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (268.356849ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (837.084262ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (494.720133ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (241.112563ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (159.031856ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (177.940514ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (252.846007ms)
|
||||
✔ a tombstone is not open (175.665225ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (197.636796ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (177.529549ms)
|
||||
✔ a human session reads the same state, with the same cap (188.409803ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (200.751701ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (145.860236ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (254.712699ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (226.885886ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (229.006551ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (119.614264ms)
|
||||
✔ async transactions refuse before invoking their function (115.342936ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (358.502094ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (297.46197ms)
|
||||
✔ each filter, alone and together, and total counts every match (385.991916ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (330.628066ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (305.335797ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1168.801997ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (385.031986ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (412.421557ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (183.005655ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (237.132073ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (132.359623ms)
|
||||
✔ a bad entry refuses the whole record (145.097288ms)
|
||||
✔ taskView reads the projection for one business (165.598278ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (335.88327ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (432.111544ms)
|
||||
✔ without an adapter the server refuses every task verb (257.927406ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (223.8076ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (366.707767ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1041.973108ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (313.610793ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (612.705535ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (240.52631ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (482.082285ms)
|
||||
✔ the tester reads the human views a reader reads (193.953556ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.159076ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.373438ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.195533ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (138.304962ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (914.609196ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1276.105708ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (871.170845ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (1116.447683ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (413.169724ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1361.477877ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (549.898865ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3596.090145ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (95.549902ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (161.12138ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (156.658782ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (173.350493ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (147.129681ms)
|
||||
✖ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (130.878424ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (149.672749ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (108.753649ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (145.862807ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (507.286444ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (170.074348ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (248.494351ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (149.955281ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.592676ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (164.768712ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (227.662154ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (181.284276ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (239.68938ms)
|
||||
✔ a broker with no web service refuses a granted role (164.352135ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (223.547339ms)
|
||||
✔ a session that is not the role holder is refused (129.599803ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (606.259062ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (175.155244ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (191.337824ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (221.151328ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (135.115199ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (229.690316ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.298526ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (197.596665ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (156.910681ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (461.21964ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (176.173633ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (190.253215ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (158.324249ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 304
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 13459.004011
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:141:1
|
||||
✖ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (256.467001ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /decision-mismatch/. Input:
|
||||
|
||||
'Error: role-end-refused'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:148:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: role-end-refused
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #protectedEnd (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:503:5)
|
||||
at #checkAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:681:53)
|
||||
at #consumeAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:689:40)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1176:33)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at Object.call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/spec-fixtures.mjs:33:49)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:148:25,
|
||||
expected: /decision-mismatch/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/threads.test.mjs:396:1
|
||||
✖ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (130.878424ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /decision-mismatch/. Input:
|
||||
|
||||
'Error: role-end-refused'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/threads.test.mjs:411:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: role-end-refused
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #protectedEnd (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:503:5)
|
||||
at #checkAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:681:53)
|
||||
at #consumeAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:689:40)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1176:33)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:972:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:966:26)
|
||||
at call (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/threads.test.mjs:50:44)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/threads.test.mjs:411:23,
|
||||
expected: /decision-mismatch/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (142.309873ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (231.201892ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (367.803044ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (259.798746ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (397.235171ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (212.02064ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (230.831747ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (216.60349ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (963.843246ms)
|
||||
✔ agents: stranded is per role and per business (374.286349ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (154.105087ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (301.650289ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (202.787714ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (312.824123ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (432.648317ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (339.267456ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (386.665924ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (168.387278ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (281.576631ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (309.051654ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (260.623363ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (368.078554ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (281.304982ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (183.937178ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (203.012845ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (117.076817ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (265.740593ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (299.378572ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (157.033714ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (231.052303ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (161.53335ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (263.180123ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (237.437295ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.662861ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (267.786792ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (360.49961ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (326.513773ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (436.237107ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (290.987227ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (311.667144ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run; its end of the assistant gets past the protection (320.097107ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (249.134553ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (343.47293ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (323.745355ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (440.91704ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (570.161417ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1034.702314ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (130.710467ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (126.238819ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (981.018335ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1846.682878ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (914.705075ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (873.90628ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (959.061595ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (116.849709ms)
|
||||
✔ credentials refuses a role session and any argument (183.716297ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (241.477878ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (267.35318ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.841626ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (4.375213ms)
|
||||
✔ expiry refuses use and env references never become client data (1.410739ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.864275ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.47774ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (2.46137ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (516.024271ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (692.495881ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (494.513961ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (501.732584ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (517.19919ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (412.467321ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (537.983819ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (480.40045ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (495.078512ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (530.385133ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (481.380012ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (435.154144ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (445.391814ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (442.247177ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (376.630317ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (256.416022ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (263.845341ms)
|
||||
✔ a human withdraw sends one message with the note (319.714821ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (443.359587ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (368.603134ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (307.830785ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (307.533623ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (292.212853ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (302.501868ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (317.897026ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (495.946425ms)
|
||||
✔ a refused supersede withdraws nothing (431.790648ms)
|
||||
✔ the assistant's within-role and gated raises still work (324.778931ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (252.393829ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (313.889133ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (378.582693ms)
|
||||
✔ recent stops at RECENT rows (1051.827553ms)
|
||||
✔ every row is what trail already gives the same session for that id (319.899108ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (447.915408ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (415.51024ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (157.673954ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (150.377271ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (171.035152ms)
|
||||
✔ endLaunch leaves a claim another run took alone (201.988658ms)
|
||||
✔ refuse records action.refused against the caller with the code only (208.690888ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (325.591384ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (400.14439ms)
|
||||
✔ REQ-WAIT-1: the broker hard waits are exactly the list, and match the business vocabulary (1.383913ms)
|
||||
✔ REQ-WAIT-2: a business granting a hard wait at either class is refused; the actions that left are grantable (116.094019ms)
|
||||
✔ REQ-DEC-2: every hard wait goes to the human, cited or not, and the arbiter cannot resolve it (888.603613ms)
|
||||
✔ REQ-DEC-2: a gated raise citing the current spec goes to the arbiter for its domain; uncited, to the human (633.272316ms)
|
||||
✔ REQ-DEC-2: an arbiter-approved cited gated decision authorizes the raiser, and the human cannot resolve it (264.993121ms)
|
||||
✔ REQ-DEC-2: a cited merge raised by merge-gate goes to the technical arbiter; a merge raised without the grant routes by citation (316.161815ms)
|
||||
✔ REQ-DEC-2: a stale or unconfirmed citation refuses without a decision; an arbiter raising its own goes to the human (314.106828ms)
|
||||
✔ Q169: the chief of staff's end of the assistant is not refused role-end-refused; its own run and another ender's are (266.282267ms)
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (229.485912ms)
|
||||
✔ Q169: a revoke of the assistant citing a decision the human resolved is not refused by the protection (240.76101ms)
|
||||
✔ Q169: a cited revoke of a role not in END_PROTECTED still goes to the arbiter, and executes (264.547675ms)
|
||||
✔ Q169: a role granted role.revoke at either class still sends a revoke of the assistant to the human (341.174075ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.601705ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.464613ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.660976ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.283166ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (218.531313ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (173.858032ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (147.575196ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (346.114755ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (239.599115ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (359.579029ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (146.317742ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (365.662836ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (217.892093ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (313.059179ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (685.224956ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (221.358863ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (214.294871ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (385.612912ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (3018.395084ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (261.012792ms)
|
||||
✔ views messages passes only its paging arguments through (0.254699ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (212.26414ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (422.215888ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (385.353863ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (440.796041ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (318.289243ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (335.545256ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (377.557884ms)
|
||||
✔ the sender list is checked before the target list (363.151065ms)
|
||||
✔ roles without the field behave exactly as before (448.547393ms)
|
||||
✔ a business with no role definitions at all is unlimited (423.075891ms)
|
||||
✔ a malformed messaging field refuses at boot (119.671095ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (381.325815ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (410.741928ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (366.044928ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (209.124271ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (517.643083ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (475.892132ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (218.819659ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (66.986171ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (220.480367ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (264.099594ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (215.306984ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (67.867886ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (192.541157ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (173.428009ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (177.673555ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (180.81081ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (140.357003ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.288023ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (235.988712ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (236.378394ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (280.418741ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (204.95764ms)
|
||||
✔ a message with no reply gives an empty list (184.844268ms)
|
||||
✔ replies come oldest first and stop at REPLIES (811.37612ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (355.279473ms)
|
||||
✔ strict arguments; a role session gets human-required (383.705107ms)
|
||||
✔ views passes replies through as one call with the id (0.256315ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (232.798166ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (162.494811ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (174.61228ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (248.094559ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (242.82092ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (310.307381ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (448.980334ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (246.57512ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (357.446501ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (470.767628ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (279.341688ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1594.869488ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (283.040113ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (224.657459ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (172.666658ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (396.904502ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (241.703687ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (236.475931ms)
|
||||
✔ class drift gated to within-role refuses before consumption (285.197496ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (325.021228ms)
|
||||
✔ class drift within-role to gated refuses before consumption (231.422614ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (250.952844ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (266.66055ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (284.183249ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1517.976505ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (283.007428ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (211.603937ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (246.520136ms)
|
||||
✔ client disconnect during await tolerates late reply (185.518208ms)
|
||||
✔ client disconnect during await tolerates late refusal (196.536129ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (393.853726ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (329.634523ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (355.084027ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (228.7702ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (292.323439ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (302.42164ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (317.676289ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (185.908016ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (536.226685ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (421.211175ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (431.296622ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (252.770273ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (611.932547ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (452.412719ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (225.026499ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (150.925805ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (144.239155ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (183.717526ms)
|
||||
✔ a tombstone is not open (177.800365ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (202.838706ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (151.210144ms)
|
||||
✔ a human session reads the same state, with the same cap (155.142841ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (169.588689ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (132.415244ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (188.599482ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (227.479788ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (224.306007ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (125.586787ms)
|
||||
✔ async transactions refuse before invoking their function (115.886513ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (338.514121ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (289.375787ms)
|
||||
✔ each filter, alone and together, and total counts every match (348.297857ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (307.676935ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (276.309848ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (931.051792ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (398.585507ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (363.807012ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (134.77228ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (263.742439ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (119.166747ms)
|
||||
✔ a bad entry refuses the whole record (116.552772ms)
|
||||
✔ taskView reads the projection for one business (129.320852ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (249.853068ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (432.680447ms)
|
||||
✔ without an adapter the server refuses every task verb (234.850492ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (211.533809ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (329.425875ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (904.907886ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (267.844483ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (571.467494ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (227.510853ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (264.789573ms)
|
||||
✔ the tester reads the human views a reader reads (182.312101ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.091283ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.339985ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.196834ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (118.235665ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (906.907804ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1111.812707ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (840.29248ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (846.342797ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (364.91389ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1201.307549ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (346.287626ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3581.476413ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (104.052747ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (153.478556ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (156.706006ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (198.6723ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (153.217928ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (144.957507ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (142.841126ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (106.34141ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (717.650965ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (513.631219ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (175.885318ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (184.196596ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (115.427156ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.824489ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (156.279664ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (145.989984ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (172.092623ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (212.208249ms)
|
||||
✔ a broker with no web service refuses a granted role (147.221811ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (210.059542ms)
|
||||
✔ a session that is not the role holder is refused (122.600863ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (399.420573ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (160.227129ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (177.042197ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (189.97177ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (130.606701ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (231.343444ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.266379ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (212.244347ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (155.516111ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (447.626574ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (168.079457ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (190.484769ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (157.092837ms)
|
||||
ℹ tests 306
|
||||
ℹ suites 0
|
||||
ℹ pass 305
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12767.820872
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/hard-waits.test.mjs:126:1
|
||||
✖ Q169: another role's cited revoke of the assistant, resolved by an arbiter, is refused (229.485912ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /role-end-refused/. Input:
|
||||
|
||||
'Error: decision-mismatch'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:138:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: decision-mismatch
|
||||
at fail (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:104:9)
|
||||
at #checkAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:682:7)
|
||||
at #consumeAuthority (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:688:40)
|
||||
at #dispatch (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:1175:33)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:971:38
|
||||
at Store.transaction (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.request (file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/src/broker.mjs:965:26)
|
||||
at file:///home/jwoltje/dewey-scratch/r139/wt/packages/bus/tests/hard-waits.test.mjs:138:29
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24),
|
||||
expected: /role-end-refused/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
m1-no-spec-check packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:09:11Z end=2026-10-16T19:09:23Z
|
||||
m2-no-hard-wait-check packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:09:23Z end=2026-10-16T19:09:36Z
|
||||
m3-new-action-not-hard-wait packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:09:36Z end=2026-10-16T19:09:49Z
|
||||
m4-hard-wait-routed packages/business/src/vocabulary.mjs suite=business rc=1 KILLED restored=True start=2026-10-16T19:09:49Z end=2026-10-16T19:09:51Z
|
||||
m5-validator-refusal packages/business/src/role.mjs suite=business rc=1 KILLED restored=True start=2026-10-16T19:09:51Z end=2026-10-16T19:09:53Z
|
||||
m6-no-assistant-check packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:09:53Z end=2026-10-16T19:10:06Z
|
||||
m7-no-chief-exemption packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:10:06Z end=2026-10-16T19:10:19Z
|
||||
m8-no-human-exemption packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:10:19Z end=2026-10-16T19:10:33Z
|
||||
m9-no-revoke-protection packages/bus/src/broker.mjs suite=bus rc=1 KILLED restored=True start=2026-10-16T19:10:33Z end=2026-10-16T19:10:46Z
|
||||
Reference in New Issue
Block a user