agents: Rocko row 138 packets r1, r3-before-152 and r3 (#1632)

Round 3 candidate on 26a0b0fab, manifest digest 75e07b65...47d1, 42
paths, with the runtime.mjs project adapter Sage approved in sage-0488.
Rocko's run: 747 package tests passed, 54/54 mutants killed. Packet
scanned for secrets and binaries, none found.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-15 20:12:17 -05:00
co-authored by Claude Opus 5.5
parent 26a0b0fab4
commit 1e3575be66
140 changed files with 10457 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
# Row 138 revised design — file-backed spec (proposal)
Recorded 2026-10-15 23:07:15 UTC against the section in
`docs/plans/2026-10-15_q167-rows-r3.md`, per sage-0414. Design only.
Implementation waits for Filbert to approve row 147. The superseded worktree
and PAUSED.md stay preserved; no old specs/confirmation tables carry forward.
Row 143 belongs to Researcher and is no longer on Rocko's list.
## Layout and Git reads
Use row 147's declared business/project resolution and separate repository.
The only spec path is `spec/north-star.md`. Proposed meaning of current commit:
the most recent reachable commit that changes that file, rather than HEAD.
A docs/requirements/decisions commit therefore does not invalidate citations.
Read returns bounded UTF-8 content at a validated full commit ID, its file
commit, and a bounded log for that path. Reject revisions outside the local
repository's reachable history and paths outside this fixed path. Reads invoke
no shell, network, filters, hooks or caller-supplied Git options. They use the
same sanitized Git and repository checks as row 147.
A human-authored file commit is confirmation. Check the author against the
business's human and the local identity convention used by init; this records
local provenance, not a cryptographic identity claim. An agent-authored latest
spec change must not silently fall back to an older human version. Refuse a
citation until the spec has a valid human confirmation. Reads may expose
committed history for diagnosis without granting a write. Dirty working bytes
are never returned as confirmed content.
This needs a shared read helper in packages/project, beside its writer, to avoid
copying repository/Git validation into the broker. That path is not explicitly
in row 138's Files owned list: ask Sage for the small scope addition before code.
Coordinate this helper with row 148's human read/save API.
## Bus and tools
Add nullable spec_path and spec_commit to decisions, preserving old uncited
raises. A cited raise requires project, the exact fixed path, and the current
human-confirmed file commit. Require both citation fields together. Resolve and
validate before any decision/event insert. Store exactly that path and full
commit. Existing classification, routing, resolution and authorization stay as
they are; row 139 changes routing later. A later spec commit never changes old
rows or resolution events.
Any authenticated role instance may read the spec for a project declared in its
own business, at current or requested historical commit, with its path log.
The record-write action is separate: add its vocabulary entry and only the
brief-approved role grants. Bind author definition/instance from the broker's
session, never request fields. Pass the validated record to row 147 writeRecord.
No spec-write verb, propose/confirm action, shell tool or alternate writer is
added. The harness strict schemas expose spec read, record write, and optional
paired citation fields on raise_decision. Agent writes to spec must refuse in
the package, broker and harness paths.
## Migration and evidence
The 3e to 3f step adds only the two nullable decision columns. No spec tables.
Use the existing ordered migration mechanism, a schema-3e fixture built from
the repository, and preservation assertions covering every existing table and
row. Keep the future-version chaining test. MIGRATION.md gives Mos the exact
backup, offline migration, validation, re-pin and rollback procedure; no seat
reads or migrates the live store.
Acceptance checks each get a mutant: current citation stored; stale/nonhuman/
missing confirmation refused; no-spec raise unchanged; settled decision survives
a spec edit; docs-only commit leaves current spec commit unchanged; read content
and path log at current/historical commits; business/project/path isolation;
bound author on record commit; each exposed spec-write path refused; migration
preservation and chaining. The revised brief requires bus, business, harness,
cli and all scripts/test-*.sh; include project suite if the helper is approved.
Ask for the shared slot before suites or mutants. No schema/live step until
147 is done, review is approved, and Mos runs the separate window.
## Shared reader API — sage-0419
Scope addition approved by Sage in sage-0419, at Rocko's request: reader and
fixture tests in packages/project share row 147 repository validation. Record
that approval in BUILD.md when the build begins. The API below is the proposed
exported contract for Researcher's row 148; no implementation has started.
Exports from packages/project/src/index.mjs (both async):
```js
readProjectFile({ business, project, dataRoot, path, commit })
readSpec({ business, project, dataRoot, commit })
```
Context is exactly row 147's context. `path` accepts only
`spec/north-star.md` or `docs/<name>.md`, with the same canonical single-file
Markdown name grammar as writeRecord; no traversal, absolute paths or extra
keys. `commit` is optional. Omission selects a snapshot of HEAD. A supplied
commit is a full lowercase 40-character Git SHA-1 naming a commit reachable
from that HEAD, never an arbitrary revision expression. Capture HEAD once and
use that snapshot for every subsequent Git read in the call.
readProjectFile returns:
```js
{
repo, // resolved absolute path
path, // validated repository-relative path
head, // captured HEAD commit
revision, // requested commit, or head
commit, // last commit changing path at revision
content, // exact bounded UTF-8 blob bytes decoded, trailing LF kept
author, // { name, email } from that file commit
log, // newest first, at most 100 path-changing commits
truncated // true if more than 100 entries exist
}
// Each log entry: { commit, author: { name, email }, at, subject }
// at is the author timestamp rendered as canonical UTC ISO text.
```
The log is for this path through revision, following its fixed name (no rename
following), not all repository commits. Messages/identities are data, never Git
arguments. Content is at revision, and commit names its last change. The file
must be a regular Git blob, not a symlink/submodule, with at most 1 MiB, valid
UTF-8 and no NUL. No trimming of content. Repository identity in committed
project.json must match the requested business/project. Reject unsafe local
metadata/remotes using row 147's checks. Reads do not require a clean working
tree: they ignore uncommitted bytes, allowing the editor to load the last
committed version without silently treating pending edits as confirmation.
readSpec fixes path to spec/north-star.md and returns all fields above plus
`confirmed: boolean`, true exactly when author.name equals business.human.
It returns history even when false, so diagnosis is possible. The broker must
refuse a cited raise with false; it must compare the citation against a fresh
current readSpec call, not trust a caller's historical read. A direct read of an
older confirmed commit does not make it current. Existing settled decisions
keep their recorded commit and are never rewritten.
Failures throw ProjectError with a stable .code; messages are explanatory only:
| Code | Meaning |
| --- | --- |
| project-id | Invalid context ID. |
| project-path | Invalid repository root, overlap, or linked ancestor. |
| project-not-declared | Project absent from this business. |
| project-repository | Unsafe/missing Git metadata. |
| project-remote | Repository has a remote. |
| project-invalid | Committed project identity/layout metadata invalid. |
| project-read-path | Missing/invalid path or unsupported argument keys. |
| project-read-commit | Malformed, missing, non-commit or unreachable revision. |
| project-read-missing | Path absent at the selected revision. |
| project-read-content | Nonregular blob, oversized, invalid UTF-8 or NUL. |
| project-git | Bounded local Git invocation otherwise failed. |
Missing-spec or nonhuman confirmation refusal for decision.raise is a broker
policy error, separate from the reader's diagnostic result. Neither helper
writes a file, lock, index, config or commit. Row 148's save writer must still
check its stale base under its write lock; a successful earlier read cannot
substitute for that check. Row 138 adds no human or agent spec writer.
+37
View File
@@ -0,0 +1,37 @@
# Row 138 paused — sage-0390, 2026-10-15 22:25:32Z
Stopped immediately for Jason's revised Q167 design. Row 143 is also held.
No full suite, gate, mutant batch, live step, commit or push was run for this
candidate. Focused test commands completed before the stop; no runner remains.
Preserved worktree: `/mnt/storage/src/mosaic-stack-rocko-138`, detached at
`e37d6e583`. Claim rev1373 remains in-progress pending Sage's revised brief.
All candidate source is uncommitted. Existing logs are in `queue-138/r1/`.
Built under the superseded brief:
- Append-only `specs` and `spec_confirmations`, nullable decision spec_id /
spec_version fields, and a 3e→3f migration step with source 3e fixture DDL.
- Broker spec.propose (assistant definition plus within-role grant), human-only
spec.confirm, current confirmed spec reads, and exact current-version citation
checks. No-spec raises remain valid; resolution/routing remain unchanged.
- Assistant spec.propose vocabulary/grant and contract text.
- Human CLI spec read / exact-version confirmation, outside-run transport, and
scripts/mosaic dispatch. Typed propose_spec/read_spec and optional citation
fields in raise_decision, per scope extension sage-0386.
- Focused broker, CLI, harness and business tests; existing migration tests
updated to follow the current version and retain the future-version chain.
Likely reusable, subject to the new brief: negative tests for no-spec raises,
invalid/stale citations, business isolation, human authority, unchanged decision
resolution and settled-decision persistence; CLI transport/refusal patterns and
strict typed citation schemas. These tests currently use the old table/version
model and will need new path/commit fixtures and assertions.
Not assumed reusable: the two new tables, version/confirmation verbs, role grant,
3e→3f DDL, table-specific tests and assistant contract wording. Nothing from this
candidate is landed or used live. Do not run its migration.
New direction recorded only, not implemented: a Markdown spec in the project,
kept in git; Jason edits it directly, each save is a local commit, his commit is
confirmation, and decisions record the spec path and commit. Await revised scope
before changing code or starting row143.
@@ -0,0 +1,18 @@
✔ the role file loads and resolves through loadBusiness (5.711615ms)
✔ the shipped file is exactly the approved list (0.68977ms)
✔ the assistant holds only message.send and spec.propose within role (1.680218ms)
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.572705ms)
✔ a business grant through limits does not widen the role (1.394964ms)
✔ a launch block whose by is the assistant is refused (1.456847ms)
✔ the instance takes no credential references and no tracker (2.195976ms)
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (3.609965ms)
✔ an arbiter without messaging lists is accepted beside the limited assistant (2.700844ms)
✔ the contract passes work to the chief of staff and directs no one (0.916963ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 83.826588
@@ -0,0 +1,13 @@
✔ explicit 3b copy migration preserves evidence and opens as 3e; normal startup never migrates (51.901503ms)
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (71.128612ms)
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (59.418223ms)
✔ migration refuses mismatched source metadata without changing schema or evidence (32.97925ms)
✔ offline command migrates only the supplied fixture root and reports usage errors (153.21709ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 436.382373
@@ -0,0 +1,11 @@
✔ spec read and exact-version confirmation use the existing human transport (2.418377ms)
✔ spec confirmation refuses agents, tester flags, malformed versions and unattended confirmation (2.051085ms)
✔ scripts/mosaic dispatches spec to the human CLI rather than the seat CLI (72.833996ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 166.369892
@@ -0,0 +1,13 @@
✔ assistant proposes immutable versions, human confirms, roles read only confirmed current text (25.231458ms)
✔ proposal requires assistant definition, current holder and within-role grant; confirmation requires human proof (37.025538ms)
✔ needs map to one spec per business; confirmations advance and cannot leak across businesses (28.136703ms)
✔ no-spec raises keep their route; pending/stale citations refuse, settled old decisions remain closed (26.348206ms)
✔ spec verbs and citations reject malformed keys, versions and oversized text without publication (25.26877ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 195.541464
@@ -0,0 +1,25 @@
✔ the PM gets its task verbs and the reads, and no launch (6.794233ms)
✔ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.113111ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (2.408694ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.130631ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (8.159211ms)
✔ the assistant gets send_message and the reads, no launch (1.411972ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (2.219633ms)
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (1.026512ms)
✔ a coder with a tracker gets its own task tools and no task_reassign (0.929196ms)
✔ launch only when the business's launch block names the instance as launcher (1.91002ms)
✔ an action outside the instance's authority has no tool (1.439962ms)
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (3.488208ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (8.384254ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (2.487427ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.322393ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.751119ms)
✔ spec proposal is grant-bound, spec read is universal and raises accept exact spec citations (6.624366ms)
ℹ tests 17
ℹ suites 0
ℹ pass 17
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 137.849662
@@ -0,0 +1,62 @@
✖ spec read and exact-version confirmation use the existing human transport (1.659329ms)
✔ spec confirmation refuses agents, tester flags, malformed versions and unattended confirmation (1.979476ms)
✖ scripts/mosaic dispatches spec to the human CLI rather than the seat CLI (29.167443ms)
ℹ tests 3
ℹ suites 0
ℹ pass 1
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 128.097348
✖ failing tests:
test at packages/cli/tests/spec.test.mjs:16:1
✖ spec read and exact-version confirmation use the existing human transport (1.659329ms)
Error [CliError]: usage:
mosaic limits [--business ID] [--json] | set --file PATCH [--business ID] | migrate --file ORGANIZATION --models MAPPING [--roles-dir DIR]
mosaic inbox [--business <id>] [--json] [--tester]
mosaic decide <decision> <option> [--note <text>] [--yes] [--business <id>]
mosaic tasks [--business <id>] [--json] [--tester]
mosaic agents [--business <id>] [--json] [--tester]
mosaic trail <task|decision> [--business <id>] [--json] [--tester]
mosaic talk <role> <text> [--wait <seconds> | --follow] [--business <id>] [--tester]
mosaic follow [--business <id>] [--tester]
mosaic stop <run>
mosaic launches off|on [--business <id>]
mosaic launches list [--json]
mosaic bus start <business> [--pm]
mosaic bus stop
mosaic bus status [--json]
at usage (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/cli/src/cli.mjs:50:24)
at main (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/cli/src/cli.mjs:391:9)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/cli/tests/spec.test.mjs:19:9)
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: 4
}
test at packages/cli/tests/spec.test.mjs:43:1
✖ scripts/mosaic dispatches spec to the human CLI rather than the seat CLI (29.167443ms)
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /mosaic spec/. Input:
'refused: usage: mosaic launch <seat|seat-dir> [--task TEXT] [--project NAME] [--workspace PATH] [--harness NAME] [--repo PATH] [--config PATH] [-- args...]\n' +
' mosaic seat task <seat> <text> [--by NAME] [--layout repo|fleet|unknown] [--config PATH]\n'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/cli/tests/spec.test.mjs:48: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: 'refused: usage: mosaic launch <seat|seat-dir> [--task TEXT] [--project NAME] [--workspace PATH] [--harness NAME] [--repo PATH] [--config PATH] [-- args...]\n mosaic seat task <seat> <text> [--by NAME] [--layout repo|fleet|unknown] [--config PATH]\n',
expected: /mosaic spec/,
operator: 'match',
diff: 'simple'
}
@@ -0,0 +1,93 @@
✖ assistant proposes immutable versions, human confirms, roles read only confirmed current text (8.835896ms)
✖ proposal requires assistant definition, current holder and within-role grant; confirmation requires human proof (5.635513ms)
✖ needs map to one spec per business; confirmations advance and cannot leak across businesses (5.535498ms)
✖ no-spec raises keep their route; pending/stale citations refuse, settled old decisions remain closed (5.510388ms)
✖ spec verbs and citations reject malformed keys, versions and oversized text without publication (5.629215ms)
ℹ tests 5
ℹ suites 0
ℹ pass 0
ℹ fail 5
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 99.536984
✖ failing tests:
test at packages/bus/tests/specs.test.mjs:45:1
✖ assistant proposes immutable versions, human confirms, roles read only confirmed current text (8.835896ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:78:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:166:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:22:13)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:46:45)
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) {
code: 'invalid-authority'
}
test at packages/bus/tests/specs.test.mjs:66:1
✖ proposal requires assistant definition, current holder and within-role grant; confirmation requires human proof (5.635513ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:78:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:166:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:22:13)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:67: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 startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
code: 'invalid-authority'
}
test at packages/bus/tests/specs.test.mjs:81:1
✖ needs map to one spec per business; confirmations advance and cannot leak across businesses (5.535498ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:78:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:166:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:22:13)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:82: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) {
code: 'invalid-authority'
}
test at packages/bus/tests/specs.test.mjs:95:1
✖ no-spec raises keep their route; pending/stale citations refuse, settled old decisions remain closed (5.510388ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:78:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:166:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:22:13)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:96:52)
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) {
code: 'invalid-authority'
}
test at packages/bus/tests/specs.test.mjs:117:1
✖ spec verbs and citations reject malformed keys, versions and oversized text without publication (5.629215ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:78:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/src/broker.mjs:166:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:22:13)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/bus/tests/specs.test.mjs:118:52)
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) {
code: 'invalid-authority'
}
@@ -0,0 +1,68 @@
✔ the PM gets its task verbs and the reads, and no launch (5.514913ms)
✔ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (1.522759ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (1.829326ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.101613ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (5.542362ms)
✖ the assistant gets send_message and the reads, no launch (1.909622ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.864248ms)
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.908615ms)
✔ a coder with a tracker gets its own task tools and no task_reassign (0.770874ms)
✔ launch only when the business's launch block names the instance as launcher (1.556452ms)
✔ an action outside the instance's authority has no tool (1.162425ms)
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (2.766877ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (7.433735ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (2.033033ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (1.918467ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.617302ms)
✖ spec proposal is grant-bound, spec read is universal and raises accept exact spec citations (0.99624ms)
ℹ tests 17
ℹ suites 0
ℹ pass 15
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 105.02284
✖ failing tests:
test at packages/harness/tests/tools.test.mjs:82:1
✖ the assistant gets send_message and the reads, no launch (1.909622ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ [
+ 'spec.propose'
+ ]
- []
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/harness/tests/tools.test.mjs:87: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: [ 'spec.propose' ],
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:249:1
✖ spec proposal is grant-bound, spec read is universal and raises accept exact spec citations (0.99624ms)
Error [BusinessError]: business acme declares no role instance "assistant"
at refuse (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/business/src/errors.mjs:12:9)
at resolveInstance (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/business/src/resolve.mjs:35:15)
at resolvedFor (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/harness/tests/helpers.mjs:28:10)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138/packages/harness/tests/tools.test.mjs:250: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)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
exitCode: 2
}
@@ -0,0 +1,113 @@
# Row 138 / #1632: file-backed north-star specs
This is the revised r3 brief's first build candidate, not the superseded
spec-table candidate in ../r1. Base 56639c99b, detached worktree:
/mnt/storage/src/mosaic-stack-rocko-138-r3. Reviewer Dewey, gate owner Sage.
Old worktree and PAUSED.md are preserved. Completed row 153's worktree was
verified against its packet and removed as Sage authorized in sage-0478.
## Behavior and boundaries
The spec is spec/north-star.md in row 147's separate project repository. The
shared project reader returns exact committed UTF-8 (BOM/trailing bytes kept),
the last reachable commit changing the file, author and bounded path log.
Historical full SHA-1 commits must be reachable from a captured HEAD; dirty
working bytes are ignored. A docs-only commit never stales a citation. The
committed project.json identity, paths, Git metadata/remotes, regular blob mode,
1 MiB content bound, UTF-8 and NUL constraints are checked. Log output is bounded
to 256 KiB and 100 entries, with truncation explicit. Blob reads use a bounded
raw-byte Git runner sharing sanitized Git options/environment and group timeout
cleanup, because the existing text runner trims output and replaces invalid
UTF-8, which cannot preserve this contract.
readSpec.confirmed is true exactly when the file commit's author.name equals
business.human. A latest agent-authored file stays unconfirmed; no fallback.
This is local provenance, not a cryptographic identity proof. Exported APIs and
refusal codes match ../DESIGN-r3.md and are documented in the package README;
row 148 uses the same reader and adds its own locked stale-base human writer.
A cited decision.raise requires project and paired exact spec_path/spec_commit.
The broker reads the current snapshot, refuses invalid/stale/unconfirmed
citations and stores both fields. Existing uncited raises retain their sync
path and existing validity/routing/resolution rules. No new spec commit changes
old decisions or resolution events. No spec table or propose/confirm verb ships.
record.write author is derived only from the bound session's definition and
instance. Caller identity keys refuse. Authority is checked before the filesystem
effect; package validation and exclusive repository writer lock apply. spec/
refuses through package, broker and typed tool. Concurrent requests to one repo
return one commit and one project-busy, not a Git index race. Commit/receipt are
two effects; a commit whose SQL authority receipt cannot be recorded refuses
outcome-unknown for inspection, never automatic retry. This row adds no human
writer, shell escape, config edit, Console route or spec confirmation action.
The existing wire request limit remains 64 KiB; package file bound is 1 MiB.
read_spec is offered to every role. write_record follows the record.write grant.
raise_decision's strict schema accepts optional project and paired citations;
the broker enforces pairing and freshness. Eleven current roleVersion 2 files
have the within-role grant; legacy researcher v1 and conductor-policy do not
change (Sage count correction sage-0482).
## Scope additions and rulings
- sage-0419, at Rocko's request with Sage's agreement: packages/project shared
reader and fixture tests, beside row 147's writer, sharing repository checks.
The names, arguments, return shapes and refusal codes were written before
code in ../DESIGN-r3.md for Researcher's row 148.
- sage-0480, at Rocko's request: packages/bus/src/server.mjs, only awaiting
spec.read, record.write and spec-citing decision.raise. All other sync paths
are unchanged byte for byte. Async rejections preserve their refusal envelope
and code; transient proofs live until completion. Late replies/refusals after
disconnect do not write a dead socket. Real socket tests cover all three
verbs, own refusal codes/transient cleanup, late success/failure, continued
server usability and two concurrent writes with project-busy.
- sage-0480 and sage-0482: record.write belongs within-role for all eleven v2
definitions. The earlier count of twelve was mistaken; researcher is v1.
## Schema and migration
3e to 3f adds only decisions.spec_path and decisions.spec_commit, nullable, using
an appended named step. Fresh and migrated schema digests match. The 3e fixture
is copied from the tree at this base, never from a live store. The test seeds
every evidence table and compares every old column/row, plus an untouched copy.
Older chain tests follow the current version and retain their pinned old DDL;
the future-version fixture still chains, now to 3g. MIGRATION.md contains exact
DDL, hashes and Mos's approved stopped-bus backup/migrate/re-pin/rollback plan.
No seat reads/migrates the live store or controls any unit.
## Focused evidence and planned gate
Only singly invoked node --test FILE checks have run. No suite, browser,
Docker, sandbox, shell suite or mutant batch. Reader 7; spec migration 1; broker
spec 4; real socket 5; harness spec tools 2; grant contract 1. Existing focused
files: comment migration 5, thread migration 3, bus chief 13, harness tools 18,
business chief 10, business core 16, resolve 10. All pass, no skips. Red logs
capture absent reader/migration/broker/tools/server and BOM normalization before
their implementations. Existing tool-name lists and chief authority contract
were updated to preserve their prior intent while including the approved tools.
51 mutants are prepared and exact-once sites preflighted only. They cover the
reader, citation rules, bound authors, spec refusal, authority/receipts, async
socket behavior, concurrent writer lock, typed tools, migration preservation
and chaining, and each of the eleven grants. Timeout/syntax/import failure is
not a kill. Whole groups and detached Git descendants are killed on timeout;
every original file restores in finally. Run only after Sage's explicit grant.
Required package gate: project, bus, business, harness and cli. The revised
brief requires every scripts/test-*.sh: auth, conductor, config, discord,
extension-package, foundation, land-work, queue, release and task. Their current
list was obtained with rg --files scripts, not inferred from prior gate counts.
Sage owns the landing gate. DOCKER_HOST is a dead socket by default; any Docker
run requires the shared slot and the task/release Docker cases must not be
silently skipped. One recurrence of #258/#261/#262/#263 is a note; two of the
same flake in a gate stop and are reported. Slot request and final results are
pending. No review-ready, gate or mutant success claim yet.
### Slot boundary — sage-0485
Sage is gating/pushing row 152 first. Wait for the explicit clock-stamped grant;
a CLEAR process probe alone does not authorize a run. Authorized future batch:
51 mutants plus project, bus, business, harness and cli suites only. No Docker,
browser or shell suite; Sage's landing gate runs every shell suite. Check base
drift after row 152 is pushed before the granted runs. Clean base+patch
reconstruction already verifies all 37 current candidate paths on 56639c99b.
@@ -0,0 +1,84 @@
# Row 138: offline schema 3e to 3f window
Only Mos runs the live steps, with Jason's approved downtime/re-pin window.
Development seats run this command against disposable fixture copies only.
Nothing in this packet authorizes a seat to read the live store, stop/start a
unit, migrate a live file, or re-pin a copy.
## Exact change
Source schema 3e is packages/bus/tests/fixtures/schema-3e.sql, copied from
56639c99b's repository tree, SHA-256:
21e6c091f14f818396f4d7836f381cc1389d45b2680ecaa1a00646b652c45050.
Target schema is 3f, source SHA-256:
472cbcd0d4548848873f3029e8250dc07bba4fb8db2a93241aae5b8e7e3771e2.
The new ordered step is packages/bus/src/migrations/3e-3f.sql:
```sql
ALTER TABLE decisions ADD COLUMN spec_path TEXT;
ALTER TABLE decisions ADD COLUMN spec_commit TEXT;
```
Both columns are nullable. Existing decisions get nulls; existing events,
settlements and every other row/old column stay unchanged. There are no specs
or spec_confirmations tables. Each completed named step commits separately;
prior migration steps and future-version chaining remain supported. Normal
startup refuses 3e under the new copy; it never auto-migrates.
## Mos's procedure, before and inside the window
1. Before stopping anything, prepare the approved pinned code copy and verify
its candidate/source manifests and migration command. Identify the existing
pinned copy for rollback. This packet does not switch any live pointer.
2. In Mos's approved window, make the PM run idle and stop all users of the bus
and the bus itself using the window's existing service procedure. Confirm no
writer remains. Do not migrate while the bus or another writer is running.
3. Make a consistent, owner-only backup of the stopped data root's entire bus
directory, including any SQLite WAL/SHM files. Keep the prior pinned code
copy and its launch/service settings with the backup receipt. Record time,
backup paths and hashes without printing message content. Do not delete an
unexplained writer.lock; diagnose it under the existing stale-lock procedure.
4. On a disposable copy of that backup, run the approved new copy's command
below and validate normal opening/quick_check/foreign_key_check. A refusal
stops the window for diagnosis. Never improvise around schema/digest checks.
5. With the live bus still stopped and the original backup preserved, Mos runs:
```sh
node <approved-copy>/packages/bus/src/migrate-schema.mjs <absolute-dataRoot>
```
It must exit 0 and end with `bus schema 3f ready`. The exclusive writer lock,
source schema/digest, timestamps, WAL and integrity checks must all pass.
Only the same stopped source proven in step 4 is used.
6. Mos follows the approved re-pin/start procedure for the new copy and checks
the stack-copy/runtime proof and normal reads. No spec or organization file
edit is required for this schema step; project init is a separate human
operation. Human spec commits confirm the spec; uncited existing raises work.
7. Record the backup, code copy, command exit, readiness checks and any downtime.
Existing settled decisions remain settled. Hold unrelated row migrations
until their own reviewed window plan says they may run.
## Refusal and rollback
A failed step rolls its transaction back; earlier completed named steps remain
valid. Preserve evidence and diagnose instead of retrying blindly. Rerunning an
already-current 3f store validates it without changing evidence.
If Mos chooses rollback, stop every new-copy reader/writer first, preserve a
consistent copy of the post-attempt bus directory for reconciliation, restore
the complete pre-window bus backup with its original permissions and WAL/SHM
state, and restore the prior pinned copy and launch settings together. Old 3e
code must never open the upgraded 3f file. Do not strip columns or edit evidence
in place. If any new messages/decisions were recorded after start, rollback
would discard them from the active store: Mos/Jason must resolve that data
boundary before proceeding; keep the post-attempt copy intact.
## Fixture evidence
spec-migration.test.mjs builds a 3e database from the pinned tree DDL, populates
every evidence table, keeps an untouched copy, checks normal startup refuses,
migrates, and compares every old table/column/row and sequence counter. Only
schema_version/schema_digest values and the two added null columns differ.
Integrity and normal 3f reopening pass. Existing 3b/3c/3d migration tests remain,
and the future fixture now chains through 3f to a fixture-only 3g.
@@ -0,0 +1 @@
56639c99b03ddca8f5fa84826b19322cd09a713e
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (23.299455ms)
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (21.755576ms)
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (18.284545ms)
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (16.18574ms)
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (18.09891ms)
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (19.134945ms)
✔ REQ-COS-1: the chief of staff cannot end its own run or the assistant's through role.end (18.875751ms)
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (14.419152ms)
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (19.934864ms)
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (19.817717ms)
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (23.638175ms)
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (48.888848ms)
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (50.287517ms)
ℹ tests 13
ℹ suites 0
ℹ pass 13
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 399.070837
@@ -0,0 +1,24 @@
✔ config directory and file path follow MOSAIC_CONFIG (1.041858ms)
✔ the fixture business validates and comes back frozen (3.451636ms)
✔ two instances may share a definition (1.094883ms)
✔ top-level refusals (2.871191ms)
✔ arbiters and projects (4.205919ms)
✔ role instances (2.039439ms)
✔ Vikunja bots (4.690039ms)
✔ a role without Vikunja takes no tracker block (1.774192ms)
✔ credential references match the definition's services (1.902936ms)
✔ launch (6.201564ms)
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (3.541192ms)
✔ loadBusiness: file checks (1.488956ms)
✔ loadBusiness: not a regular file (37.211304ms)
✔ loading writes nothing (1.020932ms)
✔ names that are Object.prototype properties don't count as declared (2.530155ms)
✔ the shipped example refuses as written and validates once filled in (0.727335ms)
ℹ tests 16
ℹ suites 0
ℹ pass 16
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 129.585359
@@ -0,0 +1,18 @@
✔ the role file loads and resolves through loadBusiness (4.889292ms)
✔ the shipped file is exactly the approved list (0.180316ms)
✔ the resolved record matches the approved list, so a widened file fails (1.205872ms)
✔ the chief of staff holds role.launch, message.send, role.end and organization.change; every other action is gated (1.022328ms)
✔ the pm does not hold role.launch (1.111834ms)
✔ a business grant of a gated action through limits does not widen the role (1.278493ms)
✔ a limit that drops role.launch leaves the chief of staff with no launch block (0.759263ms)
✔ a launch block whose by is the pm instance is refused (1.091254ms)
✔ the contract names no duty to talk to the human and the pm contract no launch (0.270865ms)
✔ the instance takes no credential references and no tracker (1.567165ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 67.492254
@@ -0,0 +1,18 @@
✔ systemVars flattens the validated config (1.329251ms)
✔ precedence: system, business, project, project role, agent (3.978643ms)
✔ limits narrow the definition and never widen it (1.642735ms)
✔ role.launch stays within-role only for the instance the launch block names (3.989532ms)
✔ limits.authority without role.launch leaves the launcher with no launch block (1.553313ms)
✔ limits.authority narrows cross-role actions too (0.873042ms)
✔ classify (0.893281ms)
✔ the record carries what the broker and launcher need (0.860897ms)
✔ digest: key order doesn't matter, any value change does (7.984664ms)
✔ refusals (1.554462ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 74.048715
@@ -0,0 +1,37 @@
f3d44384701ca83fd6704002f24eab41734538709ce2df7ee531818da27847c4 packages/bus/README.md
472cbcd0d4548848873f3029e8250dc07bba4fb8db2a93241aae5b8e7e3771e2 packages/bus/schema.sql
29ea1b2ac38c944e5464d9e2c1fda45b800a00bb9c8e3da35ca6628fdef307eb packages/bus/src/broker.mjs
bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3 packages/bus/src/migrations/3e-3f.sql
eef4be8ec386c5ed0ef49bcec7416b06b89e659016e4a3d21cc71b1ec6547c6d packages/bus/src/server.mjs
de51a1a5cd857fd143f19c599947c30615f6c2a14a99eb503d9a37dccef43ef2 packages/bus/src/store.mjs
5a6ff816b7a921af365a32a286cd66801d5310a31af7ae83dc083e8e807e4c07 packages/bus/tests/chief-of-staff.test.mjs
0495d15e8b2cb145b1db0d0468a967f7ee5275af6f0736f31b978714269ed926 packages/bus/tests/comment-migration.test.mjs
21e6c091f14f818396f4d7836f381cc1389d45b2680ecaa1a00646b652c45050 packages/bus/tests/fixtures/schema-3e.sql
38ad58cd14efd41254a830c320ce65cf77893e32f4cbacc2b3e9af0f9e65995f packages/bus/tests/spec-fixtures.mjs
70a86e4ba863793403201f3c89d1e2f33d49fb20dc7407e60e7e66d8462e59e6 packages/bus/tests/spec-migration.test.mjs
40bf5599fc87c56cc1d4c50d5ac18401c7264be14388e79c74a03e2ad6bfc067 packages/bus/tests/spec-socket.test.mjs
acd888e2e5eb9fdbe1436d5e29b309e7f9bbf8b623ec576a0f733eecb4119031 packages/bus/tests/spec.test.mjs
ac3b5131de1d8384d999af4b8f8ec4021725b6ba402ac0a3cfc691139ec4ee59 packages/bus/tests/thread-migration.test.mjs
3b32890ebe5b5d7aa31e0976159c7cd014c08664fbea830459ef4028ca0fd038 packages/business/src/vocabulary.mjs
12b468ff1c3473e77a0adcb4a5578662a1840b8a5b049f36e82d5ba8585d4a5b packages/business/tests/chief-of-staff.test.mjs
8652806dbba42e554b67e7c67150fb04e85b46eac50705abf53efb216b79c5ca packages/business/tests/record-grants.test.mjs
78490210a60321754b20fc2d1b0730162df6c25e596019e8746a8061a35948a5 packages/harness/README.md
290ca7336d2f70c26846f0561ae3447b898c94760cb6c62615b70bf76586aca2 packages/harness/src/tools.mjs
56196834173d1f684bee7bc8a5929b8bcb234acd06f04b2ade51ab52bbe066f1 packages/harness/tests/spec-tools.test.mjs
9e0751927d378b51c35fa68613c5f3a6f26a4ee024ddd2e2398004b93624595f packages/harness/tests/tools.test.mjs
3c34eae08653cd40cc34d342cb1572cfbca0cba78ad37f73a3e90046a4251585 packages/project/README.md
d0041915939a1e72285295bead3137911f24a2ebacb794de9382dda47293584e packages/project/src/git.mjs
81bd630bddf0c650be72fe6863d5736dcec09d404f891fcb2e62a0e8f13dcb24 packages/project/src/index.mjs
f1e5f77adc8cd66dcf36e0f46db15416bca0c58ed1e7ab19c49a8f2e407be7a4 packages/project/src/read.mjs
791fa559241828cb9bb098e69d76f4e4c601c7d469a7aeff78ef582c17fbcac8 packages/project/tests/read.test.mjs
5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7 roles/assistant.json
314074c8081953923f962f2df045d4c14629010ea99d1f23449ed45294b46bcc roles/chief-executive-officer.json
539d531a0f5744aebb933ca685b52022554e3e93ae54cc8b67e4de0eb27d3460 roles/chief-financial-officer.json
8ee8e7213d4c073e2d9ba7732fd84b3b3130d9bbb930d07595b7f692bb9fc5dc roles/chief-information-officer.json
a550428603979f4342e57ad9ccddd4d2e44a5203a64f19027ce09a24f1dbfc0e roles/chief-information-security-officer.json
3cdd799159d3e676529efee01f467a4ed7d67920253cddba2e098566368a1e36 roles/chief-marketing-officer.json
d5765eb50ea3cf4cf2a1688892005d38826e84bb142aabc56bd8e17defa82a9e roles/chief-of-staff.json
c314058bb989333143f09b1cec74b87cb10ae78a7dc10afc998edfe510169560 roles/coder.json
895ffb0b5b2c57c3a699d2494a3dff8f844ada25970762e0d87509c786fc3f87 roles/cto.json
77d9682da3a04146b53b2a9ecdb00a4442a6e07661d25abe6e336ea34609772c roles/pm.json
0a432e25a6aa339533064594c323a4a4cef22070a383849227c2f568f71538bc roles/reviewer.json
@@ -0,0 +1,275 @@
✖ the PM gets its task verbs and the reads, and no launch (6.771468ms)
✖ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.250286ms)
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (7.316382ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (1.242897ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.090135ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (5.087481ms)
✖ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (1.006576ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.635595ms)
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.869549ms)
✖ a coder with a tracker gets its own task tools and no task_reassign (0.922462ms)
✔ launch only when the business's launch block names the instance as launcher (1.529053ms)
✖ an action outside the instance's authority has no tool (0.991289ms)
✖ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (1.045234ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (9.60071ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.806843ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (1.833478ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.453321ms)
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (1.988839ms)
ℹ tests 18
ℹ suites 0
ℹ pass 11
ℹ fail 7
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 119.448179
✖ failing tests:
test at packages/harness/tests/tools.test.mjs:9:1
✖ the PM gets its task verbs and the reads, and no launch (6.771468ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines
[
'send_message',
'request_staff',
'task_create',
'task_assign',
...
'task_close',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'resolve_decision',
'list_agents',
'inbox',
'trail',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:12:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [
'send_message', 'request_staff',
'task_create', 'task_assign',
'task_reassign', 'task_schedule',
'task_priority_change', 'task_scope_change',
'task_update_assigned', 'task_close',
'read_spec', 'write_record',
'raise_decision', 'resolve_decision',
'list_agents', 'inbox',
'trail', 'list_tasks',
'get_task', 'list_requirements'
],
expected: [
'send_message', 'request_staff',
'task_create', 'task_assign',
'task_reassign', 'task_schedule',
'task_priority_change', 'task_scope_change',
'task_update_assigned', 'task_close',
'raise_decision', 'resolve_decision',
'list_agents', 'inbox',
'trail', 'list_tasks',
'get_task', 'list_requirements'
],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:33:1
✖ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.250286ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'launch',
'end_run',
'change_organization',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:36: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: [ 'send_message', 'launch', 'end_run', 'change_organization', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'launch', 'end_run', 'change_organization', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:110:1
✖ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (1.006576ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'web_search',
'web_fetch',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.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: [ 'send_message', 'web_search', 'web_fetch', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'web_search', 'web_fetch', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:144:1
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.869549ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail'
]
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:147: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: [ 'send_message', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail' ],
expected: [ 'send_message', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:153:1
✖ a coder with a tracker gets its own task tools and no task_reassign (0.922462ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'task_scope_change',
'task_update_assigned',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:155: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: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:168:1
✖ an action outside the instance's authority has no tool (0.991289ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'request_review',
+ 'read_spec',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:170: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: [ 'request_review', 'read_spec', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:174: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.045234ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'task_scope_change',
'task_update_assigned',
'push_working',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:177: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: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'push_working', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'push_working', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,26 @@
✔ the PM gets its task verbs and the reads, and no launch (5.952717ms)
✔ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.062539ms)
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (7.127672ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (1.265174ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.083198ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (5.089895ms)
✔ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (0.840647ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.562099ms)
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.766939ms)
✔ a coder with a tracker gets its own task tools and no task_reassign (0.794408ms)
✔ launch only when the business's launch block names the instance as launcher (1.458379ms)
✔ an action outside the instance's authority has no tool (0.821668ms)
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (3.303109ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (7.841259ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.984775ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.187672ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.541918ms)
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (2.331519ms)
ℹ tests 18
ℹ suites 0
ℹ pass 18
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 114.813846
@@ -0,0 +1,9 @@
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (2.2084ms)
ℹ tests 1
ℹ suites 0
ℹ pass 1
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 53.649613
@@ -0,0 +1,12 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (94.302279ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (87.195651ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (37.300488ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (40.068752ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 310.422428
@@ -0,0 +1,13 @@
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (44.797845ms)
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (63.015363ms)
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (48.195716ms)
✔ migration refuses mismatched source metadata without changing schema or evidence (32.217971ms)
✔ offline command migrates only the supplied fixture root and reports usage errors (115.900551ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 356.813643
@@ -0,0 +1,9 @@
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (66.701474ms)
ℹ tests 1
ℹ suites 0
ℹ pass 1
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 120.991752
@@ -0,0 +1,15 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (62.748618ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.360915ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (55.153761ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (98.755688ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (27.560482ms)
✔ path history is bounded at 100 and explicitly marks truncation (681.120229ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (31.150921ms)
ℹ tests 7
ℹ suites 0
ℹ pass 7
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1038.048427
@@ -0,0 +1,13 @@
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (82.226656ms)
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (23.699192ms)
✔ two real socket writes to one repository yield one commit and one project-busy refusal (39.647654ms)
✔ client disconnect during await tolerates late reply (35.818624ms)
✔ client disconnect during await tolerates late refusal (20.960688ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 259.163828
@@ -0,0 +1,11 @@
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (59.460229ms)
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (38.869362ms)
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (84.355853ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 238.375001
@@ -0,0 +1,10 @@
✔ every role sees read_spec, record writer follows its grant, citation schemas stay strict (9.482785ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (68.612006ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 151.095078
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""One fault per acceptance check. Preflight is read-only; batches require Sage's slot."""
import json, os, pathlib, signal, subprocess, sys
ROOT = pathlib.Path('/mnt/storage/src/mosaic-stack-rocko-138-r3')
OUT = pathlib.Path(__file__).resolve().parent / 'mutants'
R = 'packages/project/src/read.mjs'
RT = 'packages/project/tests/read.test.mjs'
B = 'packages/bus/src/broker.mjs'
BT = 'packages/bus/tests/spec.test.mjs'
ST = 'packages/bus/tests/spec-socket.test.mjs'
HT = 'packages/harness/tests/spec-tools.test.mjs'
cases = []
def add(name, path, old, new, test):
cases.append(dict(check=name, path=path, old=old, new=new, test=test))
add('01-content-trailing-bytes', R, 'return text(await gitBytes(repo, [\'cat-file\', \'blob\', match[2]], MAX_BYTES));', 'return text(await gitBytes(repo, [\'cat-file\', \'blob\', match[2]], MAX_BYTES)).trimEnd();', RT)
add('02-file-commit-not-head', R, 'commit: log[0].commit, content', 'commit: head, content', RT)
add('03-historical-revision', R, 'const revision = commit === undefined ? head : commit;', 'const revision = head;', RT)
add('04-reachable-history', R, "await git(repo, ['merge-base', '--is-ancestor', revision, head]);", '/* reachability omitted */', RT)
add('05-full-commit-id', R, "if (typeof revision !== 'string' || !SHA.test(revision))", 'if (false)', RT)
add('06-read-path-confinement', R, r"if (typeof path !== 'string' || !(path === 'spec/north-star.md' || /^docs\/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.md$/.test(path)))", 'if (false)', RT)
add('07-strict-utf8', R, '{ fatal: true, ignoreBOM: true }', '{ fatal: false, ignoreBOM: true }', RT)
add('08-no-nul', R, "if (value.includes('\\0'))", 'if (false)', RT)
add('09-blob-size', R, 'if (!Number.isSafeInteger(size) || size < 0 || size > MAX_BYTES)', 'if (false)', RT)
add('10-regular-blob-mode', R, '(100644|100755) blob', '(100644|100755|120000) blob', RT)
add('11-project-identity', R, 'metadata.business !== business.id', 'false', RT)
add('12-repository-validation', R, ' await inspectGit(repo);', ' /* repository validation omitted */', RT)
add('13-log-page-bound', R, 'log: log.slice(0, 100)', 'log: log.slice(0, 101)', RT)
add('14-log-truncation', R, 'truncated: log.length > 100', 'truncated: false', RT)
add('15-human-confirmation', R, 'result.author.name === args.business.human', 'true', RT)
add('16-preserve-bom', R, 'ignoreBOM: true', 'ignoreBOM: false', RT)
add('17-read-argument-keys', R, "if (!args || typeof args !== 'object' || Array.isArray(args) || Object.keys(args).some(k => !allowed.includes(k)))", 'if (false)', RT)
add('18-invalid-revision-refusal-code', R, "fail('project-read-commit', 'commit is not reachable from HEAD')", "fail('project-git', 'commit is not reachable from HEAD')", RT)
add('19-stale-citation', B, "if (args.spec_commit !== spec.commit) fail('stale-spec');", '/* stale citation check omitted */', BT)
add('20-unconfirmed-citation', B, "if (!spec.confirmed) fail('spec-unconfirmed');", '/* human confirmation omitted */', BT)
add('21-partial-citation', B, "if (typeof args.project !== 'string' || args.spec_path !== 'spec/north-star.md' ||\n typeof args.spec_commit !== 'string' || !/^[0-9a-f]{40}$/.test(args.spec_commit))", 'if (false)', BT)
add('22-persist-spec-commit', B, ' spec?.commit ?? null,', ' null,', BT)
add('23-persist-spec-path', B, ' spec?.path ?? null,', ' null,', BT)
add('24-uncited-raises-still-valid', B, "if ((a.spec_path !== undefined || a.spec_commit !== undefined) && !spec)", 'if (!spec)', BT)
add('25-session-author', B, 'definition: business.roles[s.role].definition, instance: s.role', 'definition: business.roles[s.role].definition, instance: business.human', BT)
add('26-record-spec-refusal', 'packages/project/src/index.mjs', "if (path === 'spec' || path.startsWith('spec/'))", 'if (false)', BT)
add('27-writer-cannot-accept-author', B, "keys(args, ['project', 'path', 'record', 'decision'], ['project', 'path', 'record']);", "keys(args, ['project', 'path', 'record', 'decision', 'author'], ['project', 'path', 'record']);", BT)
add('28-write-authority-before-effect', B, "this.#store.transaction(() => this.#checkAuthority(s, 'record.write', authority));", '/* pre-write authority omitted */', BT)
add('29-write-commit-receipt', B, '{ project: args.project, path: result.path, commit: result.commit }', '{ project: args.project, path: result.path, commit: null }', BT)
p = 'packages/bus/src/server.mjs'
old = "if (r.verb === 'spec.read' || r.verb === 'record.write' ||\n (r.verb === 'decision.raise' && (Object.hasOwn(r.args ?? {}, 'spec_path') || Object.hasOwn(r.args ?? {}, 'spec_commit'))))"
add('30-await-only-project-effects', p, old, 'if (false)', ST)
add('31-async-own-refusal-code', p, "e => { if (!socket.destroyed) finish({ ok: false, error: e instanceof BusError ? e.code : 'invalid-envelope' }); }", "e => { if (!socket.destroyed) finish({ ok: false, error: 'invalid-envelope' }); }", ST)
add('32-live-transient-proof', p, "Promise.resolve().then(() => broker.request(cap, { verb: r.verb, args: r.args ?? {} })).then(", "if (own) broker.disconnect(own);\n Promise.resolve().then(() => broker.request(cap, { verb: r.verb, args: r.args ?? {} })).then(", ST)
add('33-concurrent-write-refusal', 'packages/project/src/index.mjs', "fd = openSync(lock, 'wx', 0o600);", "fd = openSync(lock, 'w', 0o600);", ST)
p = 'packages/harness/src/tools.mjs'
add('34-read-for-every-role', p, ' add("read_spec",', ' if (held.has("record.write")) add("read_spec",', HT)
add('35-writer-follows-grant', p, 'if (held.has("record.write"))', 'if (true)', HT)
add('36-typed-spec-path', p, 'const: "spec/north-star.md"', 'const: "docs/design.md"', HT)
add('37-typed-writer-path', p, 'pattern: "^(docs/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\\\\.md|(requirements|decisions)/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\\\\.json)$"', 'pattern: ".*"', HT)
add('38-migration-runs-new-step', 'packages/bus/src/store.mjs', ' this.#db.exec(step.sql);', " if (step.from !== '3e') this.#db.exec(step.sql);", 'packages/bus/tests/spec-migration.test.mjs')
add('39-preserve-old-evidence', 'packages/bus/src/store.mjs', ' step.initialize?.(this);', " step.initialize?.(this);\n if (step.from === '3e') this.#db.exec(\"DROP TRIGGER decision_events_no_delete; DELETE FROM decision_events; CREATE TRIGGER decision_events_no_delete BEFORE DELETE ON decision_events BEGIN SELECT RAISE(ABORT, 'decision_events is append-only'); END\");", 'packages/bus/tests/spec-migration.test.mjs')
add('40-future-step-chaining', 'packages/bus/src/store.mjs', 'while (version !== SCHEMA_VERSION)', 'if (version !== SCHEMA_VERSION)', 'packages/bus/tests/comment-migration.test.mjs')
roles = ['assistant', 'chief-executive-officer', 'chief-financial-officer', 'chief-information-officer',
'chief-information-security-officer', 'chief-marketing-officer', 'chief-of-staff', 'coder', 'cto', 'pm', 'reviewer']
for i, role in enumerate(roles, 41):
add(f'{i:02}-record-grant-{role}', f'roles/{role}.json', ', "record.write"', '', 'packages/business/tests/record-grants.test.mjs')
for c in cases:
assert (ROOT / c['path']).read_text().count(c['old']) == 1, c['check']
if '--preflight' in sys.argv:
print('PREFLIGHT_OK', len(cases)); sys.exit(0)
OUT.mkdir(exist_ok=True)
rows = []
def stop_tree(pid):
# Git's own runner creates process groups too. Capture descendants before killing the parent.
descendants = {pid}
for _ in range(8):
before = set(descendants)
for entry in pathlib.Path('/proc').iterdir():
if not entry.name.isdigit(): continue
try:
fields = (entry / 'stat').read_text().split(') ', 1)[1].split()
if int(fields[1]) in descendants: descendants.add(int(entry.name))
except (OSError, ValueError, IndexError): pass
if before == descendants: break
for child in descendants:
try: os.killpg(child, signal.SIGKILL)
except ProcessLookupError: pass
for c in cases:
file = ROOT / c['path']; original = file.read_bytes(); process = None
try:
file.write_text(original.decode().replace(c['old'], c['new']))
with (OUT / (c['check'] + '.log')).open('w') as log:
process = subprocess.Popen(['node', '--test', c['test']], cwd=ROOT,
env={**os.environ, 'DOCKER_HOST': 'unix:///nonexistent.sock'}, stdout=log,
stderr=subprocess.STDOUT, start_new_session=True)
try: rc = process.wait(timeout=180)
except subprocess.TimeoutExpired: stop_tree(process.pid); process.wait(); rc = 'timeout'
content = (OUT / (c['check'] + '.log')).read_text()
invalid = any(x in content for x in ['SyntaxError:', 'ERR_MODULE_NOT_FOUND'])
verdict = 'INVALID' if invalid else 'TIMEOUT' if rc == 'timeout' else 'SURVIVED' if rc == 0 else 'KILLED'
rows.append({k: c[k] for k in ['check', 'path', 'test']} | {'result': verdict, 'exit': rc})
(OUT / 'results.json').write_text(json.dumps(rows, indent=2) + '\n')
print(c['check'], verdict, rc, flush=True)
finally:
if process is not None and process.poll() is None: stop_tree(process.pid); process.wait()
file.write_bytes(original)
if verdict != 'KILLED': sys.exit(1)
@@ -0,0 +1,29 @@
1160d1ee707839a97e5df47657a13f26918e8918bab66c48c178a9094dfee835 BUILD.md
24f78425425191e0aeec474f978c102cd608cc96dd1ca5fc2ea084bd6ff0fae5 MIGRATION.md
c29edd841268744dd5974a0f0387da31fcdbaaff385d36c0efdb6ed2f7016299 base.txt
5bbf0f3390c5c322b3955d87756364916a1df1718c099d35cd716a5d8206d521 build.patch
24ad57a5aa9373ab083c194d790bbe6e100c2a2fa2ce6b53f71758a101a85140 bus-chief.log
a66511230c2fdf799011392c080a45386dffb358af41ab96495647e448ba25b7 business-business.log
764fee827719f1eac877b4c39c720c0237c8d7cfbe6c150056f61a26868dae76 business-chief-of-staff.log
e58cf5d64b68d391a891293a98167f9949524c9c120ebf2727e97102dd7e1729 business-resolve.log
0e98eb0cc379b549e6904d952e7f2511d7b3aec7e4725a2c8d3515502cf9f4b6 candidate-manifest.sha256
0fa59dd786587623a5e6a432aaf347cba5f7a1c6da9b3fe56f5049e9964f6de5 existing-tools-first.log
f1f49cf45df4679228ee33094f551604874eb216cea0c16917083beeb27b7e2e existing-tools.log
dd0f1544038c1957ed205570e7973a6767439861eabd00906fbf17d257f8ef86 grants.log
8d180d1f98a0f6db0c321e099a35d690ce66e8af98cc73e8e60740fbcfd1c5f9 green-broker.log
ba1c40348a6b7eb09c85d9608a7d79bc0f715da6f3aefefd07f9c9d28e29a123 green-comment-migration.log
a5903975a79106686fd1fb59cfca9df931753d3bb8d78757fea4bf196f0c5c90 green-migration.log
e4d497da62cca9955050231b3b97736cdbed96940e126a380b957cac115d2493 green-reader.log
480bd5b9d4cb9c4f2f61f4985995cbab0c3e66719fb1e328d7705cf4c83e704f green-socket.log
3ea40d93ba2ae27db52c44b5f812ea779141745ea6149622e0ef71e74d0adbdb green-thread-migration.log
a48780d14649b6fb6e9f7e79e1e2de616754f73b261d0c62c437ba225b0164fb green-tools.log
bd179adcf037dd1f5d9daea69fbb116038674229a827a13c3065e015cb6f456a mutants.py
4ca0ce193c5102d6444000ef93afdd2d5d0453d64dd44de1eadc42969144c95b prepare.py
4133e0f282091eded4c93fc8ff188611de21ee7fcd5b8135e4bc104de9c52b94 rebuild-manifest.txt
2b7bf1a897a1a14f6a2f57e4581d111a786d65e87d5803ead92219b1b8e2bf77 red-bom.log
c50dd93ea8d0be1a624651d4cac1daab35118075aa37daaf83068e8d6fad3787 red-broker.log
ad29cd99b3ebb8660705115b182aab3c5fdefe9ddd83c97e294a060767cb9d2e red-migration.log
c55c866704e62a4f7acbd1e27a4805bc1e679d0cc292c822331f85087cefa6dd red-reader.log
3d5486b0ff13e6013a4b9339f7eb3115484be079718b2ac54d06de0e643a8597 red-socket.log
7a66ae611e1f57dcfb0b2c55e6f22fcdb6c0e05d646e494ed9229cfe82176239 red-tools.log
d03d82766a226ed4955be2572d5b71507fbb93a07e64500e78a9a16a01f227d5 scan.json
@@ -0,0 +1,17 @@
#!/usr/bin/env python3
import hashlib, pathlib, subprocess
root = pathlib.Path('/mnt/storage/src/mosaic-stack-rocko-138-r3')
out = pathlib.Path(__file__).resolve().parent
tracked = subprocess.check_output(['git','diff','--name-only'],cwd=root,text=True).splitlines()
new = subprocess.check_output(['git','ls-files','--others','--exclude-standard','--','packages/project','packages/bus','packages/harness','packages/business'],cwd=root,text=True).splitlines()
paths = sorted(set(tracked + new))
patch = subprocess.check_output(['git','diff','--binary','--no-ext-diff'],cwd=root)
for path in sorted(new):
result = subprocess.run(['git','diff','--no-index','--binary','--','/dev/null',path],cwd=root,stdout=subprocess.PIPE)
assert result.returncode == 1
patch += result.stdout
(out/'build.patch').write_bytes(patch)
(out/'base.txt').write_bytes(subprocess.check_output(['git','rev-parse','HEAD'],cwd=root))
(out/'candidate-manifest.sha256').write_text(''.join(hashlib.sha256((root/p).read_bytes()).hexdigest()+' '+p+'\n' for p in paths))
print('candidate paths',len(paths))
print('candidate SHA',hashlib.sha256((out/'candidate-manifest.sha256').read_bytes()).hexdigest())
@@ -0,0 +1,37 @@
packages/bus/README.md: OK
packages/bus/schema.sql: OK
packages/bus/src/broker.mjs: OK
packages/bus/src/migrations/3e-3f.sql: OK
packages/bus/src/server.mjs: OK
packages/bus/src/store.mjs: OK
packages/bus/tests/chief-of-staff.test.mjs: OK
packages/bus/tests/comment-migration.test.mjs: OK
packages/bus/tests/fixtures/schema-3e.sql: OK
packages/bus/tests/spec-fixtures.mjs: OK
packages/bus/tests/spec-migration.test.mjs: OK
packages/bus/tests/spec-socket.test.mjs: OK
packages/bus/tests/spec.test.mjs: OK
packages/bus/tests/thread-migration.test.mjs: OK
packages/business/src/vocabulary.mjs: OK
packages/business/tests/chief-of-staff.test.mjs: OK
packages/business/tests/record-grants.test.mjs: OK
packages/harness/README.md: OK
packages/harness/src/tools.mjs: OK
packages/harness/tests/spec-tools.test.mjs: OK
packages/harness/tests/tools.test.mjs: OK
packages/project/README.md: OK
packages/project/src/git.mjs: OK
packages/project/src/index.mjs: OK
packages/project/src/read.mjs: OK
packages/project/tests/read.test.mjs: OK
roles/assistant.json: OK
roles/chief-executive-officer.json: OK
roles/chief-financial-officer.json: OK
roles/chief-information-officer.json: OK
roles/chief-information-security-officer.json: OK
roles/chief-marketing-officer.json: OK
roles/chief-of-staff.json: OK
roles/coder.json: OK
roles/cto.json: OK
roles/pm.json: OK
roles/reviewer.json: OK
@@ -0,0 +1,36 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (62.498445ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (30.578545ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (51.414583ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (97.026854ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (27.604339ms)
✔ path history is bounded at 100 and explicitly marks truncation (675.009459ms)
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (31.197426ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1019.532864
✖ failing tests:
test at packages/project/tests/read.test.mjs:101:1
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (31.197426ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ '# North star 🧭\r\n\r\n'
- '# North star 🧭\r\n\r\n'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:105:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '# North star 🧭\r\n\r\n',
expected: '# North star 🧭\r\n\r\n',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,64 @@
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (24.365989ms)
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (17.416561ms)
✖ uncited raises retain their synchronous path and spec read is available to any held role in its business (16.617387ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (16.569561ms)
ℹ tests 4
ℹ suites 0
ℹ pass 0
ℹ fail 4
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 130.164086
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:42:1
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (24.365989ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:83:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:183:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:23:18)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:43:13)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
code: 'invalid-authority'
}
test at packages/bus/tests/spec.test.mjs:56:1
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (17.416561ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:83:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:183:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:23:18)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:57:13)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
code: 'invalid-authority'
}
test at packages/bus/tests/spec.test.mjs:71:1
✖ uncited raises retain their synchronous path and spec read is available to any held role in its business (16.617387ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:83:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:183:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:23:18)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:72:13)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
code: 'invalid-authority'
}
test at packages/bus/tests/spec.test.mjs:84:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (16.569561ms)
Error: invalid-authority
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:83:9)
at new Broker (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:183:11)
at fixture (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:23:18)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec.test.mjs:85:13)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
code: 'invalid-authority'
}
@@ -0,0 +1,27 @@
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (53.205386ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 104.727399
✖ failing tests:
test at packages/bus/tests/spec-migration.test.mjs:51:1
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (53.205386ms)
AssertionError [ERR_ASSERTION]: Missing expected exception.
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec-migration.test.mjs:53:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: /schema-mismatch/,
operator: 'throws',
diff: 'simple'
}
@@ -0,0 +1,52 @@
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (29.139456ms)
✖ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (17.45809ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (16.201068ms)
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (9.692158ms)
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (9.276195ms)
ℹ tests 5
ℹ suites 0
ℹ pass 0
ℹ fail 5
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 128.018333
✖ failing tests:
test at packages/project/tests/read.test.mjs:25:1
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (29.139456ms)
TypeError: api.readSpec is not a function
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:30:28)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
test at packages/project/tests/read.test.mjs:46:1
✖ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (17.45809ms)
TypeError: api.readSpec is not a function
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:49:28)
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)
test at packages/project/tests/read.test.mjs:54:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (16.201068ms)
TypeError: api.readProjectFile is not a function
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:57:27)
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)
test at packages/project/tests/read.test.mjs:67:1
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (9.692158ms)
TypeError: api.readProjectFile is not a function
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:69:28)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
test at packages/project/tests/read.test.mjs:81:1
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (9.276195ms)
TypeError: api.readSpec is not a function
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/project/tests/read.test.mjs:83:28)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
@@ -0,0 +1,60 @@
✖ real socket awaits spec reads, record writes and cited raises; other requests still return normally (34.760591ms)
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (23.922316ms)
✖ two real socket writes to one repository yield one commit and one project-busy refusal (25.5119ms)
✔ client disconnect during await tolerates late reply (37.320601ms)
✖ client disconnect during await tolerates late refusal (20.884551ms)
ℹ Error: Test "real socket awaits spec reads, record writes and cited raises; other requests still return normally" at packages/bus/tests/spec-socket.test.mjs:15:1 generated asynchronous activity after the test ended. This activity created the error "Error: storage-unavailable" and would have caused the test to fail, but instead triggered an unhandledRejection event.
ℹ Error: Test "two real socket writes to one repository yield one commit and one project-busy refusal" at packages/bus/tests/spec-socket.test.mjs:43:1 generated asynchronous activity after the test ended. This activity created the error "Error: storage-unavailable" and would have caused the test to fail, but instead triggered an unhandledRejection event.
ℹ tests 5
ℹ suites 0
ℹ pass 1
ℹ fail 4
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 196.706522
✖ failing tests:
test at packages/bus/tests/spec-socket.test.mjs:15:1
✖ real socket awaits spec reads, record writes and cited raises; other requests still return normally (34.760591ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ undefined
- 'eecf724f48f03959c3c369002145ae0bad0c6ad8'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/tests/spec-socket.test.mjs:18:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: undefined,
expected: 'eecf724f48f03959c3c369002145ae0bad0c6ad8',
operator: 'strictEqual',
diff: 'simple'
}
test at packages/bus/tests/spec-socket.test.mjs:28:1
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (23.922316ms)
Error: project-not-declared
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:979:58)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 'project-not-declared'
}
test at packages/bus/tests/spec-socket.test.mjs:43:1
✖ two real socket writes to one repository yield one commit and one project-busy refusal (25.5119ms)
Error: project-busy
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:979:58)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 'project-busy'
}
test at packages/bus/tests/spec-socket.test.mjs:55:38
✖ client disconnect during await tolerates late refusal (20.884551ms)
Error: project-not-declared
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/bus/src/broker.mjs:979:58) {
code: 'project-not-declared'
}
@@ -0,0 +1,31 @@
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.928892ms)
✖ typed socket forwards read content/history and agent record writes, and cannot write a spec (39.226717ms)
ℹ tests 2
ℹ suites 0
ℹ pass 0
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 132.433339
✖ failing tests:
test at packages/harness/tests/spec-tools.test.mjs:7:1
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.928892ms)
TypeError: Cannot read properties of undefined (reading 'verb')
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/spec-tools.test.mjs:11:28)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
test at packages/harness/tests/spec-tools.test.mjs:33:1
✖ typed socket forwards read content/history and agent record writes, and cannot write a spec (39.226717ms)
Error: refused: Cannot read properties of undefined (reading 'verb')
at Socket.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/src/tools.mjs:267:42)
at Socket.emit (node:events:514:20)
at addChunk (node:internal/streams/readable:575:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
at Readable.push (node:internal/streams/readable:406:5)
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)
@@ -0,0 +1,5 @@
{
"files": 28,
"findings": [],
"scope": "packet-only UTF-8/NUL and private-key/credential-value patterns; no live reads"
}
+180
View File
@@ -0,0 +1,180 @@
# Row 138 / #1632: file-backed north-star specs
This is the revised r3 brief's first build candidate, not the superseded
spec-table candidate in ../r1. Base 26a0b0fab4e58d8fe278a7da615172395b026955, detached worktree:
/mnt/storage/src/mosaic-stack-rocko-138-r3b. Reviewer Dewey, gate owner Sage.
Old worktree and PAUSED.md are preserved. Completed row 153's worktree was
verified against its packet and removed as Sage authorized in sage-0478.
## Behavior and boundaries
The spec is spec/north-star.md in row 147's separate project repository. The
shared project reader returns exact committed UTF-8 (BOM/trailing bytes kept),
the last reachable commit changing the file, author and bounded path log.
Historical full SHA-1 commits must be reachable from a captured HEAD; dirty
working bytes are ignored. A docs-only commit never stales a citation. The
committed project.json identity, paths, Git metadata/remotes, regular blob mode,
1 MiB content bound, UTF-8 and NUL constraints are checked. Log output is bounded
to 256 KiB and 100 entries, with truncation explicit. Blob reads use a bounded
raw-byte Git runner sharing sanitized Git options/environment and group timeout
cleanup, because the existing text runner trims output and replaces invalid
UTF-8, which cannot preserve this contract.
readSpec.confirmed is true exactly when the file commit's author.name equals
business.human. A latest agent-authored file stays unconfirmed; no fallback.
This is local provenance, not a cryptographic identity proof. Exported APIs and
refusal codes match ../DESIGN-r3.md and are documented in the package README;
row 148 uses the same reader and adds its own locked stale-base human writer.
A cited decision.raise requires project and paired exact spec_path/spec_commit.
The broker reads the current snapshot, refuses invalid/stale/unconfirmed
citations and stores both fields. Existing uncited raises retain their sync
path and existing validity/routing/resolution rules. No new spec commit changes
old decisions or resolution events. No spec table or propose/confirm verb ships.
record.write author is derived only from the bound session's definition and
instance. Caller identity keys refuse. Authority is checked before the filesystem
effect; package validation and exclusive repository writer lock apply. spec/
refuses through package, broker and typed tool. Concurrent requests to one repo
return one commit and one project-busy, not a Git index race. Commit/receipt are
two effects; a commit whose SQL authority receipt cannot be recorded refuses
outcome-unknown for inspection, never automatic retry. This row adds no human
writer, shell escape, config edit, Console route or spec confirmation action.
The existing wire request limit remains 64 KiB; package file bound is 1 MiB.
read_spec is offered to every role. write_record follows the record.write grant.
raise_decision's strict schema accepts optional project and paired citations;
the broker enforces pairing and freshness. Eleven current roleVersion 2 files
have the within-role grant; legacy researcher v1 and conductor-policy do not
change (Sage count correction sage-0482).
## Scope additions and rulings
- sage-0419, at Rocko's request with Sage's agreement: packages/project shared
reader and fixture tests, beside row 147's writer, sharing repository checks.
The names, arguments, return shapes and refusal codes were written before
code in ../DESIGN-r3.md for Researcher's row 148.
- sage-0480, at Rocko's request: packages/bus/src/server.mjs, only awaiting
spec.read, record.write and spec-citing decision.raise. All other sync paths
are unchanged byte for byte. Async rejections preserve their refusal envelope
and code; transient proofs live until completion. Late replies/refusals after
disconnect do not write a dead socket. Real socket tests cover all three
verbs, own refusal codes/transient cleanup, late success/failure, continued
server usability and two concurrent writes with project-busy.
- sage-0480 and sage-0482: record.write belongs within-role for all eleven v2
definitions. The earlier count of twelve was mistaken; researcher is v1.
## Schema and migration
3e to 3f adds only decisions.spec_path and decisions.spec_commit, nullable, using
an appended named step. Fresh and migrated schema digests match. The 3e fixture
is copied from the tree at this base, never from a live store. The test seeds
every evidence table and compares every old column/row, plus an untouched copy.
Older chain tests follow the current version and retain their pinned old DDL;
the future-version fixture still chains, now to 3g. MIGRATION.md contains exact
DDL, hashes and Mos's approved stopped-bus backup/migrate/re-pin/rollback plan.
No seat reads/migrates the live store or controls any unit.
## Focused evidence and planned gate
Only singly invoked node --test FILE checks have run. No suite, browser,
Docker, sandbox, shell suite or mutant batch. Reader 7; spec migration 1; broker
spec 4; real socket 5; harness spec tools 2; grant contract 1. Existing focused
files: comment migration 5, thread migration 3, bus chief 13, harness tools 18,
business chief 10, business core 16, resolve 10. All pass, no skips. Red logs
capture absent reader/migration/broker/tools/server and BOM normalization before
their implementations. Existing tool-name lists and chief authority contract
were updated to preserve their prior intent while including the approved tools.
51 mutants are prepared and exact-once sites preflighted only. They cover the
reader, citation rules, bound authors, spec refusal, authority/receipts, async
socket behavior, concurrent writer lock, typed tools, migration preservation
and chaining, and each of the eleven grants. Timeout/syntax/import failure is
not a kill. Whole groups and detached Git descendants are killed on timeout;
every original file restores in finally. Run only after Sage's explicit grant.
Required package gate: project, bus, business, harness and cli. The revised
brief requires every scripts/test-*.sh: auth, conductor, config, discord,
extension-package, foundation, land-work, queue, release and task. Their current
list was obtained with rg --files scripts, not inferred from prior gate counts.
Sage owns the landing gate. DOCKER_HOST is a dead socket by default; any Docker
run requires the shared slot and the task/release Docker cases must not be
silently skipped. One recurrence of #258/#261/#262/#263 is a note; two of the
same flake in a gate stop and are reported. Slot request and final results are
pending. No review-ready, gate or mutant success claim yet.
### Slot boundary — sage-0485
Sage is gating/pushing row 152 first. Wait for the explicit clock-stamped grant;
a CLEAR process probe alone does not authorize a run. Authorized future batch:
51 mutants plus project, bus, business, harness and cli suites only. No Docker,
browser or shell suite; Sage's landing gate runs every shell suite. Check base
drift after row 152 is pushed before the granted runs. Clean base+patch
reconstruction already verifies all 37 current candidate paths on 56639c99b.
## Rebase after row 152 — sage-0486
The incoming row overlaps only packages/bus/README.md and src/broker.mjs among
this candidate's 37 paths. Applied the original candidate cleanly onto the
pushed 26a0b0fab. Broker waiting/notice launchability behavior and its README
paragraph remain intact, beside the new async project paths. No manual conflict
resolution or new product edit was required. Prior packet preserved separately
at ../r3-before-152/. Candidate manifest regenerated before any granted suite.
The grant covers 51 mutants and the five package suites only: no Docker, browser,
shell suite or live step. DOCKER_HOST=unix:///nonexistent.sock throughout.
Package files run serially with node --test --test-concurrency=1.
### Package-run corrections
The first business run exposed four stale authority-snapshot assertions in
assistant.test.mjs and csuite.test.mjs; they still allowed only message.send.
Updated their exact approved authority lists/classification expectations for
record.write while retaining the narrowed-limit tests unchanged. The first
harness run exposed two stale bundle tool-list assertions; updated those exact
lists for read_spec/write_record. These add three test paths to the manifest.
No product code changed. Both original failure logs are preserved as
suite-business-old-snapshots.log and suite-harness-old-snapshots.log. Their
complete package reruns passed. These were expectation corrections, not flakes.
## Runtime injection and sandbox closure — sage-0488
The first CLI run exposed a real candidate import dependency: Client imports
broker.mjs for BusError; a static project import would make sandboxed runners
load host Git modules outside RUNNER_FILES. Stopped the owned CLI test runner
and descendants, preserving suite-cli-import-closure-failure.log. This was not
a known flake. A lazy project import was considered and rejected because the
sandbox's explicit import-closure contract includes lazy imports too; none
remains in the final broker.
At Rocko's request Sage approved packages/bus/src/runtime.mjs and its real
integration test in sage-0488. Runtime imports the project module, binds its
dataRoot in readSpec/writeRecord functions and passes the trusted adapter plus
ProjectError type into Broker. The constructor's adapter defaults to null;
all three new async paths refuse project-not-configured without it. Broker
has exactly its two original imports and no dynamic import. No sandbox policy,
mount, client, seat or launcher change was made.
packages/bus/tests/project-runtime.test.mjs holds this boundary explicitly:
exact original broker imports/no lazy import; all three no-adapter refusals;
real startBroker plus socket read and record write through the injected adapter.
The integration test fails with the runtime adapter omitted, and passes with it.
A new mutant each removes the no-adapter refusal, runtime injection and import
closure requirement. Total now 54; all sites re-preflighted after the fix.
The three snapshot files changed only for this candidate's approved behavior:
- business/tests/assistant.test.mjs: exact approved role/resolved authority gains
record.write beside message.send, because roles/assistant.json gains it.
Its narrowed-limit assertions remain unchanged.
- business/tests/csuite.test.mjs: exact C-suite role/resolved authority and full
classification gain record.write, because those five role files gain it.
Narrowed limits and all tool, credential and messaging restrictions remain.
- harness/tests/bundle.test.mjs: chief's exact prompt/manifest tool lists gain
read_spec/write_record, because typedTools now offers the read and the grant's
writer. Existing launch/end/organization tools stay in the same order.
The base passed these tests; their initial failures were caused by this
candidate's additions, not independent drift. Initial failure logs are kept.
The refreshed candidate has 42 paths. No product code changed outside the
approved adapter fix. All five package suites will be run on this final source;
CLI launcher failures after injection would stop and be reported, never patched
by changing launcher tests. No Docker, browser, shell suite or live step.
@@ -0,0 +1,84 @@
# Row 138: offline schema 3e to 3f window
Only Mos runs the live steps, with Jason's approved downtime/re-pin window.
Development seats run this command against disposable fixture copies only.
Nothing in this packet authorizes a seat to read the live store, stop/start a
unit, migrate a live file, or re-pin a copy.
## Exact change
Source schema 3e is packages/bus/tests/fixtures/schema-3e.sql, copied from
56639c99b's repository tree, SHA-256:
21e6c091f14f818396f4d7836f381cc1389d45b2680ecaa1a00646b652c45050.
Target schema is 3f, source SHA-256:
472cbcd0d4548848873f3029e8250dc07bba4fb8db2a93241aae5b8e7e3771e2.
The new ordered step is packages/bus/src/migrations/3e-3f.sql:
```sql
ALTER TABLE decisions ADD COLUMN spec_path TEXT;
ALTER TABLE decisions ADD COLUMN spec_commit TEXT;
```
Both columns are nullable. Existing decisions get nulls; existing events,
settlements and every other row/old column stay unchanged. There are no specs
or spec_confirmations tables. Each completed named step commits separately;
prior migration steps and future-version chaining remain supported. Normal
startup refuses 3e under the new copy; it never auto-migrates.
## Mos's procedure, before and inside the window
1. Before stopping anything, prepare the approved pinned code copy and verify
its candidate/source manifests and migration command. Identify the existing
pinned copy for rollback. This packet does not switch any live pointer.
2. In Mos's approved window, make the PM run idle and stop all users of the bus
and the bus itself using the window's existing service procedure. Confirm no
writer remains. Do not migrate while the bus or another writer is running.
3. Make a consistent, owner-only backup of the stopped data root's entire bus
directory, including any SQLite WAL/SHM files. Keep the prior pinned code
copy and its launch/service settings with the backup receipt. Record time,
backup paths and hashes without printing message content. Do not delete an
unexplained writer.lock; diagnose it under the existing stale-lock procedure.
4. On a disposable copy of that backup, run the approved new copy's command
below and validate normal opening/quick_check/foreign_key_check. A refusal
stops the window for diagnosis. Never improvise around schema/digest checks.
5. With the live bus still stopped and the original backup preserved, Mos runs:
```sh
node <approved-copy>/packages/bus/src/migrate-schema.mjs <absolute-dataRoot>
```
It must exit 0 and end with `bus schema 3f ready`. The exclusive writer lock,
source schema/digest, timestamps, WAL and integrity checks must all pass.
Only the same stopped source proven in step 4 is used.
6. Mos follows the approved re-pin/start procedure for the new copy and checks
the stack-copy/runtime proof and normal reads. No spec or organization file
edit is required for this schema step; project init is a separate human
operation. Human spec commits confirm the spec; uncited existing raises work.
7. Record the backup, code copy, command exit, readiness checks and any downtime.
Existing settled decisions remain settled. Hold unrelated row migrations
until their own reviewed window plan says they may run.
## Refusal and rollback
A failed step rolls its transaction back; earlier completed named steps remain
valid. Preserve evidence and diagnose instead of retrying blindly. Rerunning an
already-current 3f store validates it without changing evidence.
If Mos chooses rollback, stop every new-copy reader/writer first, preserve a
consistent copy of the post-attempt bus directory for reconciliation, restore
the complete pre-window bus backup with its original permissions and WAL/SHM
state, and restore the prior pinned copy and launch settings together. Old 3e
code must never open the upgraded 3f file. Do not strip columns or edit evidence
in place. If any new messages/decisions were recorded after start, rollback
would discard them from the active store: Mos/Jason must resolve that data
boundary before proceeding; keep the post-attempt copy intact.
## Fixture evidence
spec-migration.test.mjs builds a 3e database from the pinned tree DDL, populates
every evidence table, keeps an untouched copy, checks normal startup refuses,
migrates, and compares every old table/column/row and sequence counter. Only
schema_version/schema_digest values and the two added null columns differ.
Integrity and normal 3f reopening pass. Existing 3b/3c/3d migration tests remain,
and the future fixture now chains through 3f to a fixture-only 3g.
+1
View File
@@ -0,0 +1 @@
26a0b0fab4e58d8fe278a7da615172395b026955
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (23.299455ms)
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (21.755576ms)
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (18.284545ms)
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (16.18574ms)
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (18.09891ms)
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (19.134945ms)
✔ REQ-COS-1: the chief of staff cannot end its own run or the assistant's through role.end (18.875751ms)
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (14.419152ms)
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (19.934864ms)
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (19.817717ms)
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (23.638175ms)
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (48.888848ms)
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (50.287517ms)
ℹ tests 13
ℹ suites 0
ℹ pass 13
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 399.070837
@@ -0,0 +1,24 @@
✔ config directory and file path follow MOSAIC_CONFIG (1.041858ms)
✔ the fixture business validates and comes back frozen (3.451636ms)
✔ two instances may share a definition (1.094883ms)
✔ top-level refusals (2.871191ms)
✔ arbiters and projects (4.205919ms)
✔ role instances (2.039439ms)
✔ Vikunja bots (4.690039ms)
✔ a role without Vikunja takes no tracker block (1.774192ms)
✔ credential references match the definition's services (1.902936ms)
✔ launch (6.201564ms)
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (3.541192ms)
✔ loadBusiness: file checks (1.488956ms)
✔ loadBusiness: not a regular file (37.211304ms)
✔ loading writes nothing (1.020932ms)
✔ names that are Object.prototype properties don't count as declared (2.530155ms)
✔ the shipped example refuses as written and validates once filled in (0.727335ms)
ℹ tests 16
ℹ suites 0
ℹ pass 16
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 129.585359
@@ -0,0 +1,18 @@
✔ the role file loads and resolves through loadBusiness (4.889292ms)
✔ the shipped file is exactly the approved list (0.180316ms)
✔ the resolved record matches the approved list, so a widened file fails (1.205872ms)
✔ the chief of staff holds role.launch, message.send, role.end and organization.change; every other action is gated (1.022328ms)
✔ the pm does not hold role.launch (1.111834ms)
✔ a business grant of a gated action through limits does not widen the role (1.278493ms)
✔ a limit that drops role.launch leaves the chief of staff with no launch block (0.759263ms)
✔ a launch block whose by is the pm instance is refused (1.091254ms)
✔ the contract names no duty to talk to the human and the pm contract no launch (0.270865ms)
✔ the instance takes no credential references and no tracker (1.567165ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 67.492254
@@ -0,0 +1,18 @@
✔ systemVars flattens the validated config (1.329251ms)
✔ precedence: system, business, project, project role, agent (3.978643ms)
✔ limits narrow the definition and never widen it (1.642735ms)
✔ role.launch stays within-role only for the instance the launch block names (3.989532ms)
✔ limits.authority without role.launch leaves the launcher with no launch block (1.553313ms)
✔ limits.authority narrows cross-role actions too (0.873042ms)
✔ classify (0.893281ms)
✔ the record carries what the broker and launcher need (0.860897ms)
✔ digest: key order doesn't matter, any value change does (7.984664ms)
✔ refusals (1.554462ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 74.048715
@@ -0,0 +1,42 @@
89f3a787acfd002b9081330f8bad766c75454082fe6714089e6960e5970d4660 packages/bus/README.md
472cbcd0d4548848873f3029e8250dc07bba4fb8db2a93241aae5b8e7e3771e2 packages/bus/schema.sql
ffd79d4d23355434fd8433acc2b28132cfc016379e60745d18925c2ed308191a packages/bus/src/broker.mjs
bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3 packages/bus/src/migrations/3e-3f.sql
4c3ec4e057b11a0a42c517743b6f3954babccd200ba00f7a3c64c71ee251879a packages/bus/src/runtime.mjs
eef4be8ec386c5ed0ef49bcec7416b06b89e659016e4a3d21cc71b1ec6547c6d packages/bus/src/server.mjs
de51a1a5cd857fd143f19c599947c30615f6c2a14a99eb503d9a37dccef43ef2 packages/bus/src/store.mjs
5a6ff816b7a921af365a32a286cd66801d5310a31af7ae83dc083e8e807e4c07 packages/bus/tests/chief-of-staff.test.mjs
0495d15e8b2cb145b1db0d0468a967f7ee5275af6f0736f31b978714269ed926 packages/bus/tests/comment-migration.test.mjs
21e6c091f14f818396f4d7836f381cc1389d45b2680ecaa1a00646b652c45050 packages/bus/tests/fixtures/schema-3e.sql
a9859e73467fc041c4dc6252c6379f021b2587131b237281d69be17add073ccd packages/bus/tests/project-runtime.test.mjs
bcbbbbb0b0250c0a2be7e23c0ce1a6f996884b89d25a60ed343a550af48d57da packages/bus/tests/spec-fixtures.mjs
70a86e4ba863793403201f3c89d1e2f33d49fb20dc7407e60e7e66d8462e59e6 packages/bus/tests/spec-migration.test.mjs
40bf5599fc87c56cc1d4c50d5ac18401c7264be14388e79c74a03e2ad6bfc067 packages/bus/tests/spec-socket.test.mjs
acd888e2e5eb9fdbe1436d5e29b309e7f9bbf8b623ec576a0f733eecb4119031 packages/bus/tests/spec.test.mjs
ac3b5131de1d8384d999af4b8f8ec4021725b6ba402ac0a3cfc691139ec4ee59 packages/bus/tests/thread-migration.test.mjs
3b32890ebe5b5d7aa31e0976159c7cd014c08664fbea830459ef4028ca0fd038 packages/business/src/vocabulary.mjs
bc9b02da4e88e456b24e09b6b410397656581f8387102b355b14060213dcce20 packages/business/tests/assistant.test.mjs
12b468ff1c3473e77a0adcb4a5578662a1840b8a5b049f36e82d5ba8585d4a5b packages/business/tests/chief-of-staff.test.mjs
8449a4cdbde6203b30b2f3bf24e2ab6ed7fe6729537c96d0182992ed0537be7e packages/business/tests/csuite.test.mjs
8652806dbba42e554b67e7c67150fb04e85b46eac50705abf53efb216b79c5ca packages/business/tests/record-grants.test.mjs
78490210a60321754b20fc2d1b0730162df6c25e596019e8746a8061a35948a5 packages/harness/README.md
290ca7336d2f70c26846f0561ae3447b898c94760cb6c62615b70bf76586aca2 packages/harness/src/tools.mjs
81ef56ba6502f647192c5faafe20ed3035d522d1fb97ed6bef63592c78a2521d packages/harness/tests/bundle.test.mjs
56196834173d1f684bee7bc8a5929b8bcb234acd06f04b2ade51ab52bbe066f1 packages/harness/tests/spec-tools.test.mjs
9e0751927d378b51c35fa68613c5f3a6f26a4ee024ddd2e2398004b93624595f packages/harness/tests/tools.test.mjs
3c34eae08653cd40cc34d342cb1572cfbca0cba78ad37f73a3e90046a4251585 packages/project/README.md
d0041915939a1e72285295bead3137911f24a2ebacb794de9382dda47293584e packages/project/src/git.mjs
81bd630bddf0c650be72fe6863d5736dcec09d404f891fcb2e62a0e8f13dcb24 packages/project/src/index.mjs
f1e5f77adc8cd66dcf36e0f46db15416bca0c58ed1e7ab19c49a8f2e407be7a4 packages/project/src/read.mjs
791fa559241828cb9bb098e69d76f4e4c601c7d469a7aeff78ef582c17fbcac8 packages/project/tests/read.test.mjs
5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7 roles/assistant.json
314074c8081953923f962f2df045d4c14629010ea99d1f23449ed45294b46bcc roles/chief-executive-officer.json
539d531a0f5744aebb933ca685b52022554e3e93ae54cc8b67e4de0eb27d3460 roles/chief-financial-officer.json
8ee8e7213d4c073e2d9ba7732fd84b3b3130d9bbb930d07595b7f692bb9fc5dc roles/chief-information-officer.json
a550428603979f4342e57ad9ccddd4d2e44a5203a64f19027ce09a24f1dbfc0e roles/chief-information-security-officer.json
3cdd799159d3e676529efee01f467a4ed7d67920253cddba2e098566368a1e36 roles/chief-marketing-officer.json
d5765eb50ea3cf4cf2a1688892005d38826e84bb142aabc56bd8e17defa82a9e roles/chief-of-staff.json
c314058bb989333143f09b1cec74b87cb10ae78a7dc10afc998edfe510169560 roles/coder.json
895ffb0b5b2c57c3a699d2494a3dff8f844ada25970762e0d87509c786fc3f87 roles/cto.json
77d9682da3a04146b53b2a9ecdb00a4442a6e07661d25abe6e336ea34609772c roles/pm.json
0a432e25a6aa339533064594c323a4a4cef22070a383849227c2f568f71538bc roles/reviewer.json
@@ -0,0 +1,275 @@
✖ the PM gets its task verbs and the reads, and no launch (6.771468ms)
✖ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.250286ms)
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (7.316382ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (1.242897ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.090135ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (5.087481ms)
✖ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (1.006576ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.635595ms)
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.869549ms)
✖ a coder with a tracker gets its own task tools and no task_reassign (0.922462ms)
✔ launch only when the business's launch block names the instance as launcher (1.529053ms)
✖ an action outside the instance's authority has no tool (0.991289ms)
✖ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (1.045234ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (9.60071ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.806843ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (1.833478ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.453321ms)
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (1.988839ms)
ℹ tests 18
ℹ suites 0
ℹ pass 11
ℹ fail 7
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 119.448179
✖ failing tests:
test at packages/harness/tests/tools.test.mjs:9:1
✖ the PM gets its task verbs and the reads, and no launch (6.771468ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines
[
'send_message',
'request_staff',
'task_create',
'task_assign',
...
'task_close',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'resolve_decision',
'list_agents',
'inbox',
'trail',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:12:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [
'send_message', 'request_staff',
'task_create', 'task_assign',
'task_reassign', 'task_schedule',
'task_priority_change', 'task_scope_change',
'task_update_assigned', 'task_close',
'read_spec', 'write_record',
'raise_decision', 'resolve_decision',
'list_agents', 'inbox',
'trail', 'list_tasks',
'get_task', 'list_requirements'
],
expected: [
'send_message', 'request_staff',
'task_create', 'task_assign',
'task_reassign', 'task_schedule',
'task_priority_change', 'task_scope_change',
'task_update_assigned', 'task_close',
'raise_decision', 'resolve_decision',
'list_agents', 'inbox',
'trail', 'list_tasks',
'get_task', 'list_requirements'
],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:33:1
✖ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.250286ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'launch',
'end_run',
'change_organization',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:36: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: [ 'send_message', 'launch', 'end_run', 'change_organization', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'launch', 'end_run', 'change_organization', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:110:1
✖ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (1.006576ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'web_search',
'web_fetch',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.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: [ 'send_message', 'web_search', 'web_fetch', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'web_search', 'web_fetch', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:144:1
✖ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.869549ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail'
]
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:147: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: [ 'send_message', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail' ],
expected: [ 'send_message', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:153:1
✖ a coder with a tracker gets its own task tools and no task_reassign (0.922462ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'task_scope_change',
'task_update_assigned',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:155: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: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:168:1
✖ an action outside the instance's authority has no tool (0.991289ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'request_review',
+ 'read_spec',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:170: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: [ 'request_review', 'read_spec', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at packages/harness/tests/tools.test.mjs:174: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.045234ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'send_message',
'task_scope_change',
'task_update_assigned',
'push_working',
'request_review',
+ 'read_spec',
+ 'write_record',
'raise_decision',
'list_agents',
'inbox',
'trail',
'list_tasks',
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3/packages/harness/tests/tools.test.mjs:177: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: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'push_working', 'request_review', 'read_spec', 'write_record', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
expected: [ 'send_message', 'task_scope_change', 'task_update_assigned', 'push_working', 'request_review', 'raise_decision', 'list_agents', 'inbox', 'trail', 'list_tasks', 'get_task' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,26 @@
✔ the PM gets its task verbs and the reads, and no launch (5.952717ms)
✔ the chief of staff gets launch, send_message, end_run and change_organization, and no task verbs (2.062539ms)
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (7.127672ms)
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (1.265174ms)
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS (0.083198ms)
✔ a role without role.end or organization.change gets neither tool, and each tool follows its own grant (5.089895ms)
✔ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (0.840647ms)
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (1.562099ms)
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (0.766939ms)
✔ a coder with a tracker gets its own task tools and no task_reassign (0.794408ms)
✔ launch only when the business's launch block names the instance as launcher (1.458379ms)
✔ an action outside the instance's authority has no tool (0.821668ms)
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (3.303109ms)
✔ callTool: one JSON line out, the result back, a refusal rejects (7.841259ms)
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.984775ms)
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.187672ms)
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.541918ms)
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (2.331519ms)
ℹ tests 18
ℹ suites 0
ℹ pass 18
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 114.813846
@@ -0,0 +1,9 @@
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (2.2084ms)
ℹ tests 1
ℹ suites 0
ℹ pass 1
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 53.649613
@@ -0,0 +1,12 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (94.302279ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (87.195651ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (37.300488ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (40.068752ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 310.422428
@@ -0,0 +1,13 @@
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (44.797845ms)
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (63.015363ms)
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (48.195716ms)
✔ migration refuses mismatched source metadata without changing schema or evidence (32.217971ms)
✔ offline command migrates only the supplied fixture root and reports usage errors (115.900551ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 356.813643
@@ -0,0 +1,9 @@
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (66.701474ms)
ℹ tests 1
ℹ suites 0
ℹ pass 1
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 120.991752
@@ -0,0 +1,15 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (62.748618ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.360915ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (55.153761ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (98.755688ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (27.560482ms)
✔ path history is bounded at 100 and explicitly marks truncation (681.120229ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (31.150921ms)
ℹ tests 7
ℹ suites 0
ℹ pass 7
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1038.048427
@@ -0,0 +1,13 @@
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (82.226656ms)
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (23.699192ms)
✔ two real socket writes to one repository yield one commit and one project-busy refusal (39.647654ms)
✔ client disconnect during await tolerates late reply (35.818624ms)
✔ client disconnect during await tolerates late refusal (20.960688ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 259.163828
@@ -0,0 +1,11 @@
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (59.460229ms)
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (38.869362ms)
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (84.355853ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 238.375001
@@ -0,0 +1,10 @@
✔ every role sees read_spec, record writer follows its grant, citation schemas stay strict (9.482785ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (68.612006ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 151.095078
@@ -0,0 +1 @@
53ffbcadc4083f6560389585ab241c542257c0dcc80e651757aab5ff8e2ef483
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env python3
"""One fault per acceptance check. Preflight is read-only; batches require Sage's slot."""
import json, os, pathlib, signal, subprocess, sys
ROOT = pathlib.Path('/mnt/storage/src/mosaic-stack-rocko-138-r3b')
OUT = pathlib.Path(__file__).resolve().parent / 'mutants'
R = 'packages/project/src/read.mjs'
RT = 'packages/project/tests/read.test.mjs'
B = 'packages/bus/src/broker.mjs'
BT = 'packages/bus/tests/spec.test.mjs'
ST = 'packages/bus/tests/spec-socket.test.mjs'
HT = 'packages/harness/tests/spec-tools.test.mjs'
cases = []
def add(name, path, old, new, test):
cases.append(dict(check=name, path=path, old=old, new=new, test=test))
add('01-content-trailing-bytes', R, 'return text(await gitBytes(repo, [\'cat-file\', \'blob\', match[2]], MAX_BYTES));', 'return text(await gitBytes(repo, [\'cat-file\', \'blob\', match[2]], MAX_BYTES)).trimEnd();', RT)
add('02-file-commit-not-head', R, 'commit: log[0].commit, content', 'commit: head, content', RT)
add('03-historical-revision', R, 'const revision = commit === undefined ? head : commit;', 'const revision = head;', RT)
add('04-reachable-history', R, "await git(repo, ['merge-base', '--is-ancestor', revision, head]);", '/* reachability omitted */', RT)
add('05-full-commit-id', R, "if (typeof revision !== 'string' || !SHA.test(revision))", 'if (false)', RT)
add('06-read-path-confinement', R, r"if (typeof path !== 'string' || !(path === 'spec/north-star.md' || /^docs\/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.md$/.test(path)))", 'if (false)', RT)
add('07-strict-utf8', R, '{ fatal: true, ignoreBOM: true }', '{ fatal: false, ignoreBOM: true }', RT)
add('08-no-nul', R, "if (value.includes('\\0'))", 'if (false)', RT)
add('09-blob-size', R, 'if (!Number.isSafeInteger(size) || size < 0 || size > MAX_BYTES)', 'if (false)', RT)
add('10-regular-blob-mode', R, '(100644|100755) blob', '(100644|100755|120000) blob', RT)
add('11-project-identity', R, 'metadata.business !== business.id', 'false', RT)
add('12-repository-validation', R, ' await inspectGit(repo);', ' /* repository validation omitted */', RT)
add('13-log-page-bound', R, 'log: log.slice(0, 100)', 'log: log.slice(0, 101)', RT)
add('14-log-truncation', R, 'truncated: log.length > 100', 'truncated: false', RT)
add('15-human-confirmation', R, 'result.author.name === args.business.human', 'true', RT)
add('16-preserve-bom', R, 'ignoreBOM: true', 'ignoreBOM: false', RT)
add('17-read-argument-keys', R, "if (!args || typeof args !== 'object' || Array.isArray(args) || Object.keys(args).some(k => !allowed.includes(k)))", 'if (false)', RT)
add('18-invalid-revision-refusal-code', R, "fail('project-read-commit', 'commit is not reachable from HEAD')", "fail('project-git', 'commit is not reachable from HEAD')", RT)
add('19-stale-citation', B, "if (args.spec_commit !== spec.commit) fail('stale-spec');", '/* stale citation check omitted */', BT)
add('20-unconfirmed-citation', B, "if (!spec.confirmed) fail('spec-unconfirmed');", '/* human confirmation omitted */', BT)
add('21-partial-citation', B, "if (typeof args.project !== 'string' || args.spec_path !== 'spec/north-star.md' ||\n typeof args.spec_commit !== 'string' || !/^[0-9a-f]{40}$/.test(args.spec_commit))", 'if (false)', BT)
add('22-persist-spec-commit', B, ' spec?.commit ?? null,', ' null,', BT)
add('23-persist-spec-path', B, ' spec?.path ?? null,', ' null,', BT)
add('24-uncited-raises-still-valid', B, "if ((a.spec_path !== undefined || a.spec_commit !== undefined) && !spec)", 'if (!spec)', BT)
add('25-session-author', B, 'definition: business.roles[s.role].definition, instance: s.role', 'definition: business.roles[s.role].definition, instance: business.human', BT)
add('26-record-spec-refusal', 'packages/project/src/index.mjs', "if (path === 'spec' || path.startsWith('spec/'))", 'if (false)', BT)
add('27-writer-cannot-accept-author', B, "keys(args, ['project', 'path', 'record', 'decision'], ['project', 'path', 'record']);", "keys(args, ['project', 'path', 'record', 'decision', 'author'], ['project', 'path', 'record']);", BT)
add('28-write-authority-before-effect', B, "this.#store.transaction(() => this.#checkAuthority(s, 'record.write', authority));", '/* pre-write authority omitted */', BT)
add('29-write-commit-receipt', B, '{ project: args.project, path: result.path, commit: result.commit }', '{ project: args.project, path: result.path, commit: null }', BT)
p = 'packages/bus/src/server.mjs'
old = "if (r.verb === 'spec.read' || r.verb === 'record.write' ||\n (r.verb === 'decision.raise' && (Object.hasOwn(r.args ?? {}, 'spec_path') || Object.hasOwn(r.args ?? {}, 'spec_commit'))))"
add('30-await-only-project-effects', p, old, 'if (false)', ST)
add('31-async-own-refusal-code', p, "e => { if (!socket.destroyed) finish({ ok: false, error: e instanceof BusError ? e.code : 'invalid-envelope' }); }", "e => { if (!socket.destroyed) finish({ ok: false, error: 'invalid-envelope' }); }", ST)
add('32-live-transient-proof', p, "Promise.resolve().then(() => broker.request(cap, { verb: r.verb, args: r.args ?? {} })).then(", "if (own) broker.disconnect(own);\n Promise.resolve().then(() => broker.request(cap, { verb: r.verb, args: r.args ?? {} })).then(", ST)
add('33-concurrent-write-refusal', 'packages/project/src/index.mjs', "fd = openSync(lock, 'wx', 0o600);", "fd = openSync(lock, 'w', 0o600);", ST)
p = 'packages/harness/src/tools.mjs'
add('34-read-for-every-role', p, ' add("read_spec",', ' if (held.has("record.write")) add("read_spec",', HT)
add('35-writer-follows-grant', p, 'if (held.has("record.write"))', 'if (true)', HT)
add('36-typed-spec-path', p, 'const: "spec/north-star.md"', 'const: "docs/design.md"', HT)
add('37-typed-writer-path', p, 'pattern: "^(docs/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\\\\.md|(requirements|decisions)/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\\\\.json)$"', 'pattern: ".*"', HT)
add('38-migration-runs-new-step', 'packages/bus/src/store.mjs', ' this.#db.exec(step.sql);', " if (step.from !== '3e') this.#db.exec(step.sql);", 'packages/bus/tests/spec-migration.test.mjs')
add('39-preserve-old-evidence', 'packages/bus/src/store.mjs', ' step.initialize?.(this);', " step.initialize?.(this);\n if (step.from === '3e') this.#db.exec(\"DROP TRIGGER decision_events_no_delete; DELETE FROM decision_events; CREATE TRIGGER decision_events_no_delete BEFORE DELETE ON decision_events BEGIN SELECT RAISE(ABORT, 'decision_events is append-only'); END\");", 'packages/bus/tests/spec-migration.test.mjs')
add('40-future-step-chaining', 'packages/bus/src/store.mjs', 'while (version !== SCHEMA_VERSION)', 'if (version !== SCHEMA_VERSION)', 'packages/bus/tests/comment-migration.test.mjs')
roles = ['assistant', 'chief-executive-officer', 'chief-financial-officer', 'chief-information-officer',
'chief-information-security-officer', 'chief-marketing-officer', 'chief-of-staff', 'coder', 'cto', 'pm', 'reviewer']
for i, role in enumerate(roles, 41):
add(f'{i:02}-record-grant-{role}', f'roles/{role}.json', ', "record.write"', '', 'packages/business/tests/record-grants.test.mjs')
add('52-no-adapter-refusal', B, "if (!this.#project) fail('project-not-configured');", "if (false) fail('project-not-configured');", 'packages/bus/tests/project-runtime.test.mjs')
add('53-runtime-passes-adapter', 'packages/bus/src/runtime.mjs', """ project: {
readSpec: context => projectModule.readSpec({ ...context, dataRoot }),
writeRecord: context => projectModule.writeRecord({ ...context, dataRoot }),
ProjectError: projectModule.ProjectError,
},
""", '', 'packages/bus/tests/project-runtime.test.mjs')
add('54-broker-import-closure', B, "import { randomUUID, randomBytes } from 'node:crypto';", "import { randomUUID, randomBytes } from 'node:crypto';\nimport { dirname } from 'node:path';", 'packages/bus/tests/project-runtime.test.mjs')
for c in cases:
assert (ROOT / c['path']).read_text().count(c['old']) == 1, c['check']
if '--preflight' in sys.argv:
print('PREFLIGHT_OK', len(cases)); sys.exit(0)
OUT.mkdir(exist_ok=True)
rows = []
def stop_tree(pid):
# Git's own runner creates process groups too. Capture descendants before killing the parent.
descendants = {pid}
for _ in range(8):
before = set(descendants)
for entry in pathlib.Path('/proc').iterdir():
if not entry.name.isdigit(): continue
try:
fields = (entry / 'stat').read_text().split(') ', 1)[1].split()
if int(fields[1]) in descendants: descendants.add(int(entry.name))
except (OSError, ValueError, IndexError): pass
if before == descendants: break
for child in descendants:
try: os.killpg(child, signal.SIGKILL)
except ProcessLookupError: pass
for c in cases:
file = ROOT / c['path']; original = file.read_bytes(); process = None
try:
file.write_text(original.decode().replace(c['old'], c['new']))
with (OUT / (c['check'] + '.log')).open('w') as log:
process = subprocess.Popen(['node', '--test', c['test']], cwd=ROOT,
env={**os.environ, 'DOCKER_HOST': 'unix:///nonexistent.sock'}, stdout=log,
stderr=subprocess.STDOUT, start_new_session=True)
try: rc = process.wait(timeout=180)
except subprocess.TimeoutExpired: stop_tree(process.pid); process.wait(); rc = 'timeout'
content = (OUT / (c['check'] + '.log')).read_text()
invalid = any(x in content for x in ['SyntaxError:', 'ERR_MODULE_NOT_FOUND'])
verdict = 'INVALID' if invalid else 'TIMEOUT' if rc == 'timeout' else 'SURVIVED' if rc == 0 else 'KILLED'
rows.append({k: c[k] for k in ['check', 'path', 'test']} | {'result': verdict, 'exit': rc})
(OUT / 'results.json').write_text(json.dumps(rows, indent=2) + '\n')
print(c['check'], verdict, rc, flush=True)
finally:
if process is not None and process.poll() is None: stop_tree(process.pid); process.wait()
file.write_bytes(original)
if verdict != 'KILLED': sys.exit(1)
@@ -0,0 +1,58 @@
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (55.139412ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (38.985626ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (67.782527ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (122.686054ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (33.753638ms)
✔ path history is bounded at 100 and explicitly marks truncation (812.523803ms)
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (36.163058ms)
ℹ tests 7
ℹ suites 0
ℹ pass 5
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1220.90348
✖ failing tests:
test at packages/project/tests/read.test.mjs:25:1
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (55.139412ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ '# Spec\n\nKeep this.'
- '# Spec\n\nKeep this.\n\n'
^
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:31:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '# Spec\n\nKeep this.',
expected: '# Spec\n\nKeep this.\n\n',
operator: 'strictEqual',
diff: 'simple'
}
test at packages/project/tests/read.test.mjs:103:1
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (36.163058ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ '# North star 🧭'
- '# North star 🧭\r\n\r\n'
^
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:107:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '# North star 🧭',
expected: '# North star 🧭\r\n\r\n',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,37 @@
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (55.45924ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (38.974843ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (73.557275ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (119.462236ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (35.963156ms)
✔ path history is bounded at 100 and explicitly marks truncation (766.003568ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.273292ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1176.569807
✖ failing tests:
test at packages/project/tests/read.test.mjs:25:1
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (55.45924ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ 'fc1cf6121da8ade8b9464ac1af78e410c2a7bd20'
- '8c09a6b5a31c9f43a4e0b5e988701b16ea926aee'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:34:80)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'fc1cf6121da8ade8b9464ac1af78e410c2a7bd20',
expected: '8c09a6b5a31c9f43a4e0b5e988701b16ea926aee',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,51 @@
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.417534ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (36.45928ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (50.740895ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (111.498189ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (32.280564ms)
✔ path history is bounded at 100 and explicitly marks truncation (763.244567ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.216722ms)
ℹ tests 7
ℹ suites 0
ℹ pass 5
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1150.28506
✖ failing tests:
test at packages/project/tests/read.test.mjs:25:1
✖ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.417534ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ 'c7e18a56d330bd280bf4eed0efa3147df4f799f5'
- 'dd06797fee9ae3bbf36cf2481e620d3c2b1471dc'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:43:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'c7e18a56d330bd280bf4eed0efa3147df4f799f5',
expected: 'dd06797fee9ae3bbf36cf2481e620d3c2b1471dc',
operator: 'strictEqual',
diff: 'simple'
}
test at packages/project/tests/read.test.mjs:56:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (50.740895ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:63:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-commit' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.701079ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (34.901426ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (72.418083ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (108.010734ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (31.436937ms)
✔ path history is bounded at 100 and explicitly marks truncation (768.879186ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (32.480297ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1166.833418
✖ failing tests:
test at packages/project/tests/read.test.mjs:56:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (72.418083ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:66:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-commit' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (68.727147ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (34.829686ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (54.81965ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (110.523252ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (31.403517ms)
✔ path history is bounded at 100 and explicitly marks truncation (752.836275ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.68497ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1141.823232
✖ failing tests:
test at packages/project/tests/read.test.mjs:56:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (54.81965ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:63:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-commit' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,46 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (68.573793ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.433508ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (47.222266ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (112.75651ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (34.004204ms)
✔ path history is bounded at 100 and explicitly marks truncation (770.310672ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.330747ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1154.854781
✖ failing tests:
test at packages/project/tests/read.test.mjs:56:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (47.222266ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'project-git'
- code: 'project-read-path'
}
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:61:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: Error: project-git: local git ls-tree refused (fatal: ../outside.md: '../outside.md' is outside repository at '/mnt/storage/scratch/tmp/project-spec-read-DOFHMW/records')
at git (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/git.mjs:14:25)
at async blob (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:19:17)
at async Module.readProjectFile (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:49:19)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:61:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'project-read-path' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (67.82591ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (52.13902ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (83.851804ms)
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (48.222102ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (33.401497ms)
✔ path history is bounded at 100 and explicitly marks truncation (807.221651ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (35.697852ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1180.238669
✖ failing tests:
test at packages/project/tests/read.test.mjs:69:1
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (48.222102ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:74:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-content' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,32 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (71.150402ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.659952ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (64.449719ms)
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (67.923698ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (33.923624ms)
✔ path history is bounded at 100 and explicitly marks truncation (795.600293ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (36.36683ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1161.385101
✖ failing tests:
test at packages/project/tests/read.test.mjs:69:1
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (67.923698ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:74:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-content' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,44 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (68.422432ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.169693ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (63.626987ms)
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (99.460352ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (37.210188ms)
✔ path history is bounded at 100 and explicitly marks truncation (799.592461ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (36.755851ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1192.695342
✖ failing tests:
test at packages/project/tests/read.test.mjs:69:1
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (99.460352ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'project-git'
- code: 'project-read-content'
}
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:74:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: Error: project-git: bounded local Git read refused
at ChildProcess.finish (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/git.mjs:73:40)
at ChildProcess.emit (node:events:514:20)
at maybeClose (node:internal/child_process:1125:16)
at Socket.<anonymous> (node:internal/child_process:497:11)
at Socket.emit (node:events:514:20)
at Pipe.<anonymous> (node:net:362:12),
expected: { code: 'project-read-content' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (73.09995ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (40.390091ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (63.313198ms)
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (117.740816ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (36.026676ms)
✔ path history is bounded at 100 and explicitly marks truncation (785.92812ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (35.108274ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1203.362447
✖ failing tests:
test at packages/project/tests/read.test.mjs:69:1
✖ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (117.740816ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:80:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-content' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.491014ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (34.815015ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (64.586025ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (116.389327ms)
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (36.299911ms)
✔ path history is bounded at 100 and explicitly marks truncation (767.835383ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.276783ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1177.476879
✖ failing tests:
test at packages/project/tests/read.test.mjs:83:1
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (36.299911ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:89:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-invalid' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,48 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (64.408178ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (33.894339ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (52.711332ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (104.610273ms)
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (37.433795ms)
✔ path history is bounded at 100 and explicitly marks truncation (843.376156ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (32.519879ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1220.183508
✖ failing tests:
test at packages/project/tests/read.test.mjs:83:1
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (37.433795ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'project-invalid'
- code: 'project-remote'
}
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:91: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: Error: project-invalid: committed project identity does not match context
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:6:41)
at readProjectFile (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:48:5)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Module.readSpec (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:68:18)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:91:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'project-remote' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,34 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (68.60952ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.333954ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (64.765305ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (115.698484ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (33.865086ms)
✖ path history is bounded at 100 and explicitly marks truncation (785.974015ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (35.53488ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1191.206869
✖ failing tests:
test at packages/project/tests/read.test.mjs:94:1
✖ path history is bounded at 100 and explicitly marks truncation (785.974015ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
101 !== 100
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:98:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 101,
expected: 100,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,34 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.379063ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.372835ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (66.988726ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (117.173705ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (32.680342ms)
✖ path history is bounded at 100 and explicitly marks truncation (784.35618ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.861842ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1194.9876
✖ failing tests:
test at packages/project/tests/read.test.mjs:94:1
✖ path history is bounded at 100 and explicitly marks truncation (784.35618ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
false !== true
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:99:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,34 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (68.37198ms)
✖ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.53368ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (64.824482ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (115.728805ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (34.101077ms)
✔ path history is bounded at 100 and explicitly marks truncation (774.642157ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (35.20603ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1178.240978
✖ failing tests:
test at packages/project/tests/read.test.mjs:48:1
✖ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (35.53368ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
true !== false
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:52:47)
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: true,
expected: false,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,36 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (70.096461ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (38.350647ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (63.789155ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (113.687208ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (32.424139ms)
✔ path history is bounded at 100 and explicitly marks truncation (884.939835ms)
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (51.510458ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1310.318327
✖ failing tests:
test at packages/project/tests/read.test.mjs:103:1
✖ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (51.510458ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ '# North star 🧭\r\n\r\n'
- '# North star 🧭\r\n\r\n'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:107:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '# North star 🧭\r\n\r\n',
expected: '# North star 🧭\r\n\r\n',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,32 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (90.367514ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (48.124687ms)
✔ shared file reader exposes committed docs and refuses path/revision injection or another history (75.418631ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (184.624224ms)
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (38.030607ms)
✔ path history is bounded at 100 and explicitly marks truncation (1134.940036ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (51.038808ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1690.741445
✖ failing tests:
test at packages/project/tests/read.test.mjs:83:1
✖ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (38.030607ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:85:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'project-read-path' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,46 @@
✔ spec reads exact committed content and its path commit/log, not dirty bytes or a later docs commit (77.952371ms)
✔ latest agent spec edit is visible but never confirmed or replaced by an earlier human version (41.483017ms)
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (55.296258ms)
✔ reader rejects missing paths, links, invalid UTF-8, NUL and oversized committed blobs (136.450192ms)
✔ reader refuses mismatched committed project identity, unsafe config and unknown argument keys (48.101928ms)
✔ path history is bounded at 100 and explicitly marks truncation (907.640116ms)
✔ committed UTF-8 BOM, Unicode and trailing newlines are returned without normalization (34.147656ms)
ℹ tests 7
ℹ suites 0
ℹ pass 6
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1362.911179
✖ failing tests:
test at packages/project/tests/read.test.mjs:56:1
✖ shared file reader exposes committed docs and refuses path/revision injection or another history (55.296258ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'project-git'
- code: 'project-read-commit'
}
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:63:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: Error: project-git: commit is not reachable from HEAD
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:6:41)
at readProjectFile (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:43:13)
at async Module.readSpec (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/src/read.mjs:68:18)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/project/tests/read.test.mjs:63:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'project-read-commit' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,28 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (106.409062ms)
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (50.472278ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (44.59276ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (51.69932ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 313.581311
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:23:1
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (50.472278ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:26:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'stale-spec' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,29 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (102.969708ms)
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (77.781973ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (44.802271ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (49.062725ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 335.802116
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:23:1
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (77.781973ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:28:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'spec-unconfirmed' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,44 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (106.127587ms)
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (96.639621ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (47.444577ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (50.568469ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 361.439294
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:23:1
✖ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (96.639621ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'spec-unconfirmed'
- code: 'invalid-spec-citation'
}
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:31:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: Error: spec-unconfirmed
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:84:9)
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:974:28)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:31:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'invalid-spec-citation' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,33 @@
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (52.091662ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (103.870959ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (44.362126ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (53.845249ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 313.598598
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:9:1
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (52.091662ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ null
- '4408766e498a481085f0f10af5dadb0c048a222e'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:13:64)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: null,
expected: '4408766e498a481085f0f10af5dadb0c048a222e',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,34 @@
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (54.770312ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (108.490983ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (43.522369ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (49.98387ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 317.625487
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:9:1
✖ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (54.770312ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ null
- 'spec/north-star.md'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:13:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: null,
expected: 'spec/north-star.md',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,30 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (107.404562ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (106.182499ms)
✖ uncited raises retain their synchronous path and spec read is available to any held role in its business (24.99614ms)
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (50.535048ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 348.902517
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:38:1
✖ uncited raises retain their synchronous path and spec read is available to any held role in its business (24.99614ms)
Error: invalid-spec-citation
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:84:9)
at #dispatch (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:1164:20)
at file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:930:38
at Store.transaction (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/store.mjs:242:22)
at Broker.request (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:924:26)
at call (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-fixtures.mjs:32:49)
at Object.raise (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-fixtures.mjs:33:25)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:40:15)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
code: 'invalid-spec-citation'
}
@@ -0,0 +1,34 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (102.421591ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (107.061987ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (45.59718ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (45.048636ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 361.103481
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:51:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (45.048636ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ 'coder.jason'
- 'coder.coder'
^
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:54:10)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'coder.jason',
expected: 'coder.coder',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,41 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (103.492772ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (101.190757ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (45.408308ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (51.618988ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 362.78572
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:51:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (51.618988ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'project-record-path'
- code: 'project-spec-human-only'
}
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:56: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: Error: project-record-path
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:983:78)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:56:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'project-spec-human-only' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,28 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (101.0845ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (100.590506ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (42.516357ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (66.867138ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 374.714949
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:51:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (66.867138ms)
AssertionError [ERR_ASSERTION]: Missing expected rejection.
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:57:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { code: 'invalid-request' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,44 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (105.090829ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (103.31354ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (44.909325ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (70.43652ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 385.120053
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:51:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (70.43652ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'outcome-unknown'
- code: 'decision-required'
}
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:58: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: Error: outcome-unknown
at fail (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:84:9)
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:967:19)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async waitForActual (node:assert:615:5)
at async strict.rejects (node:assert:738:25)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:58:3)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
expected: { code: 'decision-required' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,34 @@
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (106.063813ms)
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (102.586834ms)
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (43.144914ms)
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (51.945915ms)
ℹ tests 4
ℹ suites 0
ℹ pass 3
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 362.043321
✖ failing tests:
test at packages/bus/tests/spec.test.mjs:51:1
✖ record writes bind the session author, require authority and refuse spec and impersonation paths (51.945915ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ null
- 'd82142e58fa25637d84d37f42c7a4474310ccc2a'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec.test.mjs:60:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: null,
expected: 'd82142e58fa25637d84d37f42c7a4474310ccc2a',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,60 @@
✖ real socket awaits spec reads, record writes and cited raises; other requests still return normally (41.633054ms)
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (26.996331ms)
✖ two real socket writes to one repository yield one commit and one project-busy refusal (30.720877ms)
✔ client disconnect during await tolerates late reply (45.209346ms)
✖ client disconnect during await tolerates late refusal (25.811102ms)
ℹ Error: Test "real socket awaits spec reads, record writes and cited raises; other requests still return normally" at packages/bus/tests/spec-socket.test.mjs:15:1 generated asynchronous activity after the test ended. This activity created the error "Error: storage-unavailable" and would have caused the test to fail, but instead triggered an unhandledRejection event.
ℹ Error: Test "two real socket writes to one repository yield one commit and one project-busy refusal" at packages/bus/tests/spec-socket.test.mjs:43:1 generated asynchronous activity after the test ended. This activity created the error "Error: storage-unavailable" and would have caused the test to fail, but instead triggered an unhandledRejection event.
ℹ tests 5
ℹ suites 0
ℹ pass 1
ℹ fail 4
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 231.671888
✖ failing tests:
test at packages/bus/tests/spec-socket.test.mjs:15:1
✖ real socket awaits spec reads, record writes and cited raises; other requests still return normally (41.633054ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ undefined
- '5ee7eb9d9a83e9b26235d009641cfb0ce3df8ff7'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-socket.test.mjs:18:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: undefined,
expected: '5ee7eb9d9a83e9b26235d009641cfb0ce3df8ff7',
operator: 'strictEqual',
diff: 'simple'
}
test at packages/bus/tests/spec-socket.test.mjs:28:1
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (26.996331ms)
Error: project-not-declared
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:983:78)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 'project-not-declared'
}
test at packages/bus/tests/spec-socket.test.mjs:43:1
✖ two real socket writes to one repository yield one commit and one project-busy refusal (30.720877ms)
Error: project-busy
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:983:78)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 'project-busy'
}
test at packages/bus/tests/spec-socket.test.mjs:55:38
✖ client disconnect during await tolerates late refusal (25.811102ms)
Error: project-not-declared
at #requestProject (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/broker.mjs:983:78) {
code: 'project-not-declared'
}
@@ -0,0 +1,63 @@
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (94.355488ms)
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (26.849735ms)
✖ two real socket writes to one repository yield one commit and one project-busy refusal (46.055563ms)
✔ client disconnect during await tolerates late reply (43.411423ms)
✔ client disconnect during await tolerates late refusal (25.848671ms)
ℹ tests 5
ℹ suites 0
ℹ pass 3
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 297.629473
✖ failing tests:
test at packages/bus/tests/spec-socket.test.mjs:28:1
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (26.849735ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'invalid-envelope'
- code: 'project-not-declared'
}
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-socket.test.mjs:37: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: Error: invalid-envelope
at Socket.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/client.mjs:41:17)
at Socket.emit (node:events:514:20)
at addChunk (node:internal/streams/readable:575:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
at Readable.push (node:internal/streams/readable:406:5)
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23),
expected: { code: 'project-not-declared' },
operator: 'rejects',
diff: 'simple'
}
test at packages/bus/tests/spec-socket.test.mjs:43:1
✖ two real socket writes to one repository yield one commit and one project-busy refusal (46.055563ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ 'invalid-envelope'
- 'project-busy'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-socket.test.mjs:51:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'invalid-envelope',
expected: 'project-busy',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,43 @@
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (100.612983ms)
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (29.190274ms)
✔ two real socket writes to one repository yield one commit and one project-busy refusal (47.260278ms)
✔ client disconnect during await tolerates late reply (43.135548ms)
✔ client disconnect during await tolerates late refusal (25.699343ms)
ℹ tests 5
ℹ suites 0
ℹ pass 4
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 304.176733
✖ failing tests:
test at packages/bus/tests/spec-socket.test.mjs:28:1
✖ real socket preserves asynchronous refusal codes and disconnects its transient proof (29.190274ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
Comparison {
+ code: 'unauthenticated'
- code: 'agent-required'
}
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-socket.test.mjs:38: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: Error: unauthenticated
at Socket.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/client.mjs:41:17)
at Socket.emit (node:events:514:20)
at addChunk (node:internal/streams/readable:575:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
at Readable.push (node:internal/streams/readable:406:5)
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23),
expected: { code: 'agent-required' },
operator: 'rejects',
diff: 'simple'
}
@@ -0,0 +1,33 @@
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (96.957718ms)
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (28.807081ms)
✖ two real socket writes to one repository yield one commit and one project-busy refusal (52.149382ms)
✔ client disconnect during await tolerates late reply (43.28484ms)
✔ client disconnect during await tolerates late refusal (26.971991ms)
ℹ tests 5
ℹ suites 0
ℹ pass 4
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 312.25036
✖ failing tests:
test at packages/bus/tests/spec-socket.test.mjs:43:1
✖ two real socket writes to one repository yield one commit and one project-busy refusal (52.149382ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
0 !== 1
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-socket.test.mjs:49:10)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async Test.run (node:internal/test_runner/test:1409:7)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 0,
expected: 1,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (13.220604ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (83.472939ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 178.764655
✖ failing tests:
test at packages/harness/tests/spec-tools.test.mjs:7:1
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (13.220604ms)
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(tools.some(t => t.name === 'read_spec'))
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/harness/tests/spec-tools.test.mjs:29:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '==',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (13.435825ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (86.643905ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 180.013102
✖ failing tests:
test at packages/harness/tests/spec-tools.test.mjs:7:1
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (13.435825ms)
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(!tools.some(t => t.name === 'write_record'))
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/harness/tests/spec-tools.test.mjs:30:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '==',
diff: 'simple'
}
@@ -0,0 +1,33 @@
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.187469ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (79.628078ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 166.789784
✖ failing tests:
test at packages/harness/tests/spec-tools.test.mjs:7:1
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.187469ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ 'docs/design.md'
- 'spec/north-star.md'
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/harness/tests/spec-tools.test.mjs:23:12)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'docs/design.md',
expected: 'spec/north-star.md',
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,31 @@
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.422958ms)
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (87.087234ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 173.901002
✖ failing tests:
test at packages/harness/tests/spec-tools.test.mjs:7:1
✖ every role sees read_spec, record writer follows its grant, citation schemas stay strict (6.422958ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
true !== false
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/harness/tests/spec-tools.test.mjs:19:12)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: true,
expected: false,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,24 @@
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (58.871201ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 114.424763
✖ failing tests:
test at packages/bus/tests/spec-migration.test.mjs:51:1
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (58.871201ms)
Error: schema-mismatch
at file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/store.mjs:202:61
at Store.transaction (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/store.mjs:242:22)
at #migrateSchema (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/store.mjs:193:12)
at new Store (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/src/store.mjs:160:55)
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-migration.test.mjs:54:17)
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)
@@ -0,0 +1,95 @@
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (63.113576ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 117.120835
✖ failing tests:
test at packages/bus/tests/spec-migration.test.mjs:51:1
✖ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (63.113576ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
{
+ decision_events: [],
- decision_events: [
- [Object: null prototype] {
- at: '2026-10-15T00:00:00.000Z',
- by: 'jason',
- choice: 'yes',
- decision: 'decision',
- note: null,
- op: 'resolved',
- seq: 1,
- via: null
- }
- ],
decisions: [
[Object: null prototype] {
action: 'deploy',
at: '2026-10-15T00:00:00.000Z',
blocking: 0,
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-138-r3b/packages/bus/tests/spec-migration.test.mjs:61:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: {
meta: [ [Object] ],
events: [ [Object] ],
sqlite_sequence: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object]
],
role_claims: [ [Object] ],
decisions: [ [Object] ],
decision_events: [],
messages: [ [Object] ],
deliveries: [ [Object] ],
task_snapshots: [ [Object] ],
task_comment_cursors: [ [Object] ],
projects: [ [Object] ],
threads: [ [Object] ],
thread_claims: [ [Object] ],
message_threads: [ [Object] ],
thread_opens: [ [Object] ]
},
expected: {
meta: [ [Object] ],
events: [ [Object] ],
sqlite_sequence: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object]
],
role_claims: [ [Object] ],
decisions: [ [Object] ],
decision_events: [ [Object] ],
messages: [ [Object] ],
deliveries: [ [Object] ],
task_snapshots: [ [Object] ],
task_comment_cursors: [ [Object] ],
projects: [ [Object] ],
threads: [ [Object] ],
thread_claims: [ [Object] ],
message_threads: [ [Object] ],
thread_opens: [ [Object] ]
},
operator: 'deepStrictEqual',
diff: 'simple'
}

Some files were not shown because too many files have changed in this diff Show More