agents: researcher row 119 packet (#1613): chief-of-staff and assistant role files, PM drops role.launch, org-file entry and one-window landing order
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# Row 119 (#1613): role files for the chief of staff and the assistant
|
||||
|
||||
Researcher, 2026-10-15. Brief: `docs/plans/2026-10-14_prd-1.2-build.md`, "Role files for the chief of
|
||||
staff and the assistant", pinned at 240d25518. Requirements: REQ-COS-1, REQ-ASSIST-1, REQ-ROLE-4,
|
||||
REQ-LAUNCH-1. Decisions 139 (chief holds `role.launch`), 140 (leftover "main point of interaction"
|
||||
duties removed), 144 (Jason's org file isn't edited by the stack). Reviewer: Filbert (decision 130,
|
||||
role files, no sandbox change).
|
||||
|
||||
Base: c6570f142 (`row119.patch` applies cleanly to it by `git apply --cached --check`; no commit
|
||||
between c6570f142 and 9e837ce5f touches a candidate path). No broker, thread or org-file verb changes
|
||||
(rows 120, 121, 124).
|
||||
|
||||
## What changes
|
||||
|
||||
Role files (the candidate):
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `roles/assistant.json` (new) | tools `read grep find ls`; network api-only; `withinRole ["message.send"]`, `crossRole []`; credentials `[]` |
|
||||
| `roles/assistant.md` (new) | REQ-ASSIST-1: talks with the user, passes work to the chief of staff, directs no agent, creates or assigns no task, launches no session |
|
||||
| `roles/chief-of-staff.json` | `withinRole ["message.send", "role.launch"]` (decision 139); tools, network and credentials unchanged |
|
||||
| `roles/chief-of-staff.md` | rewritten to REQ-COS-1; the "main point of interaction" duties are gone (decision 140); never talks to the user |
|
||||
| `roles/pm.json` | `role.launch` removed from `withinRole` (REQ-LAUNCH-1) |
|
||||
| `roles/pm.md` | the launch bullet becomes "Take the work the chief of staff passes you. You don't launch sessions."; "resume or launch work" becomes "resume or start work" |
|
||||
|
||||
Docs and example: `packages/business/README.md` (Chief-of-staff and assistant section, rewritten) and
|
||||
`packages/business/examples/mosaic-stack.example.json` (adds `chief` and `assistant`, `launch.by "chief"`).
|
||||
|
||||
Tests (fixtures follow the roles; the only source files untouched are the packages' `src/`):
|
||||
|
||||
- business: `helpers.mjs` (shared `businessDoc` gains `chief`, `launch.by "chief"`), `business.test.mjs`,
|
||||
`cli.test.mjs`, `resolve.test.mjs`, `role.test.mjs`, `chief-of-staff.test.mjs`, new `assistant.test.mjs`.
|
||||
- harness: `tools.test.mjs` (PM has no launch; new chief and assistant tool lists), `bundle.test.mjs`
|
||||
(PM bundle has no launch; new chief bundle test), `mcp-server.test.mjs`, `pi-session.test.mjs`
|
||||
(the two symlink-write tests and the climbs loop use the PM, because the chief has no write tool).
|
||||
- cli: `launcher.test.mjs` (launcher instance renamed pm to chief; the founder-credentials test launches
|
||||
the coder through a bound chief capability), `trackers-boot.test.mjs` (guards for roles with no
|
||||
tracker or credentials).
|
||||
- webui: `reads.test.mjs` (chief `role.launch` within, PM gated, `b.launch.by "chief"`).
|
||||
- Not changed: `packages/webui/tests/views.test.mjs` (stub fixture, no launch assertion). Correction to
|
||||
my earlier message to Sage: bus needed no fixture edits. Its suite passes 156/156 untouched because
|
||||
its fixtures are in memory.
|
||||
|
||||
Instance names `chief` and `assistant` are my fixture and example choices. Jason picks the real ones.
|
||||
|
||||
## Gate (decision 136, targeted; slot held per sage-0250)
|
||||
|
||||
Worktree `/mnt/storage/scratch/researcher/q119` at c6570f142 plus `row119.patch`. Outputs are in `suites/`.
|
||||
|
||||
| Run | Result |
|
||||
|---|---|
|
||||
| business | 78 / 78 |
|
||||
| bus | 156 / 156 |
|
||||
| harness | 84 / 84 (first pass 81 / 84; the three pi-session symlink tests called `write` on the chief; fixed as above) |
|
||||
| cli | 187 / 187 |
|
||||
| webui | 108 / 108 |
|
||||
| tasks | 92 / 92 |
|
||||
| conversation | 182 / 182 |
|
||||
| seat | 132 / 132 |
|
||||
| `scripts/test-task.sh` | 98 passed, 0 failed |
|
||||
|
||||
## Mutants (`mutants.sh`, `mutants-run.txt`, `mutants/`)
|
||||
|
||||
Eight controls pass. 25 mutants, each one exact-once edit, each run against the named test file:
|
||||
|
||||
| Mutant | Edit | Caught by |
|
||||
|---|---|---|
|
||||
| m1a-f | chief drops `role.launch` | chief-of-staff, harness tools, harness bundle, cli launcher, webui reads, business |
|
||||
| m2a, m2b | PM regains `role.launch` | chief-of-staff ("the pm does not hold role.launch", "launch.by pm refused"), role ("shipped authority follows the note's table") |
|
||||
| m2c, m2d, m2e | same edit | **survive** (harness tools, harness bundle, webui reads); see below |
|
||||
| m3 | assistant gains `role.launch` | assistant |
|
||||
| m4 | assistant gains `write` | assistant |
|
||||
| m5 | assistant gains a crossRole action | assistant |
|
||||
| m6 | assistant gains a credential | assistant |
|
||||
| m7 | chief gains `write` | chief-of-staff |
|
||||
| m8 | chief gains a credential | chief-of-staff |
|
||||
| m9a-c | validator stops requiring `role.launch` of the launcher | chief-of-staff, assistant, business |
|
||||
| m10 | `pm.md` launches again | chief-of-staff (contract pin) |
|
||||
| m11 | `chief-of-staff.md` is the main point of interaction again | chief-of-staff (contract pin) |
|
||||
| m12 | `assistant.md` directs agents | assistant (contract pin) |
|
||||
| m13a, m13b | `assistant.json` names a missing contract | role ("every role file in roles/ loads through the validator"), assistant |
|
||||
|
||||
Why m2c, m2d and m2e survive: `packages/business/src/resolve.mjs:74` keeps `role.launch` only for the
|
||||
instance `launch.by` names, and lines 76-77 filter it out of every other instance. The PM is never
|
||||
`launch.by` in the fixtures, so a PM role file that holds `role.launch` resolves with it gated, and the
|
||||
harness tools, harness bundle and webui reads see the same effective result as before the edit. Those
|
||||
tests pin the resolved behaviour, which stays safe. The role file itself is pinned where it is read,
|
||||
by m2a and m2b in the business package. The broker has the same gate at `packages/bus/src/broker.mjs:305`
|
||||
(`role.launch` is gated unless `business.launch.by === s.role`). Sage agreed on 2026-10-15 (sage-0255).
|
||||
|
||||
## What Jason has to do, and in what order
|
||||
|
||||
The stack never writes Jason's org file (decision 144). Row 119 ships the role files; the entry below is
|
||||
what makes them usable. File: `~/.config/mosaic-dev/businesses/mosaic-stack.json`.
|
||||
|
||||
Add under `roles` (names are Jason's choice; `vars` mirror the PM's, and the assistant's harness and model
|
||||
are his call):
|
||||
|
||||
```json
|
||||
"chief": {
|
||||
"definition": "chief-of-staff",
|
||||
"vars": { "harness": "claude-code", "model": "claude-opus-5-5", "thinking": "high" }
|
||||
},
|
||||
"assistant": {
|
||||
"definition": "assistant",
|
||||
"holder": "mos",
|
||||
"vars": { "harness": "claude-code", "model": "claude-opus-5-5", "thinking": "high" }
|
||||
}
|
||||
```
|
||||
|
||||
and change `launch.by` from `"pm"` to `"chief"` (`instances` and `max` stay as they are:
|
||||
`["coder","reviewer"]`, `{"opus":4,"sonnet":4}`). Neither instance takes `tracker` or `credentials`; the
|
||||
validator refuses both.
|
||||
|
||||
### Landing order: one window, PM idle
|
||||
|
||||
- Before the re-pin, Jason can't name a chief instance in `launch.by`: the pinned copy's
|
||||
`chief-of-staff.json` lacks `role.launch`, so the old copy refuses it.
|
||||
- After the re-pin, his current file (`launch.by: "pm"`) fails to load, because the new `pm.json` no
|
||||
longer holds `role.launch`.
|
||||
- So his edit and the re-pin happen in one window run by Mos, with the PM run idle. This is the same
|
||||
pattern as decision 145 for row 122. The re-pin is Sage's and lands with rows 104, 106 and 109.
|
||||
- Until Jason adds the entry, the broker keeps `role.launch` gated for any chief-of-staff session
|
||||
(`broker.mjs:305`: `launch.by` is still `pm`). That is expected and not a defect.
|
||||
|
||||
### After that window
|
||||
|
||||
Only a running chief-of-staff session can launch. Until one runs, coders and reviewers don't start.
|
||||
Mos needs to plan the window with that in mind: start the chief session first, then let it launch the
|
||||
rest. This ships what decision 139 chose; it is not a defect in the row.
|
||||
|
||||
## Out of scope and follow-ups
|
||||
|
||||
- Broker send limits for the assistant: row 120 (REQ-ASSIST-2, #1614), mine next.
|
||||
- Threads, org-file verbs, anything under `packages/bus/src`: rows 121, 124, 128.
|
||||
- `scripts/test-task.sh` still names `pm cto coder reviewer` in its shipped-roles loop; the node tests
|
||||
(`role.test.mjs`) load every role file, so I left the script alone.
|
||||
|
||||
## Files in this packet
|
||||
|
||||
`row119.patch`, `candidate-manifest.sha256` (the 22 post-patch candidate files), `mutants.sh`,
|
||||
`mutants-run.txt`, `mutants/` (per-mutant output, return code, patch), `suites/` (suite output),
|
||||
`packet-manifest.sha256` (digests of the packet files themselves).
|
||||
@@ -0,0 +1,22 @@
|
||||
0fe45e5c62e73dc84674e6ed8c3354ad489b6c6ece540042ff246a0abb3da9e3 packages/business/examples/mosaic-stack.example.json
|
||||
f5bcb448a5d27c2da425536ad0487bb24c63dd6d8ec169a944fc67d25effa00f packages/business/README.md
|
||||
0c4d1e87fe76911cb9252320ac5efc98394cb3d5a8403fd4ab2be6d57adf9c56 packages/business/tests/assistant.test.mjs
|
||||
907074699b67f61ada185123547c65da75ddde591bc6c703cc0dcb14dbb3af7c packages/business/tests/business.test.mjs
|
||||
e308edbf5e15e6a55fc0ce6eb8b1ccadb3f0c3071146b59a5139bf8ddb231b6f packages/business/tests/chief-of-staff.test.mjs
|
||||
653ae43cfe894dcf486cad6963bcde0d33c811642d4ebd927d727f95983f2dfa packages/business/tests/cli.test.mjs
|
||||
2490610d70bf3f03778a3cf2f59a31fa8d9b3fa425dd9b531e4aa2f8ed4b0b8f packages/business/tests/helpers.mjs
|
||||
9fe2fecc03af3ad31e880bf611dc55e75a25b54f95502baa282eb820c7a90043 packages/business/tests/resolve.test.mjs
|
||||
028751009b33fe068ceb33603d08f39982e06d870a7e7a6e4a2f2eb2fd6049cd packages/business/tests/role.test.mjs
|
||||
d95115368e3711ad6a59a7f7570a5b35ac93ff528e513e53f0f039140d9b7b35 packages/cli/tests/launcher.test.mjs
|
||||
250c3413e51994928c3860da940947aa8f94afe3938cba8236af8c650509bced packages/cli/tests/trackers-boot.test.mjs
|
||||
3792f9d2b8d41e27d2eb07b1f6b190639a4e75221c6bcf2bda830363f176bc5a packages/harness/tests/bundle.test.mjs
|
||||
fb229602039dcecfc609e51f7176f264fbbfbe23cd7897ec86a524cab3f58695 packages/harness/tests/mcp-server.test.mjs
|
||||
cd88d390187fba8dcb7acd0ef05c56306dcb8d60eb7f4f635520f2bad19be83c packages/harness/tests/pi-session.test.mjs
|
||||
8f92328d54ec790ae2aca7c04b5c768e146120152a46fa01bab3007591106101 packages/harness/tests/tools.test.mjs
|
||||
2d9f2a3ce4865087fe7b865f48dbc71564fc0efd26e7834aeab05ed796fcc98c packages/webui/tests/reads.test.mjs
|
||||
35b6465f280999ebac881d941cb6e5cc618e68e6bf55bfccecf27ea1c961c992 roles/assistant.json
|
||||
f97fe0b24d8873ace1aa65140336085bf012ad794acf03087053fad4a0c7bd02 roles/assistant.md
|
||||
28e394bba7a4991c5f7edd41d40499ec35cbcd56bd72d412f3c69a45b0ed0284 roles/chief-of-staff.json
|
||||
f0238afad94190fc0dfbbf7fa97d283df0091dfe17f0be38c5b638d635700744 roles/chief-of-staff.md
|
||||
a74cbd80054356658cb6517654a016d2111bdbba15a606f982a5aabe1c34dc5d roles/pm.json
|
||||
7087d972d285f5260859bd40500904665bdd01e1c4d9bf89d405b5ea292faf2c roles/pm.md
|
||||
@@ -0,0 +1,147 @@
|
||||
control-chief-of-staff: exit 0; ℹ tests 10 ℹ pass 10 ℹ fail 0
|
||||
control-assistant: exit 0; ℹ tests 7 ℹ pass 7 ℹ fail 0
|
||||
control-role: exit 0; ℹ tests 13 ℹ pass 13 ℹ fail 0
|
||||
control-business: exit 0; ℹ tests 15 ℹ pass 15 ℹ fail 0
|
||||
control-tools: exit 0; ℹ tests 13 ℹ pass 13 ℹ fail 0
|
||||
control-bundle: exit 0; ℹ tests 9 ℹ pass 9 ℹ fail 0
|
||||
control-launcher: exit 0; ℹ tests 17 ℹ pass 17 ℹ fail 0
|
||||
control-reads: exit 0; ℹ tests 10 ℹ pass 10 ℹ fail 0
|
||||
m1a-chief-drops-launch: exit 1; ℹ tests 10 ℹ pass 3 ℹ fail 7
|
||||
failed: ✖ a business grant of a gated action through limits does not widen the role
|
||||
failed: ✖ a limit that drops role.launch leaves the chief of staff with no launch block
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the chief of staff holds role.launch and message.send; every other action is gated
|
||||
failed: ✖ the pm does not hold role.launch
|
||||
failed: ✖ the resolved record matches the approved list, so a widened file fails
|
||||
failed: ✖ the role file loads and resolves through loadBusiness
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m1b-chief-drops-launch: exit 1; ℹ tests 13 ℹ pass 3 ℹ fail 10
|
||||
failed: ✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker
|
||||
failed: ✖ a coder with a tracker gets its own task tools and no task_reassign
|
||||
failed: ✖ an action outside the instance's authority has no tool
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ launch only when the business's launch block names the instance as launcher
|
||||
failed: ✖ list_requirements reads the requirement ids, for a task.create holder with a tracker
|
||||
failed: ✖ list_tasks takes the broker's filters and pages; get_task takes a task_ref
|
||||
failed: ✖ the assistant gets send_message and the reads, no launch
|
||||
failed: ✖ the chief of staff gets launch and send_message, and no task verbs
|
||||
failed: ✖ the PM gets its task verbs and the reads, and no launch
|
||||
failed: ✖ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM
|
||||
m1c-chief-drops-launch: exit 1; ℹ tests 9 ℹ pass 0 ℹ fail 9
|
||||
failed: ✖ a bundle is written once: an existing file refuses
|
||||
failed: ✖ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools
|
||||
failed: ✖ a claude-code bundle adds the wrapped gate hook and the MCP config
|
||||
failed: ✖ a path with a single quote can't go into the hook command
|
||||
failed: ✖ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ sessionModel: agent vars win, then the system's execution settings
|
||||
failed: ✖ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review
|
||||
failed: ✖ the prompt names the project clones in the workspace, and none when there are none
|
||||
failed: ✖ the prompt's built-in tools line is the harness's own names, as the manifest lists them
|
||||
m1d-chief-drops-launch: exit 1; ℹ tests 17 ℹ pass 1 ℹ fail 14
|
||||
failed: ✖ a Claude Code launch with no session credential refuses before it starts
|
||||
failed: ✖ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again
|
||||
failed: ✖ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again
|
||||
failed: ✖ a launch client that never closes its side doesn't hold the host's close
|
||||
failed: ✖ a malformed sessions.json refuses the host start with exit 3 and stays as it was
|
||||
failed: ✖ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback
|
||||
failed: ✖ an over-long launch request is refused at once, not at the 10 s idle timeout
|
||||
failed: ✖ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables
|
||||
failed: ✖ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left
|
||||
failed: ✖ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold
|
||||
failed: ✖ a runner killed from the host ends its launch as killed, not failed
|
||||
failed: ✖ a runner that ignores SIGTERM is killed when the host closes
|
||||
failed: ✖ a runner that stops at once ends its launch with the runner's reason
|
||||
failed: ✖ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest
|
||||
failed: ✖ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code
|
||||
m1e-chief-drops-launch: exit 1; ℹ tests 10 ℹ pass 9 ℹ fail 1
|
||||
failed: ✖ business: names, vars on the allowlist, authority, credential metadata only
|
||||
failed: ✖ failing tests:
|
||||
m1f-chief-drops-launch: exit 1; ℹ tests 15 ℹ pass 6 ℹ fail 9
|
||||
failed: ✖ a role without Vikunja takes no tracker block
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ launch
|
||||
failed: ✖ loadBusiness: file checks
|
||||
failed: ✖ loading writes nothing
|
||||
failed: ✖ names that are Object.prototype properties don't count as declared
|
||||
failed: ✖ the fixture business validates and comes back frozen
|
||||
failed: ✖ the shipped example refuses as written and validates once filled in
|
||||
failed: ✖ two instances may share a definition
|
||||
failed: ✖ Vikunja bots
|
||||
m2a-pm-regains-launch: exit 1; ℹ tests 10 ℹ pass 8 ℹ fail 2
|
||||
failed: ✖ a launch block whose by is the pm instance is refused
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the pm does not hold role.launch
|
||||
m2b-pm-regains-launch: exit 1; ℹ tests 13 ℹ pass 12 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ shipped authority follows the note's table
|
||||
m2c-pm-regains-launch: exit 0; ℹ tests 13 ℹ pass 13 ℹ fail 0
|
||||
m2d-pm-regains-launch: exit 0; ℹ tests 9 ℹ pass 9 ℹ fail 0
|
||||
m2e-pm-regains-launch: exit 0; ℹ tests 10 ℹ pass 10 ℹ fail 0
|
||||
m3-assistant-launch: exit 1; ℹ tests 7 ℹ pass 4 ℹ fail 3
|
||||
failed: ✖ a launch block whose by is the assistant is refused
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the assistant's authority is message.send within role and nothing else
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m4-assistant-write: exit 1; ℹ tests 7 ℹ pass 6 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m5-assistant-crossrole: exit 1; ℹ tests 7 ℹ pass 5 ℹ fail 2
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the assistant's authority is message.send within role and nothing else
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m6-assistant-credential: exit 1; ℹ tests 7 ℹ pass 1 ℹ fail 6
|
||||
failed: ✖ a business grant through limits does not widen the role
|
||||
failed: ✖ a launch block whose by is the assistant is refused
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the assistant's authority is message.send within role and nothing else
|
||||
failed: ✖ the instance takes no credential references and no tracker
|
||||
failed: ✖ the role file loads and resolves through loadBusiness
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m7-chief-write: exit 1; ℹ tests 10 ℹ pass 8 ℹ fail 2
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the resolved record matches the approved list, so a widened file fails
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m8-chief-credential: exit 1; ℹ tests 10 ℹ pass 1 ℹ fail 9
|
||||
failed: ✖ a business grant of a gated action through limits does not widen the role
|
||||
failed: ✖ a launch block whose by is the pm instance is refused
|
||||
failed: ✖ a limit that drops role.launch leaves the chief of staff with no launch block
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the chief of staff holds role.launch and message.send; every other action is gated
|
||||
failed: ✖ the instance takes no credential references and no tracker
|
||||
failed: ✖ the pm does not hold role.launch
|
||||
failed: ✖ the resolved record matches the approved list, so a widened file fails
|
||||
failed: ✖ the role file loads and resolves through loadBusiness
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
m9a-validator-accepts-any-launcher: exit 1; ℹ tests 10 ℹ pass 9 ℹ fail 1
|
||||
failed: ✖ a launch block whose by is the pm instance is refused
|
||||
failed: ✖ failing tests:
|
||||
m9b-validator-accepts-any-launcher: exit 1; ℹ tests 7 ℹ pass 6 ℹ fail 1
|
||||
failed: ✖ a launch block whose by is the assistant is refused
|
||||
failed: ✖ failing tests:
|
||||
m9c-validator-accepts-any-launcher: exit 1; ℹ tests 15 ℹ pass 14 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ launch
|
||||
m10-pm-contract-launches: exit 1; ℹ tests 10 ℹ pass 9 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the contract names no duty to talk to the human and the pm contract no launch
|
||||
m11-chief-contract-talks: exit 1; ℹ tests 10 ℹ pass 9 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the contract names no duty to talk to the human and the pm contract no launch
|
||||
m12-assistant-contract-directs: exit 1; ℹ tests 7 ℹ pass 6 ℹ fail 1
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the contract passes work to the chief of staff and directs no one
|
||||
m13a-assistant-contract-missing: exit 1; ℹ tests 13 ℹ pass 12 ℹ fail 1
|
||||
failed: ✖ every role file in roles/ loads through the validator, and a v2 contract exists
|
||||
failed: ✖ failing tests:
|
||||
m13b-assistant-contract-missing: exit 1; ℹ tests 7 ℹ pass 1 ℹ fail 6
|
||||
failed: ✖ a business grant through limits does not widen the role
|
||||
failed: ✖ a launch block whose by is the assistant is refused
|
||||
failed: ✖ failing tests:
|
||||
failed: ✖ the assistant's authority is message.send within role and nothing else
|
||||
failed: ✖ the instance takes no credential references and no tracker
|
||||
failed: ✖ the role file loads and resolves through loadBusiness
|
||||
failed: ✖ the shipped file is exactly the approved list
|
||||
done
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
# Row 119 (#1613): role files for the chief of staff and the assistant.
|
||||
# Each check must fail on a mutant. For each mutant this runs one named test file against the
|
||||
# real source (control) and against the source with one exact-once text edit, in the given worktree,
|
||||
# one test file at a time, and restores every source file on exit.
|
||||
# Usage: mutants.sh <worktree> <outdir>
|
||||
set -u
|
||||
WT=$(cd "$1" && pwd); OUT=$(mkdir -p "$2" && cd "$2" && pwd)
|
||||
cd "$WT" || exit 2
|
||||
BAK=$(mktemp -d "$OUT/.bak.XXXXXX")
|
||||
declare -A SAVED
|
||||
save() { [ -n "${SAVED[$1]:-}" ] || { mkdir -p "$BAK/$(dirname "$1")"; cp "$1" "$BAK/$1"; SAVED[$1]=1; }; }
|
||||
restore() { for f in "${!SAVED[@]}"; do cp "$BAK/$f" "$f"; done; rm -rf "$BAK"; }
|
||||
trap restore EXIT
|
||||
edit() { # file old new: exact-once replace
|
||||
save "$1"
|
||||
node -e '
|
||||
const fs = require("fs"); const [f, a, b] = process.argv.slice(1);
|
||||
const s = fs.readFileSync(f, "utf8"); const n = s.split(a).length - 1;
|
||||
if (n !== 1) { console.error("expected one match, found " + n); process.exit(3); }
|
||||
fs.writeFileSync(f, s.replace(a, () => b));
|
||||
' "$1" "$2" "$3"
|
||||
}
|
||||
run() { # name testfile
|
||||
setsid -w timeout -k 10 400 node --test "$2" > "$OUT/$1.out" 2>&1; echo "$?" > "$OUT/$1.rc"
|
||||
echo "$1: exit $(cat "$OUT/$1.rc"); $(grep -E '^ℹ (tests|pass|fail)' "$OUT/$1.out" | tr '\n' ' ')"
|
||||
grep -E '^✖' "$OUT/$1.out" | sort -u | sed 's/ ([0-9.]*ms)$//' | sed "s/^/ failed: /"
|
||||
}
|
||||
mutant() { # name testfile file old new
|
||||
edit "$3" "$4" "$5" || { echo "$1: edit failed"; return; }
|
||||
diff -u "$BAK/$3" "$3" > "$OUT/$1.patch"
|
||||
run "$1" "$2"
|
||||
cp "$BAK/$3" "$3"
|
||||
}
|
||||
BT=packages/business/tests; HT=packages/harness/tests; CT=packages/cli/tests; WT_=packages/webui/tests
|
||||
COS=$BT/chief-of-staff.test.mjs; AST=$BT/assistant.test.mjs; ROLE=$BT/role.test.mjs; BUS=$BT/business.test.mjs
|
||||
TOOLS=$HT/tools.test.mjs; BUNDLE=$HT/bundle.test.mjs; LAUNCH=$CT/launcher.test.mjs; READS=$WT_/reads.test.mjs
|
||||
C=roles/chief-of-staff.json; P=roles/pm.json; A=roles/assistant.json; V=packages/business/src/business.mjs
|
||||
for t in "$COS" "$AST" "$ROLE" "$BUS" "$TOOLS" "$BUNDLE" "$LAUNCH" "$READS"; do run "control-$(basename "$t" .test.mjs)" "$t"; done
|
||||
|
||||
# m1: the chief of staff loses role.launch (REQ-COS-1, decision 139)
|
||||
for pair in "a $COS" "b $TOOLS" "c $BUNDLE" "d $LAUNCH" "e $READS" "f $BUS"; do
|
||||
set -- $pair
|
||||
mutant "m1$1-chief-drops-launch" "$2" "$C" '"withinRole": ["message.send", "role.launch"]' '"withinRole": ["message.send"]'
|
||||
done
|
||||
# m2: the PM regains role.launch (REQ-LAUNCH-1)
|
||||
for pair in "a $COS" "b $ROLE" "c $TOOLS" "d $BUNDLE" "e $READS"; do
|
||||
set -- $pair
|
||||
mutant "m2$1-pm-regains-launch" "$2" "$P" '"task.close", "message.send"]' '"task.close", "message.send", "role.launch"]'
|
||||
done
|
||||
# m3: the assistant gains role.launch
|
||||
mutant m3-assistant-launch "$AST" "$A" '"withinRole": ["message.send"]' '"withinRole": ["message.send", "role.launch"]'
|
||||
# m4: the assistant gains a write tool
|
||||
mutant m4-assistant-write "$AST" "$A" '"tools": ["read", "grep", "find", "ls"]' '"tools": ["read", "write", "grep", "find", "ls"]'
|
||||
# m5: the assistant gains a cross-role action
|
||||
mutant m5-assistant-crossrole "$AST" "$A" '"crossRole": []' '"crossRole": ["task.priority.change"]'
|
||||
# m6: the assistant gains a credential
|
||||
mutant m6-assistant-credential "$AST" "$A" '"credentials": []' '"credentials": [{"service": "gitea", "scopes": ["read:user"]}]'
|
||||
# m7: the chief of staff gains a write tool
|
||||
mutant m7-chief-write "$COS" "$C" '"tools": ["read", "grep", "find", "ls"]' '"tools": ["read", "write", "grep", "find", "ls"]'
|
||||
# m8: the chief of staff gains a credential
|
||||
mutant m8-chief-credential "$COS" "$C" '"credentials": []' '"credentials": [{"service": "gitea", "scopes": ["read:user"]}]'
|
||||
# m9: the validator stops requiring role.launch of the launcher
|
||||
for pair in "a $COS" "b $AST" "c $BUS"; do
|
||||
set -- $pair
|
||||
mutant "m9$1-validator-accepts-any-launcher" "$2" "$V" 'if (!launcher.authority.withinRole.includes("role.launch")) {' 'if (false) {'
|
||||
done
|
||||
# m10: the PM contract launches again
|
||||
mutant m10-pm-contract-launches "$COS" roles/pm.md "You don't launch sessions." "Launch coders and reviewers when a task is ready."
|
||||
# m11: the chief of staff contract talks to the user again
|
||||
mutant m11-chief-contract-talks "$COS" roles/chief-of-staff.md "You never talk to the user." "You never talk to the user, but you are the main point of interaction."
|
||||
# m12: the assistant contract directs agents again
|
||||
mutant m12-assistant-contract-directs "$AST" roles/assistant.md "You don't direct" "You direct"
|
||||
# m13: a shipped role file names a contract that isn't there (every shipped role loads)
|
||||
for pair in "a $ROLE" "b $AST"; do
|
||||
set -- $pair
|
||||
mutant "m13$1-assistant-contract-missing" "$2" "$A" '"contract": "assistant.md"' '"contract": "missing.md"'
|
||||
done
|
||||
echo done
|
||||
@@ -0,0 +1,15 @@
|
||||
✔ the role file loads and resolves through loadBusiness (5.380069ms)
|
||||
✔ the shipped file is exactly the approved list (0.617395ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.692848ms)
|
||||
✔ a business grant through limits does not widen the role (1.301892ms)
|
||||
✔ a launch block whose by is the assistant is refused (1.685068ms)
|
||||
✔ the instance takes no credential references and no tracker (2.082295ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.260393ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 75.186139
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,17 @@
|
||||
✔ sessionModel: agent vars win, then the system's execution settings (8.173961ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (3.869685ms)
|
||||
✔ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (1.94595ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (2.003966ms)
|
||||
✔ the prompt's built-in tools line is the harness's own names, as the manifest lists them (6.339124ms)
|
||||
✔ the prompt names the project clones in the workspace, and none when there are none (4.679244ms)
|
||||
✔ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (5.569899ms)
|
||||
✔ a bundle is written once: an existing file refuses (1.284826ms)
|
||||
✔ a path with a single quote can't go into the hook command (1.267172ms)
|
||||
ℹ tests 9
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 108.140666
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,23 @@
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (1.166197ms)
|
||||
✔ the fixture business validates and comes back frozen (3.596814ms)
|
||||
✔ two instances may share a definition (1.185427ms)
|
||||
✔ top-level refusals (3.040992ms)
|
||||
✔ arbiters and projects (4.657842ms)
|
||||
✔ role instances (2.599191ms)
|
||||
✔ Vikunja bots (5.514796ms)
|
||||
✔ a role without Vikunja takes no tracker block (1.950376ms)
|
||||
✔ credential references match the definition's services (2.140196ms)
|
||||
✔ launch (7.052738ms)
|
||||
✔ loadBusiness: file checks (1.956659ms)
|
||||
✔ loadBusiness: not a regular file (37.826353ms)
|
||||
✔ loading writes nothing (1.064115ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.597286ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.596556ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 136.706583
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,18 @@
|
||||
✔ the role file loads and resolves through loadBusiness (5.091607ms)
|
||||
✔ the shipped file is exactly the approved list (0.188753ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.373328ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.153466ms)
|
||||
✔ the pm does not hold role.launch (1.076093ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.074327ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.12725ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.074131ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.266941ms)
|
||||
✔ the instance takes no credential references and no tracker (1.451867ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 10
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 72.564157
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,25 @@
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1176.763228ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (403.445783ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3505.567701ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (115.683865ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (189.134417ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (86.958219ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (173.26982ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (231.076999ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (98.960576ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1045.475968ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (603.186416ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3549.875105ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (87.166383ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (97.452561ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (94.048463ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1203.975856ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (5.024922ms)
|
||||
ℹ tests 17
|
||||
ℹ suites 0
|
||||
ℹ pass 17
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12757.275816
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,18 @@
|
||||
✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.165102ms)
|
||||
✔ credential state from the date alone, as the bus states it (0.135356ms)
|
||||
✔ queue: rows, one row, ids and methods, notes; no path or id from a row (324.567354ms)
|
||||
✔ queue: a refused read fails closed with the store's text, redacted (175.047944ms)
|
||||
✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (735.04744ms)
|
||||
✔ business: names, vars on the allowlist, authority, credential metadata only (8.501691ms)
|
||||
✔ business: missing or invalid file refuses with the module's text, redacted (7.238663ms)
|
||||
✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.790176ms)
|
||||
✔ settings: release, board, loopback address, notifier binding name only (97.613512ms)
|
||||
✔ task fields: the committed table with no reads configured, GET only; a bad table refuses with no path (17.893823ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 10
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1463.493381
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,21 @@
|
||||
✔ the four shipped version 2 roles load (2.410958ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.722453ms)
|
||||
✔ shipped authority follows the note's table (0.466127ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (0.446442ms)
|
||||
✔ version 1 files keep loading with no authority (0.804793ms)
|
||||
✔ the conductor policy isn't a role (0.189712ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.381166ms)
|
||||
✔ version 2 refusals (1.001994ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (1.606018ms)
|
||||
✔ credentials: Gitea scopes (0.667001ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.816119ms)
|
||||
✔ credentials: services (0.388723ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.767818ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 66.911114
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,21 @@
|
||||
✔ the PM gets its task verbs and the reads, and no launch (5.785325ms)
|
||||
✔ the chief of staff gets launch and send_message, and no task verbs (1.69927ms)
|
||||
✔ the assistant gets send_message and the reads, no launch (1.910748ms)
|
||||
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (2.337574ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (1.005499ms)
|
||||
✔ a coder with a tracker gets its own task tools and no task_reassign (0.964471ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (1.707095ms)
|
||||
✔ an action outside the instance's authority has no tool (1.248353ms)
|
||||
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (3.343682ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (7.281014ms)
|
||||
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (2.090985ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (1.99025ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.696522ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 100.217643
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,103 @@
|
||||
✔ the role file loads and resolves through loadBusiness (5.021267ms)
|
||||
✔ the shipped file is exactly the approved list (0.197538ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.283835ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.057029ms)
|
||||
✔ the pm does not hold role.launch (1.034891ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.110785ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.098455ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.106585ms)
|
||||
✖ the contract names no duty to talk to the human and the pm contract no launch (0.901615ms)
|
||||
✔ the instance takes no credential references and no tracker (1.481531ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 69.339697
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:132:1
|
||||
✖ the contract names no duty to talk to the human and the pm contract no launch (0.901615ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /You don't launch sessions/. Input:
|
||||
|
||||
'# Role contract: product manager (pm)\n' +
|
||||
'\n' +
|
||||
"You hold the `pm` role for one business. You turn the business's approved\n" +
|
||||
'requirements into tasks, keep the board in order and decide delivery\n' +
|
||||
"order. You don't write the product's code and you don't review it.\n" +
|
||||
'\n' +
|
||||
'## Duties\n' +
|
||||
'\n' +
|
||||
'- Break each approved requirement into tasks on the tracker. Every task\n' +
|
||||
' you create cites the requirement id it serves, such as `REQ-TASK-1`,\n' +
|
||||
' and the human request that asked for it. A task without both is\n' +
|
||||
' refused.\n' +
|
||||
'- Before creating a task, pick its requirement id from\n' +
|
||||
" `list_requirements`, the approved PRD's list. `task_create` refuses\n" +
|
||||
' any other id. The request is the `request <id>` in the header of the\n' +
|
||||
" human message you're answering, not the message's own id.\n" +
|
||||
"- When no id fits the request, don't create the task, and don't ask in\n" +
|
||||
' your answer. Raise a decision with action `prd.approve`, `blocking`\n' +
|
||||
' false and no `task_ref`, naming the request and the nearest ids. It\n' +
|
||||
" goes to the human's Inbox.\n" +
|
||||
'- Assign each task to a role instance the business file declares, set\n' +
|
||||
' its schedule and priority, and close it when its acceptance evidence\n' +
|
||||
' is in.\n' +
|
||||
'- `task_close` cites a review verdict id. Find it with `trail` on the\n' +
|
||||
' task, as a `review.verdict` event. A task with pushed work closes only\n' +
|
||||
' on an `approve` verdict for its latest push: a missing, `changes` or\n' +
|
||||
' stale verdict is refused.\n' +
|
||||
'- You arbitrate delivery order. When two roles disagree about what ships\n' +
|
||||
' first, the decision comes to you, and you resolve it with a reason.\n' +
|
||||
'- Take the work the chief of staff passes you. Launch coders and reviewers when a task is ready.\n' +
|
||||
' When a task needs a coder or reviewer session, say so to the chief of\n' +
|
||||
' staff by message, naming the role instance and the task.\n' +
|
||||
'\n' +
|
||||
'## Authority\n' +
|
||||
'\n' +
|
||||
"Your role file lists what you do on your own, what needs another role's\n" +
|
||||
'arbiter, and what goes to the human. The launch record you received shows\n' +
|
||||
'the resolved list for this business and project, which may be narrower.\n' +
|
||||
"Anything the list doesn't name is gated: raise a decision for the human\n" +
|
||||
'and wait for it. Never route around a refusal.\n' +
|
||||
'\n' +
|
||||
'A blocking decision holds a task: it needs `task_ref`, and the task\n' +
|
||||
'waits for the answer. A decision with no task is non-blocking, and a\n' +
|
||||
"gated one still reaches the human's Inbox.\n" +
|
||||
'\n' +
|
||||
'Only the human stops a run, with `mosaic stop`. If you think a coder or\n' +
|
||||
'reviewer run should stop, raise a `role.revoke` decision with `blocking`\n' +
|
||||
'false and the role instance as target, naming the run and saying why.\n' +
|
||||
'\n' +
|
||||
"Changing a task's priority or scope against the CTO's technical call is\n" +
|
||||
'cross-role. Raise it as a decision for the technical arbiter.\n' +
|
||||
'\n' +
|
||||
'## Protocol\n' +
|
||||
'\n' +
|
||||
'- You act on the tracker and on Gitea only through the typed tools the\n' +
|
||||
' broker gives you. You never hold a token.\n' +
|
||||
'- Each turn opens with a "Current state" block, read when the turn\n' +
|
||||
' started. It is the truth for launch state and task status. A message\n' +
|
||||
' or a note of yours that disagrees with it is out of date. Before you\n' +
|
||||
' plan to resume or start work on a task, check the task with\n' +
|
||||
' `get_task`.\n' +
|
||||
'- Send messages through the bus, addressed to a role, not a person.\n' +
|
||||
'- Report a blocker as soon as you find it, with what you tried.\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:139: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: '# Role contract: product manager (pm)\n\nYou hold the `pm` role for one business. You turn the business\'s approved\nrequirements into tasks, keep the board in order and decide delivery\norder. You don\'t write the product\'s code and you don\'t review it.\n\n## Duties\n\n- Break each approved requirement into tasks on the tracker. Every task\n you create cites the requirement id it serves, such as `REQ-TASK-1`,\n and the human request that asked for it. A task without both is\n refused.\n- Before creating a task, pick its requirement id from\n `list_requirements`, the approved PRD\'s list. `task_create` refuses\n any other id. The request is the `request <id>` in the header of the\n human message you\'re answering, not the message\'s own id.\n- When no id fits the request, don\'t create the task, and don\'t ask in\n your answer. Raise a decision with action `prd.approve`, `blocking`\n false and no `task_ref`, naming the request and the nearest ids. It\n goes to the human\'s Inbox.\n- Assign each task to a role instance the business file declares, set\n its schedule and priority, and close it when its acceptance evidence\n is in.\n- `task_close` cites a review verdict id. Find it with `trail` on the\n task, as a `review.verdict` event. A task with pushed work closes only\n on an `approve` verdict for its latest push: a missing, `changes` or\n stale verdict is refused.\n- You arbitrate delivery order. When two roles disagree about what ships\n first, the decision comes to you, and you resolve it with a reason.\n- Take the work the chief of staff passes you. Launch coders and reviewers when a task is ready.\n When a task needs a coder or reviewer session, say so to the chief of\n staff by message, naming the role instance and the task.\n\n## Authority\n\nYour role file lists what you do on your own, what needs another role\'s\narbiter, and what goes to the human. The launch record you received shows\nthe resolved list for this business and project, which may be narrower.\nAnything the list doesn\'t name is gated: raise a decision for the human\nand wait for it. Never route around a refusal.\n\nA blocking decision holds a task: it needs `task_ref`, and the task\nwaits for the answer. A decision with no task is non-blocking, and a\ngated one still reaches the human\'s Inbox.\n\nOnly the human stops a run, with `mosaic stop`. If you think a coder or\nreviewer run should stop, raise a `role.revoke` decision with `blocking`\nfalse and the role instance as target, naming the run and saying why.\n\nChanging a task\'s priority or scope against the CTO\'s technical call is\ncross-role. Raise it as a decision for the technical arbiter.\n\n## Protocol\n\n- You act on the tracker and on Gitea only through the typed tools the\n broker gives you. You never hold a token.\n- Each turn opens with a "Current state" block, read when the turn\n started. It is the truth for launch state and task status. A message\n or a note of yours that disagrees with it is out of date. Before you\n plan to resume or start work on a task, check the task with\n `get_task`.\n- Send messages through the bus, addressed to a role, not a person.\n- Report a blocker as soon as you find it, with what you tried.\n',
|
||||
expected: /You don't launch sessions/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.md 2026-10-14 19:38:55.168411949 -0500
|
||||
+++ roles/pm.md 2026-10-14 19:38:55.184649711 -0500
|
||||
@@ -27,7 +27,7 @@
|
||||
stale verdict is refused.
|
||||
- You arbitrate delivery order. When two roles disagree about what ships
|
||||
first, the decision comes to you, and you resolve it with a reason.
|
||||
-- Take the work the chief of staff passes you. You don't launch sessions.
|
||||
+- Take the work the chief of staff passes you. Launch coders and reviewers when a task is ready.
|
||||
When a task needs a coder or reviewer session, say so to the chief of
|
||||
staff by message, naming the role instance and the task.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,95 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.941113ms)
|
||||
✔ the shipped file is exactly the approved list (0.187485ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.376016ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.096444ms)
|
||||
✔ the pm does not hold role.launch (1.101329ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.211125ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.112314ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.178365ms)
|
||||
✖ the contract names no duty to talk to the human and the pm contract no launch (0.845836ms)
|
||||
✔ the instance takes no credential references and no tracker (1.599566ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 70.312162
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:132:1
|
||||
✖ the contract names no duty to talk to the human and the pm contract no launch (0.845836ms)
|
||||
AssertionError [ERR_ASSERTION]: The input was expected to not match the regular expression /main (agent|point of interaction)/i. Input:
|
||||
|
||||
'# Role contract: chief of staff (chief-of-staff)\n' +
|
||||
'\n' +
|
||||
'You hold the `chief-of-staff` role for one business. You run the\n' +
|
||||
'organization. You hire and terminate role instances, you own the\n' +
|
||||
"organization's structure and you are the only role that launches\n" +
|
||||
'sessions. You take work from the assistant and assign it through the\n' +
|
||||
"roles that do it. You never talk to the user, but you are the main point of interaction. You don't write the\n" +
|
||||
"product's code, you don't review it and you don't create tasks yourself.\n" +
|
||||
'\n' +
|
||||
'## Duties\n' +
|
||||
'\n' +
|
||||
'- Take the work the assistant passes you. Send it to the role that does\n' +
|
||||
' it, addressed by role, in the words the assistant gave you. The `pm`\n' +
|
||||
' role turns product work into tasks and decides who holds them and when\n' +
|
||||
' they run.\n' +
|
||||
'- Launch role sessions with the `launch` tool, for the instances and\n' +
|
||||
" within the limits the business file's launch block lists. A launch\n" +
|
||||
' outside them is refused, not queued. Launch only role instances.\n' +
|
||||
"- Keep the organization's structure: which role instances exist, who\n" +
|
||||
' holds them and what they may do. To terminate a role instance, raise a\n' +
|
||||
' `role.revoke` decision, naming the instance and saying why. To hire one\n' +
|
||||
' or change the structure, raise a `policy.change` decision until the\n' +
|
||||
' broker gives you a verb for the organization file.\n' +
|
||||
'- Report to the assistant what the roles answer, and every refusal with\n' +
|
||||
' its exact text.\n' +
|
||||
'\n' +
|
||||
'## Authority\n' +
|
||||
'\n' +
|
||||
'Your role file lists what you do on your own: sending messages and\n' +
|
||||
"launching role sessions. Anything the list doesn't name is gated. That\n" +
|
||||
'includes creating or assigning tasks, pushing to a repository, sending\n' +
|
||||
'messages outside the business, minting credentials, and any change to\n' +
|
||||
'policy or to a PRD. When an action is gated, raise a decision. It\n' +
|
||||
'reaches the human through the inbox, not through you. Never route around\n' +
|
||||
'a refusal.\n' +
|
||||
'\n' +
|
||||
'You hold no human authority. Never resolve a decision for the human,\n' +
|
||||
'never approve a request in their name, and never write words as if they\n' +
|
||||
'had said them.\n' +
|
||||
'\n' +
|
||||
'Only the human stops a run, with `mosaic stop`. If you think a run should\n' +
|
||||
'stop, raise a `role.revoke` decision with `blocking` false and the role\n' +
|
||||
'instance as target, naming the run and saying why.\n' +
|
||||
'\n' +
|
||||
'## Protocol\n' +
|
||||
'\n' +
|
||||
'- You act only through the typed tools the broker gives you. Your tools\n' +
|
||||
" are read, grep, find and ls, plus the broker's launch and message\n" +
|
||||
' tools. You have no write tool, and you never hold a token or a\n' +
|
||||
' credential.\n' +
|
||||
'- Each turn opens with a "Current state" block, read when the turn\n' +
|
||||
' started. It is the truth for launch state and task status. A message\n' +
|
||||
' or a note of yours that disagrees with it is out of date.\n' +
|
||||
'- Send messages through the bus, addressed to a role, not a person.\n' +
|
||||
'- Report a blocker as soon as you find it, with what you tried.\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:134: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: '# Role contract: chief of staff (chief-of-staff)\n\nYou hold the `chief-of-staff` role for one business. You run the\norganization. You hire and terminate role instances, you own the\norganization\'s structure and you are the only role that launches\nsessions. You take work from the assistant and assign it through the\nroles that do it. You never talk to the user, but you are the main point of interaction. You don\'t write the\nproduct\'s code, you don\'t review it and you don\'t create tasks yourself.\n\n## Duties\n\n- Take the work the assistant passes you. Send it to the role that does\n it, addressed by role, in the words the assistant gave you. The `pm`\n role turns product work into tasks and decides who holds them and when\n they run.\n- Launch role sessions with the `launch` tool, for the instances and\n within the limits the business file\'s launch block lists. A launch\n outside them is refused, not queued. Launch only role instances.\n- Keep the organization\'s structure: which role instances exist, who\n holds them and what they may do. To terminate a role instance, raise a\n `role.revoke` decision, naming the instance and saying why. To hire one\n or change the structure, raise a `policy.change` decision until the\n broker gives you a verb for the organization file.\n- Report to the assistant what the roles answer, and every refusal with\n its exact text.\n\n## Authority\n\nYour role file lists what you do on your own: sending messages and\nlaunching role sessions. Anything the list doesn\'t name is gated. That\nincludes creating or assigning tasks, pushing to a repository, sending\nmessages outside the business, minting credentials, and any change to\npolicy or to a PRD. When an action is gated, raise a decision. It\nreaches the human through the inbox, not through you. Never route around\na refusal.\n\nYou hold no human authority. Never resolve a decision for the human,\nnever approve a request in their name, and never write words as if they\nhad said them.\n\nOnly the human stops a run, with `mosaic stop`. If you think a run should\nstop, raise a `role.revoke` decision with `blocking` false and the role\ninstance as target, naming the run and saying why.\n\n## Protocol\n\n- You act only through the typed tools the broker gives you. Your tools\n are read, grep, find and ls, plus the broker\'s launch and message\n tools. You have no write tool, and you never hold a token or a\n credential.\n- Each turn opens with a "Current state" block, read when the turn\n started. It is the truth for launch state and task status. A message\n or a note of yours that disagrees with it is out of date.\n- Send messages through the bus, addressed to a role, not a person.\n- Report a blocker as soon as you find it, with what you tried.\n',
|
||||
expected: /main (agent|point of interaction)/i,
|
||||
operator: 'doesNotMatch',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.md 2026-10-14 19:38:55.299379607 -0500
|
||||
+++ roles/chief-of-staff.md 2026-10-14 19:38:55.317651008 -0500
|
||||
@@ -4,7 +4,7 @@
|
||||
organization. You hire and terminate role instances, you own the
|
||||
organization's structure and you are the only role that launches
|
||||
sessions. You take work from the assistant and assign it through the
|
||||
-roles that do it. You never talk to the user. You don't write the
|
||||
+roles that do it. You never talk to the user, but you are the main point of interaction. You don't write the
|
||||
product's code, you don't review it and you don't create tasks yourself.
|
||||
|
||||
## Duties
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,81 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.432026ms)
|
||||
✔ the shipped file is exactly the approved list (0.56122ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.294502ms)
|
||||
✔ a business grant through limits does not widen the role (1.228737ms)
|
||||
✔ a launch block whose by is the assistant is refused (1.286177ms)
|
||||
✔ the instance takes no credential references and no tracker (1.745753ms)
|
||||
✖ the contract passes work to the chief of staff and directs no one (1.195231ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 67.789806
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:110:1
|
||||
✖ the contract passes work to the chief of staff and directs no one (1.195231ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /don't direct\s+other agents/. Input:
|
||||
|
||||
'# Role contract: assistant (assistant)\n' +
|
||||
'\n' +
|
||||
'You hold the `assistant` role for one user in one business. You are the\n' +
|
||||
"user's main agent. You talk with the user, and you pass the work the\n" +
|
||||
'user wants done for the business to the chief of staff. You direct\n' +
|
||||
"other agents, you don't create or assign tasks and you don't launch\n" +
|
||||
'sessions.\n' +
|
||||
'\n' +
|
||||
'## Duties\n' +
|
||||
'\n' +
|
||||
"- Talk with the user. Answer what they ask, say plainly what you don't\n" +
|
||||
' know and keep their requests in their own words.\n' +
|
||||
'- Send each request for the business to the chief of staff as a message,\n' +
|
||||
" addressed to the `chief-of-staff` role. Keep the user's words as they\n" +
|
||||
' gave them, and name the request each message carries.\n' +
|
||||
'- Relay each ruling the user gives verbatim to the role it concerns.\n' +
|
||||
" Don't summarize it, paraphrase it or add to it. Say whose ruling it is.\n" +
|
||||
'- Report to the user what the chief of staff answers, and every refusal\n' +
|
||||
' with its exact text.\n' +
|
||||
'\n' +
|
||||
'## Authority\n' +
|
||||
'\n' +
|
||||
'Your role file lists what you do on your own: sending messages. Anything\n' +
|
||||
"the list doesn't name is gated. That includes creating or assigning\n" +
|
||||
'tasks, directing another role, launching a role session, pushing to a\n' +
|
||||
'repository, sending messages outside the business, minting credentials,\n' +
|
||||
'and any change to policy or to a PRD. When an action is gated, tell the\n' +
|
||||
'user and wait for their answer. Never route around a refusal.\n' +
|
||||
'\n' +
|
||||
'You hold no human authority. Never resolve a decision for the user, never\n' +
|
||||
'approve a request in their name, and never write words as if they had said\n' +
|
||||
'them. When a question needs their decision, pass it on as their question\n' +
|
||||
'and wait for their answer.\n' +
|
||||
'\n' +
|
||||
'Only the human stops a run, with `mosaic stop`. If you think a run should\n' +
|
||||
"stop, say so to the user. Don't stop it yourself.\n" +
|
||||
'\n' +
|
||||
'## Protocol\n' +
|
||||
'\n' +
|
||||
'- You act only through the typed tools the broker gives you. Your tools\n' +
|
||||
' are read, grep, find and ls. You have no write tool, and you never hold\n' +
|
||||
' a token or a credential.\n' +
|
||||
'- Send messages through the bus, addressed to a role, not a person.\n' +
|
||||
'- Report a blocker as soon as you find it, with what you tried.\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:113: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: "# Role contract: assistant (assistant)\n\nYou hold the `assistant` role for one user in one business. You are the\nuser's main agent. You talk with the user, and you pass the work the\nuser wants done for the business to the chief of staff. You direct\nother agents, you don't create or assign tasks and you don't launch\nsessions.\n\n## Duties\n\n- Talk with the user. Answer what they ask, say plainly what you don't\n know and keep their requests in their own words.\n- Send each request for the business to the chief of staff as a message,\n addressed to the `chief-of-staff` role. Keep the user's words as they\n gave them, and name the request each message carries.\n- Relay each ruling the user gives verbatim to the role it concerns.\n Don't summarize it, paraphrase it or add to it. Say whose ruling it is.\n- Report to the user what the chief of staff answers, and every refusal\n with its exact text.\n\n## Authority\n\nYour role file lists what you do on your own: sending messages. Anything\nthe list doesn't name is gated. That includes creating or assigning\ntasks, directing another role, launching a role session, pushing to a\nrepository, sending messages outside the business, minting credentials,\nand any change to policy or to a PRD. When an action is gated, tell the\nuser and wait for their answer. Never route around a refusal.\n\nYou hold no human authority. Never resolve a decision for the user, never\napprove a request in their name, and never write words as if they had said\nthem. When a question needs their decision, pass it on as their question\nand wait for their answer.\n\nOnly the human stops a run, with `mosaic stop`. If you think a run should\nstop, say so to the user. Don't stop it yourself.\n\n## Protocol\n\n- You act only through the typed tools the broker gives you. Your tools\n are read, grep, find and ls. You have no write tool, and you never hold\n a token or a credential.\n- Send messages through the bus, addressed to a role, not a person.\n- Report a blocker as soon as you find it, with what you tried.\n",
|
||||
expected: /don't direct\s+other agents/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.md 2026-10-14 19:38:55.430709446 -0500
|
||||
+++ roles/assistant.md 2026-10-14 19:38:55.446652265 -0500
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
You hold the `assistant` role for one user in one business. You are the
|
||||
user's main agent. You talk with the user, and you pass the work the
|
||||
-user wants done for the business to the chief of staff. You don't direct
|
||||
+user wants done for the business to the chief of staff. You direct
|
||||
other agents, you don't create or assign tasks and you don't launch
|
||||
sessions.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,39 @@
|
||||
✔ the four shipped version 2 roles load (2.306789ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.683941ms)
|
||||
✔ shipped authority follows the note's table (0.426842ms)
|
||||
✖ every role file in roles/ loads through the validator, and a v2 contract exists (0.315695ms)
|
||||
✔ version 1 files keep loading with no authority (0.743232ms)
|
||||
✔ the conductor policy isn't a role (0.138346ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.29439ms)
|
||||
✔ version 2 refusals (1.066519ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (1.621213ms)
|
||||
✔ credentials: Gitea scopes (0.738868ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.8268ms)
|
||||
✔ credentials: services (0.518187ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.523636ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 63.474692
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/role.test.mjs:74:1
|
||||
✖ every role file in roles/ loads through the validator, and a v2 contract exists (0.315695ms)
|
||||
Error [BusinessError]: role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkContract (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:98:5)
|
||||
at validateRoleDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:130:19)
|
||||
at loadRoleFile (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:139:10)
|
||||
at loadRole (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:144:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/role.test.mjs:79:18)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:55.569653464 -0500
|
||||
@@ -2,7 +2,7 @@
|
||||
"roleVersion": 2,
|
||||
"name": "assistant",
|
||||
"title": "Assistant",
|
||||
- "contract": "assistant.md",
|
||||
+ "contract": "missing.md",
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,148 @@
|
||||
✖ the role file loads and resolves through loadBusiness (1.037047ms)
|
||||
✖ the shipped file is exactly the approved list (1.42952ms)
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.251584ms)
|
||||
✖ a business grant through limits does not widen the role (2.606393ms)
|
||||
✖ a launch block whose by is the assistant is refused (1.499936ms)
|
||||
✖ the instance takes no credential references and no tracker (1.129709ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.304019ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 65.793163
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:43:1
|
||||
✖ the role file loads and resolves through loadBusiness (1.037047ms)
|
||||
Error [BusinessError]: role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkContract (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:98:5)
|
||||
at validateRoleDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:130:19)
|
||||
at loadRoleFile (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:139:10)
|
||||
at loadRole (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:144:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:44:16)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:58:1
|
||||
✖ the shipped file is exactly the approved list (1.42952ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send'
|
||||
]
|
||||
},
|
||||
+ contract: 'missing.md',
|
||||
- contract: 'assistant.md',
|
||||
credentials: [],
|
||||
name: 'assistant',
|
||||
network: 'api-only',
|
||||
roleVersion: 2,
|
||||
tools: [
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:62:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'assistant', contract: 'missing.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:65:1
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.251584ms)
|
||||
Error [BusinessError]: role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkContract (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:98:5)
|
||||
at validateRoleDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:130:19)
|
||||
at loadRoleFile (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:139:10)
|
||||
at loadRole (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:144:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:66:16)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:78:1
|
||||
✖ a business grant through limits does not widen the role (2.606393ms)
|
||||
Error [BusinessError]: role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkContract (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:98:5)
|
||||
at validateRoleDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:130:19)
|
||||
at loadRoleFile (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:139:10)
|
||||
at loadRole (file:///mnt/storage/scratch/researcher/q119/packages/business/src/role.mjs:144:10)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:88:103)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:36:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:79:27) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:86:1
|
||||
✖ a launch block whose by is the assistant is refused (1.499936ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/. Input:
|
||||
|
||||
'role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md'
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:25:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:87:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md',
|
||||
expected: /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:95:1
|
||||
✖ the instance takes no credential references and no tracker (1.129709ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /must reference exactly the services its role definition needs \(none; got gitea\)/. Input:
|
||||
|
||||
'role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md'
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:25:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:96:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'role contract not found: /mnt/storage/scratch/researcher/q119/roles/missing.md',
|
||||
expected: /must reference exactly the services its role definition needs \(none; got gitea\)/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:55.684654585 -0500
|
||||
@@ -2,7 +2,7 @@
|
||||
"roleVersion": 2,
|
||||
"name": "assistant",
|
||||
"title": "Assistant",
|
||||
- "contract": "assistant.md",
|
||||
+ "contract": "missing.md",
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,148 @@
|
||||
✖ the role file loads and resolves through loadBusiness (3.670536ms)
|
||||
✖ the shipped file is exactly the approved list (1.371759ms)
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.059217ms)
|
||||
✖ the chief of staff holds role.launch and message.send; every other action is gated (0.883108ms)
|
||||
✖ the pm does not hold role.launch (0.885667ms)
|
||||
✖ a business grant of a gated action through limits does not widen the role (0.884522ms)
|
||||
✖ a limit that drops role.launch leaves the chief of staff with no launch block (0.783143ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.433136ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.267324ms)
|
||||
✔ the instance takes no credential references and no tracker (1.501525ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 7
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 68.041796
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:49:1
|
||||
✖ the role file loads and resolves through loadBusiness (3.670536ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-cByCSP/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:50:19)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:64:1
|
||||
✖ the shipped file is exactly the approved list (1.371759ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
- 'role.launch'
|
||||
]
|
||||
},
|
||||
contract: 'chief-of-staff.md',
|
||||
credentials: [],
|
||||
name: 'chief-of-staff',
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:68:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:76:1
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.059217ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-DiPCQn/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:77:27)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:86:1
|
||||
✖ the chief of staff holds role.launch and message.send; every other action is gated (0.883108ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-zF1eCK/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:87:27)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:94:1
|
||||
✖ the pm does not hold role.launch (0.885667ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-R6vM7m/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:98:27)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:103:1
|
||||
✖ a business grant of a gated action through limits does not widen the role (0.884522ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-kTeO8Q/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:106:19)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:115:1
|
||||
✖ a limit that drops role.launch leaves the chief of staff with no launch block (0.783143ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-fnbpH4/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:116:27)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:37:48.998010465 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,182 @@
|
||||
✖ the PM gets its task verbs and the reads, and no launch (4.382949ms)
|
||||
✖ the chief of staff gets launch and send_message, and no task verbs (1.266134ms)
|
||||
✖ the assistant gets send_message and the reads, no launch (1.053654ms)
|
||||
✖ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.401073ms)
|
||||
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.926067ms)
|
||||
✖ a coder with a tracker gets its own task tools and no task_reassign (0.806781ms)
|
||||
✖ launch only when the business's launch block names the instance as launcher (0.898211ms)
|
||||
✖ an action outside the instance's authority has no tool (0.867373ms)
|
||||
✖ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (1.140094ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (9.819222ms)
|
||||
✖ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.076664ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.101431ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.587872ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 10
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 96.997532
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:9:1
|
||||
✖ the PM gets its task verbs and the reads, and no launch (4.382949ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-y9yIFF/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:10:14)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:33:1
|
||||
✖ the chief of staff gets launch and send_message, and no task verbs (1.266134ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-yIZLzB/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:34:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:45:1
|
||||
✖ the assistant gets send_message and the reads, no launch (1.053654ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-SjmFtj/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:46:21)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:54:1
|
||||
✖ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.401073ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-qS5Nju/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:55:14)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:79:1
|
||||
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.926067ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-lsaGWh/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:80:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:88:1
|
||||
✖ a coder with a tracker gets its own task tools and no task_reassign (0.806781ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-F8wB7E/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:89:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:96:1
|
||||
✖ launch only when the business's launch block names the instance as launcher (0.898211ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-aMv7wR/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:97:42)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:103:1
|
||||
✖ an action outside the instance's authority has no tool (0.867373ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-tvVkh6/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:104:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:109:1
|
||||
✖ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (1.140094ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-7qZj07/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:110:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/tools.test.mjs:162:1
|
||||
✖ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.076664ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-C9Rcjc/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/tools.test.mjs:163:40)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:37:49.125011680 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,177 @@
|
||||
✖ sessionModel: agent vars win, then the system's execution settings (4.43866ms)
|
||||
✖ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (1.267473ms)
|
||||
✖ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (1.04923ms)
|
||||
✖ a claude-code bundle adds the wrapped gate hook and the MCP config (0.978591ms)
|
||||
✖ the prompt's built-in tools line is the harness's own names, as the manifest lists them (1.576487ms)
|
||||
✖ the prompt names the project clones in the workspace, and none when there are none (0.947698ms)
|
||||
✖ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (1.138803ms)
|
||||
✖ a bundle is written once: an existing file refuses (1.901477ms)
|
||||
✖ a path with a single quote can't go into the hook command (0.966374ms)
|
||||
ℹ tests 9
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 9
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 103.822342
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:30:1
|
||||
✖ sessionModel: agent vars win, then the system's execution settings (4.43866ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-PlA1i5/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:31:33)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:37:1
|
||||
✖ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (1.267473ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-9wIc98/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:38:22)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:74:1
|
||||
✖ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (1.04923ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-WxVxsV/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:75:13)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:84:1
|
||||
✖ a claude-code bundle adds the wrapped gate hook and the MCP config (0.978591ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-99QjiB/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:85:13)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:105:1
|
||||
✖ the prompt's built-in tools line is the harness's own names, as the manifest lists them (1.576487ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-5725J7/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:107:23)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:121:1
|
||||
✖ the prompt names the project clones in the workspace, and none when there are none (0.947698ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-zFj6Ol/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:123:26)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:142:1
|
||||
✖ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (1.138803ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-B1PbAF/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:146:32)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:158:1
|
||||
✖ a bundle is written once: an existing file refuses (1.901477ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /EEXIST/. Input:
|
||||
|
||||
"BusinessError: /mnt/storage/scratch/tmp/mosaic-harness-biz-5e9zr0/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role"
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:162: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: BusinessError: /mnt/storage/scratch/tmp/mosaic-harness-biz-5e9zr0/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:164:15
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:162:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25),
|
||||
expected: /EEXIST/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/harness/tests/bundle.test.mjs:171:1
|
||||
✖ a path with a single quote can't go into the hook command (0.966374ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-harness-biz-wGkKKD/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at resolvedFor (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/helpers.mjs:27:20)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/harness/tests/bundle.test.mjs:172:13)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:37:49.278013144 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,295 @@
|
||||
✖ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (45.309498ms)
|
||||
✖ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (36.210493ms)
|
||||
✖ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (36.660573ms)
|
||||
✖ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (38.671542ms)
|
||||
✖ a runner that stops at once ends its launch with the runner's reason (41.1482ms)
|
||||
✖ a Claude Code launch with no session credential refuses before it starts (39.618582ms)
|
||||
✖ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (40.819704ms)
|
||||
✖ a runner killed from the host ends its launch as killed, not failed (37.559931ms)
|
||||
✖ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (36.587442ms)
|
||||
✖ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (44.044436ms)
|
||||
file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44
|
||||
if (error instanceof BusinessError) throw new CliError(error.message, 3);
|
||||
^
|
||||
|
||||
CliError: /mnt/storage/scratch/tmp/mosaic-launch-oNauXo/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/fixtures/launch-host.mjs:12:14
|
||||
at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
|
||||
at async node:internal/modules/esm/loader:650:26
|
||||
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (30001.8402ms)
|
||||
file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44
|
||||
if (error instanceof BusinessError) throw new CliError(error.message, 3);
|
||||
^
|
||||
|
||||
CliError: /mnt/storage/scratch/tmp/mosaic-launch-8nenoQ/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/fixtures/launch-host.mjs:12:14
|
||||
at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
|
||||
at async node:internal/modules/esm/loader:650:26
|
||||
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (30001.592457ms)
|
||||
✖ a malformed sessions.json refuses the host start with exit 3 and stays as it was (38.394346ms)
|
||||
✖ an over-long launch request is refused at once, not at the 10 s idle timeout (35.00358ms)
|
||||
✖ a launch client that never closes its side doesn't hold the host's close (35.966066ms)
|
||||
✖ a runner that ignores SIGTERM is killed when the host closes (35.502462ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.616447ms)
|
||||
ℹ tests 17
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 14
|
||||
ℹ cancelled 2
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 60648.387817
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:132:1
|
||||
✖ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (45.309498ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-NqiIKY/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:133:51)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:205:1
|
||||
✖ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (36.210493ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-9WQTrB/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:206:46)
|
||||
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) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:287:1
|
||||
✖ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (36.660573ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-HJIdem/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:296:23)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:342:1
|
||||
✖ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (38.671542ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-YbUB4r/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:345:39)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:361:1
|
||||
✖ a runner that stops at once ends its launch with the runner's reason (41.1482ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-8kjKdu/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:365:39)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:381:1
|
||||
✖ a Claude Code launch with no session credential refuses before it starts (39.618582ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-NbLIE2/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:388:33)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:396:1
|
||||
✖ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (40.819704ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-xDB3Jc/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:400:33)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:409:1
|
||||
✖ a runner killed from the host ends its launch as killed, not failed (37.559931ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-lzhFbi/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:410:33)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:421:1
|
||||
✖ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (36.587442ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-t6rZ5G/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:425:38)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:443:1
|
||||
✖ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (44.044436ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-WRZWBf/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:460:41)
|
||||
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) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:502:3
|
||||
✖ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (30001.8402ms)
|
||||
'test timed out after 30000ms'
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:502:3
|
||||
✖ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (30001.592457ms)
|
||||
'test timed out after 30000ms'
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:563:1
|
||||
✖ a malformed sessions.json refuses the host start with exit 3 and stays as it was (38.394346ms)
|
||||
AssertionError [ERR_ASSERTION]: The validation function is expected to return "true". Received false
|
||||
|
||||
Caught error:
|
||||
|
||||
CliError: /mnt/storage/scratch/tmp/mosaic-launch-BYt0UB/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:568:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: CliError: /mnt/storage/scratch/tmp/mosaic-launch-BYt0UB/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:568:24)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:575:1
|
||||
✖ an over-long launch request is refused at once, not at the 10 s idle timeout (35.00358ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-O1uhwT/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:576:23)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:586:1
|
||||
✖ a launch client that never closes its side doesn't hold the host's close (35.966066ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-YIbNMC/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:587:30)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
|
||||
test at packages/cli/tests/launcher.test.mjs:618:1
|
||||
✖ a runner that ignores SIGTERM is killed when the host closes (35.502462ms)
|
||||
Error [CliError]: /mnt/storage/scratch/tmp/mosaic-launch-bBlMBO/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at business (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:44:47)
|
||||
at bootConfig (file:///mnt/storage/scratch/researcher/q119/packages/cli/src/config.mjs:89:10)
|
||||
at setup (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:83:16)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/cli/tests/launcher.test.mjs:619:40)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 3
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:37:49.442014713 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,38 @@
|
||||
✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.169264ms)
|
||||
✔ credential state from the date alone, as the bus states it (0.132024ms)
|
||||
✔ queue: rows, one row, ids and methods, notes; no path or id from a row (328.564414ms)
|
||||
✔ queue: a refused read fails closed with the store's text, redacted (176.45743ms)
|
||||
✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (721.727278ms)
|
||||
✖ business: names, vars on the allowlist, authority, credential metadata only (6.583273ms)
|
||||
✔ business: missing or invalid file refuses with the module's text, redacted (7.442982ms)
|
||||
✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.671542ms)
|
||||
✔ settings: release, board, loopback address, notifier binding name only (96.837466ms)
|
||||
✔ task fields: the committed table with no reads configured, GET only; a bad table refuses with no path (17.052555ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1453.546523
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/reads.test.mjs:110:1
|
||||
✖ business: names, vars on the allowlist, authority, credential metadata only (6.583273ms)
|
||||
AssertionError [ERR_ASSERTION]: {"error":"not-configured","message":"<config>/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role"}
|
||||
|
||||
503 !== 200
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/webui/tests/reads.test.mjs:114: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: 503,
|
||||
expected: 200,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:38:50.150600677 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,185 @@
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (1.15966ms)
|
||||
✖ the fixture business validates and comes back frozen (3.021594ms)
|
||||
✖ two instances may share a definition (0.997641ms)
|
||||
✔ top-level refusals (2.845587ms)
|
||||
✔ arbiters and projects (4.416049ms)
|
||||
✔ role instances (2.236345ms)
|
||||
✖ Vikunja bots (5.106753ms)
|
||||
✖ a role without Vikunja takes no tracker block (1.785771ms)
|
||||
✔ credential references match the definition's services (2.052986ms)
|
||||
✖ launch (2.433062ms)
|
||||
✖ loadBusiness: file checks (0.94924ms)
|
||||
✔ loadBusiness: not a regular file (41.109894ms)
|
||||
✖ loading writes nothing (1.175058ms)
|
||||
✖ names that are Object.prototype properties don't count as declared (1.650878ms)
|
||||
✖ the shipped example refuses as written and validates once filled in (0.615889ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 9
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 130.530315
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/business.test.mjs:34:1
|
||||
✖ the fixture business validates and comes back frozen (3.021594ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-SGtMTn/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at check (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:24:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:35:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:47:1
|
||||
✖ two instances may share a definition (0.997641ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-bFCbwt/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at check (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:24:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:48:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:86:1
|
||||
✖ Vikunja bots (5.106753ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-C5f9Y3/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at check (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:24:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:97:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:100:1
|
||||
✖ a role without Vikunja takes no tracker block (1.785771ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-97BKK6/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at check (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:24:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:108:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:120:1
|
||||
✖ launch (2.433062ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /must not be empty/. Input:
|
||||
|
||||
"/mnt/storage/scratch/tmp/mosaic-business-9Oz09c/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role"
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:14:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:11:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:124:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: "/mnt/storage/scratch/tmp/mosaic-business-9Oz09c/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role",
|
||||
expected: /must not be empty/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:137:1
|
||||
✖ loadBusiness: file checks (0.94924ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-AxCrbO/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:143:16)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:183:1
|
||||
✖ loading writes nothing (1.175058ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-gWuGIV/config/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:189:3)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:195:1
|
||||
✖ names that are Object.prototype properties don't count as declared (1.650878ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /instances names constructor/. Input:
|
||||
|
||||
"/mnt/storage/scratch/tmp/mosaic-business-xvV1Ya/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role"
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:14:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:11:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:198:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: "/mnt/storage/scratch/tmp/mosaic-business-xvV1Ya/businesses/acme.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role",
|
||||
expected: /instances names constructor/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/business.test.mjs:206:1
|
||||
✖ the shipped example refuses as written and validates once filled in (0.615889ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-xscwzZ/businesses/mosaic-stack.json launch.by names chief, whose role chief-of-staff doesn't hold role.launch within-role
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkLaunch (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:122:5)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:186:57)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:216:20)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:38:51.658615359 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send", "role.launch"],
|
||||
+ "withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,59 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.987588ms)
|
||||
✔ the shipped file is exactly the approved list (0.188358ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.319104ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.018319ms)
|
||||
✖ the pm does not hold role.launch (3.110803ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.598655ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.0075ms)
|
||||
✖ a launch block whose by is the pm instance is refused (0.940857ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.311021ms)
|
||||
✔ the instance takes no credential references and no tracker (1.903027ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 8
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 72.590097
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:94:1
|
||||
✖ the pm does not hold role.launch (3.110803ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(!role.authority.withinRole.includes("role.launch"))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:96: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: false,
|
||||
expected: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:123:1
|
||||
✖ a launch block whose by is the pm instance is refused (0.940857ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:27:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:124:3)
|
||||
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,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.json 2026-10-14 19:38:51.832481906 -0500
|
||||
+++ roles/pm.json 2026-10-14 19:38:51.853617258 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "write", "edit", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send"],
|
||||
+ "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send", "role.launch"],
|
||||
"crossRole": ["task.priority.change", "task.scope.change"]
|
||||
},
|
||||
"credentials": [
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,44 @@
|
||||
✔ the four shipped version 2 roles load (2.346797ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.818105ms)
|
||||
✖ shipped authority follows the note's table (3.357317ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (0.577286ms)
|
||||
✔ version 1 files keep loading with no authority (0.829688ms)
|
||||
✔ the conductor policy isn't a role (0.165409ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.382945ms)
|
||||
✔ version 2 refusals (0.995054ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (2.081947ms)
|
||||
✔ credentials: Gitea scopes (0.7104ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.73513ms)
|
||||
✔ credentials: services (0.392153ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.478367ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 73.842102
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/role.test.mjs:61:1
|
||||
✖ shipped authority follows the note's table (3.357317ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(!auth("pm").withinRole.includes("role.launch"))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/role.test.mjs:69: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: false,
|
||||
expected: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.json 2026-10-14 19:38:51.832481906 -0500
|
||||
+++ roles/pm.json 2026-10-14 19:38:51.982618514 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "write", "edit", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send"],
|
||||
+ "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send", "role.launch"],
|
||||
"crossRole": ["task.priority.change", "task.scope.change"]
|
||||
},
|
||||
"credentials": [
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,21 @@
|
||||
✔ the PM gets its task verbs and the reads, and no launch (5.585509ms)
|
||||
✔ the chief of staff gets launch and send_message, and no task verbs (1.845498ms)
|
||||
✔ the assistant gets send_message and the reads, no launch (1.886441ms)
|
||||
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (2.590532ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (1.161465ms)
|
||||
✔ a coder with a tracker gets its own task tools and no task_reassign (1.032107ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (1.797537ms)
|
||||
✔ an action outside the instance's authority has no tool (1.284862ms)
|
||||
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (3.060751ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (7.450533ms)
|
||||
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (2.396108ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.327551ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.789313ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 108.249113
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.json 2026-10-14 19:38:51.832481906 -0500
|
||||
+++ roles/pm.json 2026-10-14 19:38:52.112619781 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "write", "edit", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send"],
|
||||
+ "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send", "role.launch"],
|
||||
"crossRole": ["task.priority.change", "task.scope.change"]
|
||||
},
|
||||
"credentials": [
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,17 @@
|
||||
✔ sessionModel: agent vars win, then the system's execution settings (8.031624ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (4.125049ms)
|
||||
✔ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (1.880694ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (2.024655ms)
|
||||
✔ the prompt's built-in tools line is the harness's own names, as the manifest lists them (6.023881ms)
|
||||
✔ the prompt names the project clones in the workspace, and none when there are none (3.810268ms)
|
||||
✔ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (5.309296ms)
|
||||
✔ a bundle is written once: an existing file refuses (1.284356ms)
|
||||
✔ a path with a single quote can't go into the hook command (1.360446ms)
|
||||
ℹ tests 9
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 108.254741
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.json 2026-10-14 19:38:51.832481906 -0500
|
||||
+++ roles/pm.json 2026-10-14 19:38:52.272621339 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "write", "edit", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send"],
|
||||
+ "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send", "role.launch"],
|
||||
"crossRole": ["task.priority.change", "task.scope.change"]
|
||||
},
|
||||
"credentials": [
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,18 @@
|
||||
✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.251887ms)
|
||||
✔ credential state from the date alone, as the bus states it (0.151212ms)
|
||||
✔ queue: rows, one row, ids and methods, notes; no path or id from a row (341.049792ms)
|
||||
✔ queue: a refused read fails closed with the store's text, redacted (177.714544ms)
|
||||
✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (722.511795ms)
|
||||
✔ business: names, vars on the allowlist, authority, credential metadata only (8.519948ms)
|
||||
✔ business: missing or invalid file refuses with the module's text, redacted (6.973752ms)
|
||||
✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.121819ms)
|
||||
✔ settings: release, board, loopback address, notifier binding name only (98.140244ms)
|
||||
✔ task fields: the committed table with no reads configured, GET only; a bad table refuses with no path (18.178798ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 10
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1475.198626
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/pm.json 2026-10-14 19:38:51.832481906 -0500
|
||||
+++ roles/pm.json 2026-10-14 19:38:52.439622966 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "write", "edit", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send"],
|
||||
+ "withinRole": ["task.create", "task.assign", "task.reassign", "task.schedule", "task.update.assigned", "task.close", "message.send", "role.launch"],
|
||||
"crossRole": ["task.priority.change", "task.scope.change"]
|
||||
},
|
||||
"credentials": [
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,95 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.488033ms)
|
||||
✖ the shipped file is exactly the approved list (1.540344ms)
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.383942ms)
|
||||
✔ a business grant through limits does not widen the role (1.332572ms)
|
||||
✖ a launch block whose by is the assistant is refused (1.206276ms)
|
||||
✔ the instance takes no credential references and no tracker (1.933985ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.259623ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 66.867584
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:58:1
|
||||
✖ the shipped file is exactly the approved list (1.540344ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
+ 'role.launch'
|
||||
]
|
||||
},
|
||||
contract: 'assistant.md',
|
||||
credentials: [],
|
||||
name: 'assistant',
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:62:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:65:1
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.383942ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
+ 'role.launch'
|
||||
]
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:67: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: { withinRole: [ 'message.send', 'role.launch' ], crossRole: [] },
|
||||
expected: { withinRole: [ 'message.send' ], crossRole: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:86:1
|
||||
✖ a launch block whose by is the assistant is refused (1.206276ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:87:3)
|
||||
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,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:53.970637880 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
"tools": ["read", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
- "withinRole": ["message.send"],
|
||||
+ "withinRole": ["message.send", "role.launch"],
|
||||
"crossRole": []
|
||||
},
|
||||
"credentials": []
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,52 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.391607ms)
|
||||
✖ the shipped file is exactly the approved list (1.397263ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.244289ms)
|
||||
✔ a business grant through limits does not widen the role (1.087683ms)
|
||||
✔ a launch block whose by is the assistant is refused (1.178885ms)
|
||||
✔ the instance takes no credential references and no tracker (1.55519ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.472435ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 64.964949
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:58:1
|
||||
✖ the shipped file is exactly the approved list (1.397263ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send'
|
||||
...
|
||||
'read',
|
||||
+ 'write',
|
||||
'grep',
|
||||
'find',
|
||||
'ls'
|
||||
]
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:62:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'write', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:54.088639030 -0500
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "assistant",
|
||||
"title": "Assistant",
|
||||
"contract": "assistant.md",
|
||||
- "tools": ["read", "grep", "find", "ls"],
|
||||
+ "tools": ["read", "write", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
"withinRole": ["message.send"],
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,79 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.742996ms)
|
||||
✖ the shipped file is exactly the approved list (1.709794ms)
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.401873ms)
|
||||
✔ a business grant through limits does not widen the role (1.65882ms)
|
||||
✔ a launch block whose by is the assistant is refused (1.574074ms)
|
||||
✔ the instance takes no credential references and no tracker (1.784691ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.23497ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 69.703441
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:58:1
|
||||
✖ the shipped file is exactly the approved list (1.709794ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
authority: {
|
||||
+ crossRole: [
|
||||
+ 'task.priority.change'
|
||||
+ ],
|
||||
- crossRole: [],
|
||||
withinRole: [
|
||||
'message.send'
|
||||
]
|
||||
},
|
||||
contract: 'assistant.md',
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:62:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [Array] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:65:1
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.401873ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ crossRole: [
|
||||
+ 'task.priority.change'
|
||||
+ ],
|
||||
- crossRole: [],
|
||||
withinRole: [
|
||||
'message.send'
|
||||
]
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:67: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: { withinRole: [ 'message.send' ], crossRole: [ 'task.priority.change' ] },
|
||||
expected: { withinRole: [ 'message.send' ], crossRole: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:54.215640267 -0500
|
||||
@@ -7,7 +7,7 @@
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
"withinRole": ["message.send"],
|
||||
- "crossRole": []
|
||||
+ "crossRole": ["task.priority.change"]
|
||||
},
|
||||
"credentials": []
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,164 @@
|
||||
✖ the role file loads and resolves through loadBusiness (4.048055ms)
|
||||
✖ the shipped file is exactly the approved list (1.434875ms)
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.409068ms)
|
||||
✖ a business grant through limits does not widen the role (1.08749ms)
|
||||
✖ a launch block whose by is the assistant is refused (1.342017ms)
|
||||
✖ the instance takes no credential references and no tracker (1.123246ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.271162ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 64.401603
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:43:1
|
||||
✖ the role file loads and resolves through loadBusiness (4.048055ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-t1VgIV/businesses/acme.json roles.assistant.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:36:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:50:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:58:1
|
||||
✖ the shipped file is exactly the approved list (1.434875ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send'
|
||||
...
|
||||
contract: 'assistant.md',
|
||||
+ credentials: [
|
||||
+ {
|
||||
+ scopes: [
|
||||
+ 'read:user'
|
||||
+ ],
|
||||
+ service: 'gitea'
|
||||
+ }
|
||||
+ ],
|
||||
- credentials: [],
|
||||
name: 'assistant',
|
||||
network: 'api-only',
|
||||
roleVersion: 2,
|
||||
tools: [
|
||||
'read',
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:62:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [ [Object] ] },
|
||||
expected: { roleVersion: 2, name: 'assistant', contract: 'assistant.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:65:1
|
||||
✖ the assistant's authority is message.send within role and nothing else (0.409068ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
+ [
|
||||
+ {
|
||||
+ scopes: [
|
||||
+ 'read:user'
|
||||
+ ],
|
||||
+ service: 'gitea'
|
||||
+ }
|
||||
+ ]
|
||||
- []
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:68: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: [ { service: 'gitea', scopes: [Array] } ],
|
||||
expected: [],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:78:1
|
||||
✖ a business grant through limits does not widen the role (1.08749ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-wZ5dqA/businesses/acme.json roles.assistant.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:36:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:79:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:86:1
|
||||
✖ a launch block whose by is the assistant is refused (1.342017ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/. Input:
|
||||
|
||||
'/mnt/storage/scratch/tmp/mosaic-business-zHPTYA/businesses/acme.json roles.assistant.credentials must reference exactly the services its role definition needs (gitea; got none)'
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:25:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:87:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '/mnt/storage/scratch/tmp/mosaic-business-zHPTYA/businesses/acme.json roles.assistant.credentials must reference exactly the services its role definition needs (gitea; got none)',
|
||||
expected: /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:95:1
|
||||
✖ the instance takes no credential references and no tracker (1.123246ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:96:3)
|
||||
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,9 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/assistant.json 2026-10-14 19:38:53.952344522 -0500
|
||||
+++ roles/assistant.json 2026-10-14 19:38:54.343641515 -0500
|
||||
@@ -9,5 +9,5 @@
|
||||
"withinRole": ["message.send"],
|
||||
"crossRole": []
|
||||
},
|
||||
- "credentials": []
|
||||
+ "credentials": [{"service": "gitea", "scopes": ["read:user"]}]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,90 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.748247ms)
|
||||
✖ the shipped file is exactly the approved list (1.110678ms)
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.513003ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.128031ms)
|
||||
✔ the pm does not hold role.launch (1.118588ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.157359ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.274752ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.16483ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.269189ms)
|
||||
✔ the instance takes no credential references and no tracker (1.53432ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 8
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 72.111884
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:64:1
|
||||
✖ the shipped file is exactly the approved list (1.110678ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
...
|
||||
'read',
|
||||
+ 'write',
|
||||
'grep',
|
||||
'find',
|
||||
'ls'
|
||||
]
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:68:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'write', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
expected: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:76:1
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.513003ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
...
|
||||
'read',
|
||||
+ 'write',
|
||||
'grep',
|
||||
'find',
|
||||
'ls'
|
||||
]
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:78: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: { tools: [ 'read', 'write', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] } },
|
||||
expected: { tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] } },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:38:54.466642714 -0500
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "chief-of-staff",
|
||||
"title": "Chief of staff",
|
||||
"contract": "chief-of-staff.md",
|
||||
- "tools": ["read", "grep", "find", "ls"],
|
||||
+ "tools": ["read", "write", "grep", "find", "ls"],
|
||||
"network": "api-only",
|
||||
"authority": {
|
||||
"withinRole": ["message.send", "role.launch"],
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,201 @@
|
||||
✖ the role file loads and resolves through loadBusiness (3.466125ms)
|
||||
✖ the shipped file is exactly the approved list (1.522075ms)
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.095806ms)
|
||||
✖ the chief of staff holds role.launch and message.send; every other action is gated (0.883471ms)
|
||||
✖ the pm does not hold role.launch (0.909578ms)
|
||||
✖ a business grant of a gated action through limits does not widen the role (0.898507ms)
|
||||
✖ a limit that drops role.launch leaves the chief of staff with no launch block (0.818502ms)
|
||||
✖ a launch block whose by is the pm instance is refused (1.176901ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.61793ms)
|
||||
✖ the instance takes no credential references and no tracker (1.176009ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 9
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 70.65365
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:49:1
|
||||
✖ the role file loads and resolves through loadBusiness (3.466125ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-eFpCma/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:50:19)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:64:1
|
||||
✖ the shipped file is exactly the approved list (1.522075ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
{
|
||||
authority: {
|
||||
crossRole: [],
|
||||
withinRole: [
|
||||
'message.send',
|
||||
...
|
||||
contract: 'chief-of-staff.md',
|
||||
+ credentials: [
|
||||
+ {
|
||||
+ scopes: [
|
||||
+ 'read:user'
|
||||
+ ],
|
||||
+ service: 'gitea'
|
||||
+ }
|
||||
+ ],
|
||||
- credentials: [],
|
||||
name: 'chief-of-staff',
|
||||
network: 'api-only',
|
||||
roleVersion: 2,
|
||||
tools: [
|
||||
'read',
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:68:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [ [Object] ] },
|
||||
expected: { roleVersion: 2, name: 'chief-of-staff', contract: 'chief-of-staff.md', tools: [ 'read', 'grep', 'find', 'ls' ], network: 'api-only', authority: { withinRole: [Array], crossRole: [] }, credentials: [] },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:76:1
|
||||
✖ the resolved record matches the approved list, so a widened file fails (1.095806ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-NK6bo9/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:77:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:86:1
|
||||
✖ the chief of staff holds role.launch and message.send; every other action is gated (0.883471ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-rDyRFH/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:87:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:94:1
|
||||
✖ the pm does not hold role.launch (0.909578ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-WOEz7M/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:98:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:103:1
|
||||
✖ a business grant of a gated action through limits does not widen the role (0.898507ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-ysvukt/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:106:19)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:115:1
|
||||
✖ a limit that drops role.launch leaves the chief of staff with no launch block (0.818502ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-pPfUhl/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)
|
||||
at refuse (file:///mnt/storage/scratch/researcher/q119/packages/business/src/errors.mjs:12:9)
|
||||
at checkCredentialMap (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:45:5)
|
||||
at checkRoles (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:108:20)
|
||||
at validateBusinessDocument (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:155:34)
|
||||
at loadBusiness (file:///mnt/storage/scratch/researcher/q119/packages/business/src/business.mjs:203:10)
|
||||
at loadFixture (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:42:28)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:116:27)
|
||||
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) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:123:1
|
||||
✖ a launch block whose by is the pm instance is refused (1.176901ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /launch\.by names pm, whose role pm doesn't hold role\.launch within-role/. Input:
|
||||
|
||||
'/mnt/storage/scratch/tmp/mosaic-business-X4Xmc7/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)'
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:30:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:27:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:124:3)
|
||||
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) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '/mnt/storage/scratch/tmp/mosaic-business-X4Xmc7/businesses/acme.json roles.chief.credentials must reference exactly the services its role definition needs (gitea; got none)',
|
||||
expected: /launch\.by names pm, whose role pm doesn't hold role\.launch within-role/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:142:1
|
||||
✖ the instance takes no credential references and no tracker (1.176009ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:27:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:143:3)
|
||||
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,9 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/roles/chief-of-staff.json 2026-10-14 19:37:48.978629348 -0500
|
||||
+++ roles/chief-of-staff.json 2026-10-14 19:38:54.596643981 -0500
|
||||
@@ -9,5 +9,5 @@
|
||||
"withinRole": ["message.send", "role.launch"],
|
||||
"crossRole": []
|
||||
},
|
||||
- "credentials": []
|
||||
+ "credentials": [{"service": "gitea", "scopes": ["read:user"]}]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,38 @@
|
||||
✔ the role file loads and resolves through loadBusiness (5.227261ms)
|
||||
✔ the shipped file is exactly the approved list (0.216671ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.360346ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.204196ms)
|
||||
✔ the pm does not hold role.launch (1.327856ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.310635ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (1.263068ms)
|
||||
✖ a launch block whose by is the pm instance is refused (1.462439ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.37384ms)
|
||||
✔ the instance takes no credential references and no tracker (5.221906ms)
|
||||
ℹ tests 10
|
||||
ℹ suites 0
|
||||
ℹ pass 9
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 73.503014
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:123:1
|
||||
✖ a launch block whose by is the pm instance is refused (1.462439ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:27:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/chief-of-staff.test.mjs:124:3)
|
||||
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,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/packages/business/src/business.mjs 2026-10-14 19:38:54.712662424 -0500
|
||||
+++ packages/business/src/business.mjs 2026-10-14 19:38:54.730645286 -0500
|
||||
@@ -118,7 +118,7 @@
|
||||
requireId(launch.by, `${where}.by`);
|
||||
if (!Object.hasOwn(roles, launch.by)) refuse(`${where}.by names ${launch.by}, which the business file doesn't declare`);
|
||||
const launcher = definitions[roles[launch.by].definition];
|
||||
- if (!launcher.authority.withinRole.includes("role.launch")) {
|
||||
+ if (false) {
|
||||
refuse(`${where}.by names ${launch.by}, whose role ${launcher.name} doesn't hold role.launch within-role`);
|
||||
}
|
||||
const instances = requireDistinctList(launch.instances, `${where}.instances`, (name) => {
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,35 @@
|
||||
✔ the role file loads and resolves through loadBusiness (6.442661ms)
|
||||
✔ the shipped file is exactly the approved list (0.726312ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.702801ms)
|
||||
✔ a business grant through limits does not widen the role (1.357181ms)
|
||||
✖ a launch block whose by is the assistant is refused (1.889341ms)
|
||||
✔ the instance takes no credential references and no tracker (2.328818ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.658413ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 84.029268
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:86:1
|
||||
✖ a launch block whose by is the assistant is refused (1.889341ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/assistant.test.mjs:87:3)
|
||||
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,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/packages/business/src/business.mjs 2026-10-14 19:38:54.712662424 -0500
|
||||
+++ packages/business/src/business.mjs 2026-10-14 19:38:54.861646563 -0500
|
||||
@@ -118,7 +118,7 @@
|
||||
requireId(launch.by, `${where}.by`);
|
||||
if (!Object.hasOwn(roles, launch.by)) refuse(`${where}.by names ${launch.by}, which the business file doesn't declare`);
|
||||
const launcher = definitions[roles[launch.by].definition];
|
||||
- if (!launcher.authority.withinRole.includes("role.launch")) {
|
||||
+ if (false) {
|
||||
refuse(`${where}.by names ${launch.by}, whose role ${launcher.name} doesn't hold role.launch within-role`);
|
||||
}
|
||||
const instances = requireDistinctList(launch.instances, `${where}.instances`, (name) => {
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,43 @@
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (1.114323ms)
|
||||
✔ the fixture business validates and comes back frozen (3.611743ms)
|
||||
✔ two instances may share a definition (1.07717ms)
|
||||
✔ top-level refusals (3.083891ms)
|
||||
✔ arbiters and projects (4.886909ms)
|
||||
✔ role instances (2.195591ms)
|
||||
✔ Vikunja bots (4.907487ms)
|
||||
✔ a role without Vikunja takes no tracker block (2.080745ms)
|
||||
✔ credential references match the definition's services (2.54856ms)
|
||||
✖ launch (2.102669ms)
|
||||
✔ loadBusiness: file checks (1.911454ms)
|
||||
✔ loadBusiness: not a regular file (38.535041ms)
|
||||
✔ loading writes nothing (1.127878ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.647859ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.678868ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 14
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 129.534082
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/business.test.mjs:120:1
|
||||
✖ launch (2.102669ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refuses (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:11:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q119/packages/business/tests/business.test.mjs:123:3)
|
||||
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,11 @@
|
||||
--- /mnt/storage/src/mosaic-stack/agents/researcher/work/queue-119/mutants/.bak.Wznjl6/packages/business/src/business.mjs 2026-10-14 19:38:54.712662424 -0500
|
||||
+++ packages/business/src/business.mjs 2026-10-14 19:38:55.001647927 -0500
|
||||
@@ -118,7 +118,7 @@
|
||||
requireId(launch.by, `${where}.by`);
|
||||
if (!Object.hasOwn(roles, launch.by)) refuse(`${where}.by names ${launch.by}, which the business file doesn't declare`);
|
||||
const launcher = definitions[roles[launch.by].definition];
|
||||
- if (!launcher.authority.withinRole.includes("role.launch")) {
|
||||
+ if (false) {
|
||||
refuse(`${where}.by names ${launch.by}, whose role ${launcher.name} doesn't hold role.launch within-role`);
|
||||
}
|
||||
const instances = requireDistinctList(launch.instances, `${where}.instances`, (name) => {
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,105 @@
|
||||
32a67dc1d5d2ea3f9f7e3ed01dee56bb77163067b7bb8f7123f76b6b77e2a2ff build.md
|
||||
8ebb56b55d274c36f8e6e4d617c37e260bbc2a11fa3b05de6299df34e54ac388 candidate-manifest.sha256
|
||||
20214fa69ceb5da7f6a64efe5812edce9b6e2a0836a06bb06d347f7475f34cae mutants/control-assistant.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-assistant.rc
|
||||
f8e268ac9f2bb5dae8ec881fc322d8e0e455bbc8558f1d0d30822622a6db4c9d mutants/control-bundle.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-bundle.rc
|
||||
b68f641d5084f6907609b29cc19a1a6703ef490b7c46ca0f00c2fe4e337be8e6 mutants/control-business.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-business.rc
|
||||
24a6dfd37399b95048f2f151a202af46a9a29e152fe28dab5381cab89be1b888 mutants/control-chief-of-staff.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-chief-of-staff.rc
|
||||
07dfbc80e16e7171afa85a7bb4dcfae7fbe429242773f092363f00284c7a2a6a mutants/control-launcher.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-launcher.rc
|
||||
7a3b7c7398f25d0bd1f4744378ef464f5b7591e28cb1f8a362acb9ed8de3e056 mutants/control-reads.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-reads.rc
|
||||
798db167bf5baf94ce1fa5ab850845af34f40c101a7b37d4a9468b922978e0f1 mutants/control-role.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-role.rc
|
||||
8922f1c1ac50f57422532802b0e5414951b3e1d1df589dfd808896348a98c9a6 mutants/control-tools.out
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/control-tools.rc
|
||||
bcfb3e7171b96ca394f7865ff08ebacee41db9cfc012530f17db0507eab3fd12 mutants/m10-pm-contract-launches.out
|
||||
4be29ec28026325258b03a183c05d959302b3294578f1b458abb0d0142b8919d mutants/m10-pm-contract-launches.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m10-pm-contract-launches.rc
|
||||
ae9c55b6df0bf0588a46817aa4f3a2925fc401a33e39f6c3b1d4a1355840278c mutants/m11-chief-contract-talks.out
|
||||
bacc257d903848dd85a2b75ed801c2c8b012ffc47618845ebd34a7d5bea6bb96 mutants/m11-chief-contract-talks.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m11-chief-contract-talks.rc
|
||||
c4125e2cb9c36833b1193d42afd6d1c0b1dccc124588c24123c605d436773da1 mutants/m12-assistant-contract-directs.out
|
||||
413d8444826b41b9667f32e02fd03dfb28dd57a8954159b97705454dc23a02e4 mutants/m12-assistant-contract-directs.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m12-assistant-contract-directs.rc
|
||||
6121f69efcde862860940475d911314a931431ebfd8674b219bdf78e3437b05c mutants/m13a-assistant-contract-missing.out
|
||||
9ffbbade4871ff3d3eb79756b917fa81acf71b161b61e12af3d0c977934d97c1 mutants/m13a-assistant-contract-missing.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m13a-assistant-contract-missing.rc
|
||||
06b937ad30a9cf428151d8e242537bd2fb736e2648ba5b368280f684cdc9ffc2 mutants/m13b-assistant-contract-missing.out
|
||||
6806bcb2e15206d065b0f69505713c17a810c1213cd2ab9d855f772a013d2f7d mutants/m13b-assistant-contract-missing.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m13b-assistant-contract-missing.rc
|
||||
de90cdf3aa267b6e71ebee6b41058bb55442259dad38d2188ccb68f709988c94 mutants/m1a-chief-drops-launch.out
|
||||
f6d9c9e9f12584ccc0a867cff5b25e950775568609a4d61b080b820f424109e8 mutants/m1a-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1a-chief-drops-launch.rc
|
||||
889fc0eb03d32242f833b4de63587d41b2fceae8d7f612699f3f979db5d2820e mutants/m1b-chief-drops-launch.out
|
||||
b77ca00a70bdfb2ac510f681e1877f9c1b9cc8c50973679fb53159531d45585c mutants/m1b-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1b-chief-drops-launch.rc
|
||||
895b5f924986fc0d59c7b8f6854d7d28409c8e8a04dfd73677dc2175c6f59ed9 mutants/m1c-chief-drops-launch.out
|
||||
805255dcaaa1390f31d71b100faa1d79e14d3f5f59331a928c06933727a098be mutants/m1c-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1c-chief-drops-launch.rc
|
||||
850c7ba67a799d167f520a57997584ebe4a246bb420ea89ca27f028b5f82f0de mutants/m1d-chief-drops-launch.out
|
||||
42b2ccd96a6061d195360ab1586df27752356aace629473b33f82be96929aa60 mutants/m1d-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1d-chief-drops-launch.rc
|
||||
127397ac44076eed1c6bd9409db821f65f64d5c5954e450eefad55b91c6620bd mutants/m1e-chief-drops-launch.out
|
||||
1306159d0ff8b397d2bbde757d09bcbeed6c186fbf5193790fe3ef2e041fd758 mutants/m1e-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1e-chief-drops-launch.rc
|
||||
6d78802b57cf1c534b59b57714c290768bb2e4992d3bd57b7386eb3d6ebdaa40 mutants/m1f-chief-drops-launch.out
|
||||
c0d762b8182bf2e9fac6c15336b3ac98eeb432eb1efcb63a51bd929093f5aa91 mutants/m1f-chief-drops-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m1f-chief-drops-launch.rc
|
||||
aec994f9f0da740606b870591a5efab6a98ab7775bb67a9e0e3fdb9a09009fb1 mutants/m2a-pm-regains-launch.out
|
||||
55f26e21a9daa64078f1cd43ef3e264243d1d41009fc8e35a9c111c248eca612 mutants/m2a-pm-regains-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m2a-pm-regains-launch.rc
|
||||
831c5598caca95ecfc04a4d0df32263c4665601f6216649bf4ed7d13b8cc8bd1 mutants/m2b-pm-regains-launch.out
|
||||
15235db7d4104f8fa0ee2fad84f2ff977bfb7d64144a13564f1fb1b8a9937419 mutants/m2b-pm-regains-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m2b-pm-regains-launch.rc
|
||||
10052acab24fd04f8649300b306a4d8a617df7dc0fc4105403ccb4b1864cfcc9 mutants/m2c-pm-regains-launch.out
|
||||
1ac98a45f06dfa59bbba4148ebc7c253b747b887519eecd8efc95a90ce3d871d mutants/m2c-pm-regains-launch.patch
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/m2c-pm-regains-launch.rc
|
||||
2cd187390b6e1bb4d0c567f3cb0b5cecf60cdf3a3b75fe0f18d19bead33fce6c mutants/m2d-pm-regains-launch.out
|
||||
04b3b1064866b2837d1012f4e2c3b5a1df919bbed83ec6661f507f9cad8f32a7 mutants/m2d-pm-regains-launch.patch
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/m2d-pm-regains-launch.rc
|
||||
685dc67e0b95547ec3cf714cee1927437ec67a93fd63dde4fa7d73528436843c mutants/m2e-pm-regains-launch.out
|
||||
1f084985e0e7d32d82b440c5f7654cf6ec3fa872d4dae27865c3cf892e247b70 mutants/m2e-pm-regains-launch.patch
|
||||
9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa mutants/m2e-pm-regains-launch.rc
|
||||
8dfc2ff1cc99a3640e209bf34d0f231c85365c3e4449f519a7c730a39dd78472 mutants/m3-assistant-launch.out
|
||||
f48575f3e24b22de8a446fea339b0390adc31406fedac3233b31979d59b38657 mutants/m3-assistant-launch.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m3-assistant-launch.rc
|
||||
122ef39d3bb0c4bb11d977e6b2e9430651d18f225357d71b0e3eb63afe9ec2ab mutants/m4-assistant-write.out
|
||||
2a17a78bf0e65d3bf6c00e9982a35e09a8cf81ec73e5f0d431bf88596f304e02 mutants/m4-assistant-write.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m4-assistant-write.rc
|
||||
4edba2357c7d6670fb33451b34c309d67636bc8e7dbc4ea51514b5d2055ebbce mutants/m5-assistant-crossrole.out
|
||||
ec42a7c564c2e6b19f2902126509d97d4bdc5919f3db5b16fe56a3a60177fc3a mutants/m5-assistant-crossrole.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m5-assistant-crossrole.rc
|
||||
f7e441ceb419eb0f9d659ba3abe67357a33b58ba22bd6e2b0615bc1fa3293859 mutants/m6-assistant-credential.out
|
||||
d8e9e105d81f211d5d6a1aba0270aed96926397db014c67b2d43e19cd5bbed66 mutants/m6-assistant-credential.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m6-assistant-credential.rc
|
||||
826966f0045f5b17c1bd30836c6c90489ac0002f5278719fad8802b4954a0568 mutants/m7-chief-write.out
|
||||
1d321d947f75f82a0b77bd0859ea53697a4649245521b02158f90d3c25f0a90d mutants/m7-chief-write.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m7-chief-write.rc
|
||||
73ee25746dc618a697687e90bbfe2fa9b676a23207a09798e427ed5f2d88382b mutants/m8-chief-credential.out
|
||||
5c2c528c7485f8453037cbf9b1cb0eef8841c76eb08c218cf4634e2775996a9f mutants/m8-chief-credential.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m8-chief-credential.rc
|
||||
cf6edf4723f7e6560eff68d5a5996222c66f8f920cdb7efdcbe5820e00de22b1 mutants/m9a-validator-accepts-any-launcher.out
|
||||
8d49a707c3b8a0b6b9966cc775f9928d3bde0888d5fb3281f7edebc859a09ba7 mutants/m9a-validator-accepts-any-launcher.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m9a-validator-accepts-any-launcher.rc
|
||||
12cb2044aad1c81d6ffbbd4a81395e5adbd64c1609aa61cbe7566c0ce2d961d4 mutants/m9b-validator-accepts-any-launcher.out
|
||||
ec968e1ca36ccf21548290c58fb540509ca5b4ab44f5e54a32785cbbc5d99a8e mutants/m9b-validator-accepts-any-launcher.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m9b-validator-accepts-any-launcher.rc
|
||||
875f4be90457fdc89f7f92709e15000bd86738517e2fd3c6787b2ffa4273335e mutants/m9c-validator-accepts-any-launcher.out
|
||||
33f22744c31971cbe614c3edc109e09860206ad7173a85e079b6076f21b40b37 mutants/m9c-validator-accepts-any-launcher.patch
|
||||
4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 mutants/m9c-validator-accepts-any-launcher.rc
|
||||
8a8524db550f433863b4a5f12647f0866033bd5d185281dbb49481e869d2bec9 mutants-run.txt
|
||||
83c3b1712a75b4e3114b879fde51b2752ecc3622b1c37ea1cc4218a601bf352c mutants.sh
|
||||
b73a0976771b5226d90bb368fe93d90ef384a55eca95273874ec9ea0dd3ffce7 row119.patch
|
||||
ddacea45cc85d6125e016a6aa4abd18d17554f492ce27359cc0eed8ad51b82fc suites/business.txt
|
||||
2b1e99a388cc96da2555a514a37007f9d6e6113928f4f2f02539a30600762c59 suites/bus.txt
|
||||
0d6cea57f7f2e75989801d3700990f488286c18ab968884b015c11966376934e suites/cli.txt
|
||||
045179f68e5f83457251e17b3ea0376a36323e93e82e74b3779b70fbf6ca093d suites/conversation.txt
|
||||
a2f2020f2a4747bd1c47dab32a9ab70e9c0bd62c31de78c9f871f26f026693d5 suites/harness.txt
|
||||
39e022f7a0fdeada20a6054f2543c3b97c454fcae6df6f36d55963aa2d30ff06 suites/seat.txt
|
||||
460f6c61ee69a2dca490d4a10788c83508a2c731f0fe15d0bac1e86658ca25a0 suites/tasks.txt
|
||||
ccea37f4ffde1f160dcd1a1864988083a645d974e892065c956b338d0f8c853a suites/test-task.txt
|
||||
a5709103bff634e76b1ee460d8ca97c228526151ad95e528c774752ee9e8ee55 suites/webui.txt
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,166 @@
|
||||
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 (49.384223ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (33.623199ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (51.383272ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (21.866653ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (31.096925ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (32.782999ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (32.946874ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (34.223111ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (149.387792ms)
|
||||
✔ agents: stranded is per role and per business (42.034853ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (15.427707ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (43.250308ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (39.695895ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (34.466992ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (24.029094ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (26.240864ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (50.425174ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (22.753948ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (45.780962ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (18.483094ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (30.428515ms)
|
||||
✔ authority never transfers between action, run, target, unresolved or replaced role holder (45.908424ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (22.346528ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (29.957541ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (17.577378ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (28.088945ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (22.396626ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (4.044745ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (37.917892ms)
|
||||
✔ credentials refuses a role session and any argument (28.927412ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (32.081434ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (98.288158ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (10.928291ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (5.810698ms)
|
||||
✔ expiry refuses use and env references never become client data (1.357074ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (2.434756ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (3.930869ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (64.455611ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (33.051813ms)
|
||||
✔ a human withdraw sends one message with the note (30.855078ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (44.655889ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (50.005946ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (53.867305ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (41.036719ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (42.207659ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (60.871261ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (41.058616ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (40.916607ms)
|
||||
✔ recent stops at RECENT rows (152.660087ms)
|
||||
✔ every row is what trail already gives the same session for that id (58.821182ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (66.201023ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (48.67061ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (36.6956ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (19.754792ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (19.780958ms)
|
||||
✔ endLaunch leaves a claim another run took alone (26.78267ms)
|
||||
✔ refuse records action.refused against the caller with the code only (18.474217ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (27.182253ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (134.541434ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (4.931939ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (1.223458ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (1.342824ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.451218ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (39.070827ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (25.24062ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (30.550102ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (493.201465ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (21.622385ms)
|
||||
✔ views messages passes only its paging arguments through (0.341173ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (15.370686ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (104.969217ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (60.732531ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (106.822131ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (139.487944ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (76.24671ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (50.336838ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (72.469026ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (56.511176ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (24.515072ms)
|
||||
✔ a message with no reply gives an empty list (23.150006ms)
|
||||
✔ replies come oldest first and stop at REPLIES (129.566555ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (53.716416ms)
|
||||
✔ strict arguments; a role session gets human-required (55.564335ms)
|
||||
✔ views passes replies through as one call with the id (0.799411ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (36.879039ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (19.993024ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (26.212816ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (42.770341ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (33.756739ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (37.815061ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (62.13919ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (37.388693ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (45.979383ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (62.974417ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (37.949579ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (120.173143ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (41.746307ms)
|
||||
✔ another run cannot consume an approval; a failed check leaves it usable (29.632712ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (28.587763ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (56.460779ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (39.620882ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (37.381219ms)
|
||||
✔ class drift gated to within-role refuses before consumption (40.242234ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (37.749804ms)
|
||||
✔ class drift within-role to gated refuses before consumption (28.56679ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (25.402299ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (28.252153ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (26.619285ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (24.552263ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (23.473762ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (24.445026ms)
|
||||
✔ a tombstone is not open (23.677469ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (31.047913ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (19.994669ms)
|
||||
✔ a human session reads the same state, with the same cap (25.227503ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (21.847483ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (24.570004ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (27.246511ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (23.96838ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (84.963565ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (22.897338ms)
|
||||
✔ async transactions refuse before invoking their function (14.498062ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (228.496566ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (105.390943ms)
|
||||
✔ each filter, alone and together, and total counts every match (187.665406ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (103.515549ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (80.300203ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (362.574786ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (59.690105ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (68.616345ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (14.497092ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (34.058062ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (18.500069ms)
|
||||
✔ a bad entry refuses the whole record (19.250747ms)
|
||||
✔ taskView reads the projection for one business (24.478487ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (31.474439ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (278.546351ms)
|
||||
✔ without an adapter the server refuses every task verb (20.059427ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (20.730262ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (118.433808ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (106.852593ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (24.328038ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (45.416599ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (18.920147ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (20.482593ms)
|
||||
✔ the tester reads the human views a reader reads (24.085721ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.364101ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.42516ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.269691ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (22.206638ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (710.743158ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (36.107291ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (27.349126ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (15.169522ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (12.264245ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (17.755748ms)
|
||||
ℹ tests 156
|
||||
ℹ suites 0
|
||||
ℹ pass 156
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1450.14557
|
||||
@@ -0,0 +1,88 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ the role file loads and resolves through loadBusiness (8.757295ms)
|
||||
✔ the shipped file is exactly the approved list (1.17548ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (2.293263ms)
|
||||
✔ a business grant through limits does not widen the role (2.390957ms)
|
||||
✔ a launch block whose by is the assistant is refused (2.081935ms)
|
||||
✔ the instance takes no credential references and no tracker (3.446612ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.339161ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (2.282523ms)
|
||||
✔ the fixture business validates and comes back frozen (6.702787ms)
|
||||
✔ two instances may share a definition (2.461208ms)
|
||||
✔ top-level refusals (6.70917ms)
|
||||
✔ arbiters and projects (8.534383ms)
|
||||
✔ role instances (4.605411ms)
|
||||
✔ Vikunja bots (6.355468ms)
|
||||
✔ a role without Vikunja takes no tracker block (2.239476ms)
|
||||
✔ credential references match the definition's services (2.514846ms)
|
||||
✔ launch (8.006632ms)
|
||||
✔ loadBusiness: file checks (2.248071ms)
|
||||
✔ loadBusiness: not a regular file (42.616881ms)
|
||||
✔ loading writes nothing (1.39767ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.81657ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.631327ms)
|
||||
✔ the role file loads and resolves through loadBusiness (8.439724ms)
|
||||
✔ the shipped file is exactly the approved list (0.827515ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (2.684616ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (1.981672ms)
|
||||
✔ the pm does not hold role.launch (2.1383ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (2.654861ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (2.213253ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.827647ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.379178ms)
|
||||
✔ the instance takes no credential references and no tracker (2.101069ms)
|
||||
✔ usage errors exit 4 (299.552943ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (68.003738ms)
|
||||
✔ validate: project files (327.672493ms)
|
||||
✔ validate: missing files and a broken system config (254.070024ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (71.290439ms)
|
||||
✔ validate: a token file inside the repository is refused (68.143184ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (202.173732ms)
|
||||
✔ resolve: prints one instance's record (267.89148ms)
|
||||
✔ resolve: refusals (400.549345ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (4.093698ms)
|
||||
✔ check: a good file has no problems (1.300717ms)
|
||||
✔ check never opens the file: a write-only token passes (0.554356ms)
|
||||
✔ check: file problems (1.392279ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.351493ms)
|
||||
✔ check: dates and environment references (0.614926ms)
|
||||
✔ path and load (3.205446ms)
|
||||
✔ refusals (1.894874ms)
|
||||
✔ systemVars flattens the validated config (3.049647ms)
|
||||
✔ precedence: system, business, project, project role, agent (6.841932ms)
|
||||
✔ limits narrow the definition and never widen it (3.008136ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (7.418399ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (2.962364ms)
|
||||
✔ limits.authority narrows cross-role actions too (4.208876ms)
|
||||
✔ classify (1.824688ms)
|
||||
✔ the record carries what the broker and launcher need (1.64436ms)
|
||||
✔ digest: key order doesn't matter, any value change does (5.962938ms)
|
||||
✔ refusals (2.345609ms)
|
||||
✔ the four shipped version 2 roles load (4.1598ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (1.276827ms)
|
||||
✔ shipped authority follows the note's table (0.788543ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (0.865688ms)
|
||||
✔ version 1 files keep loading with no authority (1.107582ms)
|
||||
✔ the conductor policy isn't a role (0.242917ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.556779ms)
|
||||
✔ version 2 refusals (1.957412ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (3.549793ms)
|
||||
✔ credentials: Gitea scopes (1.62296ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.671689ms)
|
||||
✔ credentials: services (0.821372ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (1.541676ms)
|
||||
✔ every key names known layers and a merge rule (1.188872ms)
|
||||
✔ unknown keys and wrong layers refuse (0.928826ms)
|
||||
✔ types (2.445085ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.422748ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.582765ms)
|
||||
✔ merge doesn't change its inputs (0.228965ms)
|
||||
ℹ tests 78
|
||||
ℹ suites 0
|
||||
ℹ pass 78
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2059.880607
|
||||
@@ -0,0 +1,199 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ every screen and overlay fits 120x36, 80x24 and the narrow layout, row for row (1755.202058ms)
|
||||
✔ width counts terminal cells: wide CJK and emoji 2, U+FE0F after a one-cell base 1, marks 0 (85.06996ms)
|
||||
✔ broker text is shown, never interpreted: no raw control character or bidi override reaches the terminal (204.722714ms)
|
||||
✔ NO_COLOR: no escape codes, except reverse video on the selected row (351.642792ms)
|
||||
✔ 1-9 shows the decide flow's own lines and question; only y resolves (60.776791ms)
|
||||
✔ the app shows the same decide text as mosaic decide (25.334185ms)
|
||||
✔ any key but y or Y at the question answers No; nothing is sent (225.55458ms)
|
||||
✔ below 40x10 the question is hidden, so every key answers it No, y included (Filbert R3) (78.698708ms)
|
||||
✔ under 40 columns a tall terminal shows the too-small screen even where the decide box would fit; y sends nothing (Filbert N10) (321.92585ms)
|
||||
✔ a hidden decide box names the way out, and the status line under it does not promise y (Filbert N12) (43.934631ms)
|
||||
✔ a throw while answering the question goes to crash, sends nothing and leaves no job pending (27.818442ms)
|
||||
✔ type-ahead never answers the question: a paste, keys typed before it is drawn, keys inside askMs (435.140456ms)
|
||||
✔ quitting at the question answers No and sends nothing, armed or not (52.395722ms)
|
||||
✔ a timer tick reads nothing under an overlay, never answers the question, and keeps a resolved status (46.544282ms)
|
||||
✔ a long question is cut inside the question; the action, target, choice and prompt stay (Dewey B1) (57.941874ms)
|
||||
✔ a decide box too big for the terminal says so, and every key answers it No, y included (Dewey B1, round 3) (410.656819ms)
|
||||
✔ at every size the decide box shows each line y depends on, or says it is hidden (9567.651319ms)
|
||||
✔ outcome unknown: the CLI's sentence, no retry, then the trail or a re-read (65.837924ms)
|
||||
✔ refused and failed reads keep the last list, marked stale; a refused decide says refused (31.822798ms)
|
||||
✔ help or a detail box cut to fit keeps its last line, Esc included (Dewey) (15.841057ms)
|
||||
✔ keys: views, moving, trail of a selection, the command line, help and quit (79.096174ms)
|
||||
✔ one option: the status line says Press 1, not 1-1 (16.823581ms)
|
||||
✔ no business: the app says so and :business picks one (9.94374ms)
|
||||
✔ mosaic with no argument: exit 3 in an agent run, exit 4 with the usage off a terminal, the app on one (2.347613ms)
|
||||
✔ scripts/mosaic with no argument reaches the app entry; the seat usage it printed before has not drifted (186.383747ms)
|
||||
✔ strings to keep exactly live once, in the decide flow and the transport; the app does not restate them (0.472519ms)
|
||||
✔ decide with --note still asks; a No sends nothing (11.377688ms)
|
||||
✔ the app's business comes from a live bus host only (1.374452ms)
|
||||
✔ runApp leaves the terminal as it found it on q, end of input, SIGTERM, SIGINT, SIGHUP and an error, the first frame's included (7.771707ms)
|
||||
✔ draw is pure: same state, same frame (0.945961ms)
|
||||
✔ inbox lists only decisions routed to the human, with what approving authorizes and how to decide (35.738873ms)
|
||||
✔ decide resolves by id prefix with --yes, and the trail shows it in broker order with the task to follow (31.200288ms)
|
||||
✔ decide refuses without a terminal or --yes, on an unknown option and on a short reference (23.088521ms)
|
||||
✔ decide prints a declining choice as declining (22.152697ms)
|
||||
✔ an unknown outcome is reported once and never resent (17.664246ms)
|
||||
✔ a decision closed before the answer arrives exits 2 and points at its trail (19.12664ms)
|
||||
✔ a prefix that matches two open decisions exits 2 and resolves neither (20.045416ms)
|
||||
✔ without --business a command uses the live host's business, and a stale host.json is not a host (19.969845ms)
|
||||
✔ every human command refuses inside an agent run before it touches the bus (18.777842ms)
|
||||
✔ usage errors exit 4; no business and no host is a usage error (20.997088ms)
|
||||
✔ agents and tasks print through the broker (18.901526ms)
|
||||
✔ notify.json: missing, loose, malformed and extra keys refuse; a binding or null passes (2.636662ms)
|
||||
✔ bootConfig builds the broker's boot message for one business, with no trackers key when no project names one (76.567871ms)
|
||||
✔ trackers come from the tracker.* variables of the one project that names a tracker project (119.573988ms)
|
||||
✔ with two projects, the one that sets tracker.project supplies the tracker and the other is no conflict (59.154242ms)
|
||||
✔ two projects that each name a tracker project refuse, since the boot shape holds one (55.842043ms)
|
||||
✔ a business without tracker.baseUrl gets no trackers entry (61.63999ms)
|
||||
✔ an unknown business and a broken system config refuse with exit 3 (91.97515ms)
|
||||
✔ follow prints an unsolicited message after plain talk returned (48.59522ms)
|
||||
✔ talk --follow continues after reply and prints a later unsolicited message (46.078265ms)
|
||||
✔ inbox lists all unread human messages under decisions, does not deliver or read them (388.936882ms)
|
||||
✔ follow refuses agent context and bad arguments (10.874554ms)
|
||||
✔ follow Ctrl-C wakes the poll sleep and removes its handler; transport errors also clean up (12.49567ms)
|
||||
✔ plain talk leaves the process SIGINT handlers unchanged (11.741403ms)
|
||||
✔ empty views say so (1.084984ms)
|
||||
✔ the trail keeps the broker's order and names a decision's task without its rows (1.449098ms)
|
||||
✔ tasks print the tracker fields the snapshot carries (0.324599ms)
|
||||
✔ the review loop: the coder pushes and asks, the reviewer fetches and approves, and the task's trail holds each step (599.489395ms)
|
||||
✔ refusals: no action, non-fast-forward, an unknown commit or request, and a push for another task moves only that task's ref (397.704181ms)
|
||||
✔ the size cap refuses a push before any byte (180.338435ms)
|
||||
✔ a fetch over the cap refuses before any byte reaches the reviewer (409.779723ms)
|
||||
✔ the socket refuses a request with no capability, an unknown one, and a bad request line (189.404458ms)
|
||||
✔ a rigged clone runs nothing: hooks, fsmonitor, a filter, a gitlink and a symlinked .git/config leave no marker (341.200626ms)
|
||||
✔ an identity with no role, or of another business, refuses not-a-role and moves no ref (305.832007ms)
|
||||
✔ a review of a project the business no longer has refuses unknown-project (226.339594ms)
|
||||
✔ past maxActive connections the socket refuses git-busy, and a hung-up connection frees its slot (150.335156ms)
|
||||
✔ close() answers host-closing to a connection still sending its request line (151.033922ms)
|
||||
✔ a bundle that trickles in refuses body-timeout at its deadline and frees its slot (573.293435ms)
|
||||
✔ a reviewer gone before its bundle was sent is filed fetch-aborted, not as the host's fault (528.643759ms)
|
||||
✔ a reviewer that hangs up the moment it has the whole bundle was served, not aborted (695.033182ms)
|
||||
✔ send: a close after every byte left is served; one that fails a queued write is fetch-aborted (42.073341ms)
|
||||
✔ a bundle with no bytes for bodyIdle refuses body-timeout long before its deadline (470.55894ms)
|
||||
✔ send: a close once the loop is past its last chunk is served, and a failed write there is fetch-aborted (45.364464ms)
|
||||
✔ letGo waits for an answer to leave for at most its cap, then destroys the socket (302.399856ms)
|
||||
✔ a record that fails and can't be undone refuses rollback-failed, which the host logs (406.296601ms)
|
||||
✔ the host boots the broker, binds a launch in process, and the notifier DMs a blocking decision exactly once (981.345635ms)
|
||||
✔ a notifier that dies takes the host down with exit 1, so the unit restarts the pair (193.361313ms)
|
||||
✔ a second host for the same data root refuses with exit 3 while the first runs (92.94006ms)
|
||||
✔ two bus starts racing for one data root leave one host running; the other refuses that a host already runs (537.266114ms)
|
||||
✔ a host takes over a host.lock its dead host left, and puts back a live claim that replaced it meanwhile (1.848804ms)
|
||||
✔ a host.lock that goes between the check and the read is tried again; one that can't be parsed still refuses as unreadable (1.167912ms)
|
||||
✔ a live host's lock stays, however old the file is (0.751121ms)
|
||||
✔ a host.lock left by a host killed with SIGKILL doesn't stop the next bus start (835.71707ms)
|
||||
✔ while a host boots, a reader sees no host: the human commands still ask for --business, stop and status find none (243.306814ms)
|
||||
✔ a host started before host.lock existed, holding only host.json, still refuses a second start, which leaves no lock (37.827168ms)
|
||||
✔ a broker fork that throws leaves no host.lock and no host.json (38.184922ms)
|
||||
✔ a broker send that throws leaves no host.lock and no host.json (37.128017ms)
|
||||
✔ a broker that misses its boot wait leaves no host.lock and no host.json (40.998687ms)
|
||||
✔ a notifier fork that throws stops the broker and leaves no host.lock and no host.json (99.718839ms)
|
||||
✔ a notifier send that throws stops the broker and leaves no host.lock and no host.json (107.631642ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, before the notifier starts, and leaves no host.lock and no live broker (100.668983ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, with no notifier, and leaves no host.lock and no live broker (93.394ms)
|
||||
✔ a host.json that can't be written stops both children and leaves no host.lock (218.450091ms)
|
||||
✔ an error event on the broker before it replies fails the start at once, and leaves no host.lock and no live child (43.887179ms)
|
||||
✔ an error event on the notifier before it replies fails the start at once, and leaves no host.lock and no live child (100.136878ms)
|
||||
✔ an error event on the broker while the notifier starts fails the start once the notifier replies (249.692882ms)
|
||||
✔ an error event on the broker once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (249.532964ms)
|
||||
✔ an error event on the notifier once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (264.191528ms)
|
||||
✔ a broker reply that misses the wait breaks the channel: the late reply answers nothing, later requests refuse, the host exits 1 (1103.778306ms)
|
||||
✔ a broker reply with another request's id, or none, breaks the channel and the host exits 1 (194.21146ms)
|
||||
✔ a broker reply with no request waiting breaks the channel and the host exits 1 (94.166327ms)
|
||||
✔ a notifier that refuses stops the broker and the host refuses with exit 3 (169.803145ms)
|
||||
✔ a notifier that refuses after the broker died still refuses with exit 3, without a send to the dead broker (167.096847ms)
|
||||
✔ a notifier that dies before it replies, after the broker died, still refuses, without a send to the dead broker (93.964289ms)
|
||||
✔ a close send that fails with EPIPE after the notifier refuses still gives the notifier's refusal, exit 3 (151.504923ms)
|
||||
✔ a close send that fails with EPIPE after the notifier dies unanswered still gives the notifier's error (87.015545ms)
|
||||
✔ close() whose stop and close sends fail with EPIPE still finishes, with exit 1 (188.799999ms)
|
||||
✔ watchChildren reports a child that died before it was called, and one that dies later (28.269286ms)
|
||||
✔ bus stop refuses to signal a live pid that is not a bus host (203.002829ms)
|
||||
✔ bus start refuses with exit 3 and the code when the broker refuses to boot; bus status names the lock (322.940126ms)
|
||||
✔ bus start refuses with exit 3 without a notifier config (134.010318ms)
|
||||
✔ bus start runs until bus stop; status reports it while it runs (744.256824ms)
|
||||
✔ bus-service.sh renders the unit and installs it into a given directory (66.48246ms)
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (87.274248ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (20.814288ms)
|
||||
✔ bus-service.sh refuses a default claude without the execute bit, or in a PATH dir with a space (13.368898ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1346.4959ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (508.605067ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3672.4744ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (143.597981ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (221.551812ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (115.463598ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (222.486237ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (256.497589ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (114.122135ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1332.984708ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (636.743917ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3592.303557ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (93.151042ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (94.826346ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (93.829958ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1216.10315ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.930876ms)
|
||||
✔ zoned uses the IANA zone across DST (30.505883ms)
|
||||
✔ each open blocking decision is DM'd once, across polls and a restart; non-blocking ones are not (32.165556ms)
|
||||
✔ two blocking decisions get two DMs with different nonces (21.183486ms)
|
||||
✔ the digest nonce differs per business and per day and fits Discord's 25 characters (0.449784ms)
|
||||
✔ a failed DM is journaled, backs off, and is retried until it lands (27.335718ms)
|
||||
✔ five definite refusals stop a DM: one gave-up line, one log line, and a restart keeps the count (29.781901ms)
|
||||
✔ 429s, 5xx-style unknowns and refusals without a status never count toward the limit (29.763338ms)
|
||||
✔ a crash between the fifth refusal and its gave-up line: the next poll appends it and sends nothing (20.295208ms)
|
||||
✔ polled every POLL_MS against a permanent 403, a DM is sent at 0, 30, 60, 90 and 120 min and gives up only then (153.433737ms)
|
||||
✔ a restart after the second refusal does not send before that refusal's 30 min are up (72.01007ms)
|
||||
✔ the digest goes at 08:00 Chicago once a day, with blocking ones marked as DM'd (21.646608ms)
|
||||
✔ a late start with no digest for the day sends one at once; an empty inbox gets one line (12.690625ms)
|
||||
✔ an inbox read failure is logged and the next poll retries (1.218455ms)
|
||||
✔ no Discord id reaches the journal or the log (13.707228ms)
|
||||
✔ the journal: a torn tail is copied out and truncated, so an append after it reopens cleanly (3.327947ms)
|
||||
✔ the journal: a crash between the copy and the truncate leaves a tail the next open repairs (3.29716ms)
|
||||
✔ the journal: a whole file that is one torn line truncates to empty (1.787397ms)
|
||||
✔ the journal: a malformed complete line refuses and leaves the file and any torn tail alone (0.592322ms)
|
||||
✔ the journal: a loose file mode, a loose directory or a symlinked journal refuses (0.671195ms)
|
||||
✔ the journal: a line with a wrong type refuses with exit 3 and names the field (2.897815ms)
|
||||
✔ the journal: a symlinked directory refuses and says it is a link (0.446215ms)
|
||||
✔ the journal: a dangling directory link, a parent that is a file and a journal that is a directory each refuse with exit 3 (0.611818ms)
|
||||
✔ the journal: an append after the file was swapped for a symlink refuses and writes nothing through it (0.862738ms)
|
||||
✔ the journal: a directory it cannot write or create refuses with exit 3 and names the path (0.733768ms)
|
||||
✔ digest content stays within Discord's 2000 characters (0.41042ms)
|
||||
✔ runLoop never overlaps ticks and stops after the one in flight (111.120641ms)
|
||||
✔ shared copy: npm ci, pushed reachability, readonly/existing copy, webui delegation (688.486048ms)
|
||||
✔ wrapper preserves Q81 lease and marker, rejects foreign/symlink; check uses effective roots (536.085067ms)
|
||||
✔ bus unit copy/pm pins, install refuses all busy states and failed reads, drop-in refusal (528.478209ms)
|
||||
✔ missing package manifest refuses before npm; npm failure removes the unpublished temp copy (352.959961ms)
|
||||
✔ real pinned install loads bus and Console; same-copy mosaic talk passes proof, other trees refuse (4098.605397ms)
|
||||
✔ bus status reads effective copy/pm/drop-ins without writes; check refuses an overridden ExecStart (575.976938ms)
|
||||
✔ drop-ins in either override field and malformed metadata refuse; uninstall also checks --no-reload (197.548476ms)
|
||||
✔ install never shows a template name on systemd 261; template drop-ins still refuse (187.50017ms)
|
||||
✔ unlisted instance drop-in is found in another unit lookup directory; path discovery errors refuse (186.052321ms)
|
||||
✔ inherited mosaic-.service.d override refuses without changing the unit (204.842172ms)
|
||||
✔ inherited service.d override refuses without changing the unit (210.536185ms)
|
||||
✔ inherited drop-in unreadable directory or file refuses before writing (169.111231ms)
|
||||
✔ talk --tester sends a [mos test] message as tester from inside an agent and prints the role's reply (40.0176ms)
|
||||
✔ talk --tester refuses text without the [mos test] prefix before any call (19.256361ms)
|
||||
✔ the read verbs take --tester inside an agent, and the trail shows the tester as the sender (29.776371ms)
|
||||
✔ decide, stop and launches take no --tester (20.084843ms)
|
||||
✔ the tester transport runs tester-cli.mjs, and the tester's refusals exit 3 (1.780937ms)
|
||||
✔ with no stand-in transport, --tester runs tester-cli.mjs on the data root's socket (1.377433ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (378.766035ms)
|
||||
✔ the transport writes {business, verb, args} to the child and reads its JSON (56.140433ms)
|
||||
✔ a bus code on stderr becomes the exit code; garbage and timeouts are outcome problems (2264.185677ms)
|
||||
✔ busExit and refuseInsideAgent (0.610863ms)
|
||||
✔ talk sends a REQUEST, prints and reads everything that arrives, and stops at the reply (66.06505ms)
|
||||
✔ talk --wait 0 only sends; no reply within --wait exits 1 and says where it will show (1028.065757ms)
|
||||
✔ a late reply the Console has listed still reaches the next talk (2033.842939ms)
|
||||
✔ talk, stop and launches off/on refuse inside an agent run; bad arguments are usage errors (17.350045ms)
|
||||
✔ launches off and on go to the broker and change the business's launch state (14.66282ms)
|
||||
✔ launches list reads sessions.json and marks a stale entry; stop reports it and refuses a non-runner (14.528604ms)
|
||||
ℹ tests 187
|
||||
ℹ suites 0
|
||||
ℹ pass 187
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14369.811614
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user