agents: Rocko row 122 round 2 packet after row 119 and review fixes
This commit is contained in:
@@ -155,3 +155,16 @@ himself in Mos's window with the PM run idle and the re-pin in that same window.
|
||||
Both exact Claude table entries use provider `anthropic`, per Mos via Sage
|
||||
sage-0254. Map pm, cto and reviewer to opus; coder to sonnet. Keep exact model
|
||||
limits four/four, no total or provider limit, and leave execution.provider alone.
|
||||
|
||||
## Round 2 rulings (Sage sage-0269; row 119 landed)
|
||||
|
||||
The post-119 launcher is chief, with assistant holder mos. The packet covers
|
||||
both new instances and all four existing ones. For inherited models the
|
||||
print-only command reads the existing system config through loadSystem and
|
||||
systemVars, preserving both provider and exact model; invalid/missing config
|
||||
refuses. Fully explicit input still needs no system-config read. Nothing writes
|
||||
that config. Initial role entry, migration-output installation and re-pin happen
|
||||
in one Mos window with the PM idle; Sage supplies the first-chief-session step.
|
||||
Uncertain transaction evidence gates organization writes only. Startup, launch
|
||||
and read paths validate the whole file on disk without consulting receipts;
|
||||
write-time recovery still refuses uncertainty until reconciled.
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
# Row 122 / #1616 — round 2
|
||||
|
||||
Base: 0afbd818e (contains row119 94e41ae29 and its roles). Detached candidate:
|
||||
/mnt/storage/src/mosaic-stack-rocko-122-r2. Source is uncommitted; no push,
|
||||
live unit/organization/Settings action or system-config write is authorized.
|
||||
Sage sage-0269 governs this round, including F3 and recovery rulings. Filbert's
|
||||
round1 verdict is #1616 comment28537. Round2 reopened at queue rev1248.
|
||||
|
||||
## Changes from round 1 and per-path merge (F1)
|
||||
|
||||
All nine overlaps were inspected against row119. Six had textual conflicts;
|
||||
three applied without conflict and were checked by hand. Both rows' intent stays:
|
||||
|
||||
| Overlap path | Row119 kept | Row122 kept / merge |
|
||||
| --- | --- | --- |
|
||||
| packages/business/examples/mosaic-stack.example.json | chief and assistant (holder mos), launch.by chief | Six explicit model-table selections, exact provider/model table and editable four/four limits |
|
||||
| packages/business/README.md | Chief/assistant duties, chief-only role.launch, PM gated | New schema example and shared write path; initial human entry distinguished from later human Settings writes; write-time recovery wording |
|
||||
| packages/business/tests/business.test.mjs | Chief instance, launch.by chief, role authority refusals | Exact schema assertions, zero/unset/large limit values, invalid table/count refusal |
|
||||
| packages/business/tests/chief-of-staff.test.mjs | Approved role.launch authority, contract pins and launch.by PM refusal | Valid new-shape launch block and launchDoc(INSTANCE) expectation instead of old max |
|
||||
| packages/business/tests/helpers.mjs | Chief instance without credentials/tracker and default chief launcher | launchDoc table and exact test limits (2/4 fixture values, not policy ceilings) |
|
||||
| packages/business/tests/resolve.test.mjs | Chief launch authority and PM gated checks / provenance | Model-table entry for the overridden agent-model selector |
|
||||
| packages/cli/tests/launcher.test.mjs | Actual chief startup, chief launch tool, PM cannot launch, existing lifecycle/checkouts | Exact provider counters and zero model cap; first actual chief launch now also starts over uncertain receipt evidence |
|
||||
| packages/harness/tests/pi-session.test.mjs | Parameterized chief/PM tool authority and selected instance | Probe-model table entry attached to the selected instance |
|
||||
| packages/webui/tests/reads.test.mjs | Chief within-role, PM gated, chief launcher | Exact limits/model-table assertions, external model path redaction and Settings projection |
|
||||
|
||||
The additional assistant.test.mjs compatibility edit retains its refusal of
|
||||
assistant as launch.by using a valid new-shape block, so an old-schema error
|
||||
cannot accidentally satisfy that authority check. The first gate found one
|
||||
old chief launch-object assertion; its failure log is retained and the complete
|
||||
gate restarted after the assertion/assistant fixture update.
|
||||
|
||||
## F2 / F3: complete mapping and verified inheritance
|
||||
|
||||
The shipped map includes all six role instances: chief, assistant, pm, cto and
|
||||
reviewer select Anthropic opus; coder stays on Anthropic sonnet, per Sage's
|
||||
known Jason-file facts. The raw row119 example inherits for all six roles;
|
||||
its separate regression mapping selects opus throughout against an Anthropic
|
||||
Opus fixture system. Sage confirmed this distinction in sage-0273.
|
||||
|
||||
The CLI test reads the exact 94e41ae29 example from git, fills placeholder IDs
|
||||
and dates, and passes a fixture copy of this base's roles/ (byte-identical to
|
||||
94e41ae29's role files) as --roles-dir. It migrates that inherited example,
|
||||
then a Jason-shaped variant with the four known explicit selections plus
|
||||
inherited chief/assistant. Both outputs validate under the post122 validator.
|
||||
The assistant holder and chief launcher are pinned. Wrong assistant Sonnet
|
||||
against an Opus system, wrong inherited provider, and missing/invalid system
|
||||
config refuse with organization bytes and mtime unchanged. Successful runs also
|
||||
leave config bytes and mtime unchanged.
|
||||
|
||||
For every inherited instance, migrate reads execution.provider/execution.model
|
||||
through loadSystem + systemVars, the existing config path and validator. The
|
||||
mapping must preserve both values exactly. The launchable family comparison
|
||||
uses that real previous model. Explicit role models retain their exact external
|
||||
model and use the supplied provider data; fully explicit input needs no config
|
||||
read. No bus is needed. No write helper or --write exists (decision145).
|
||||
|
||||
MIGRATION.md and jason-migration.patch.json now describe the combined window:
|
||||
Jason first adds row119's chief/assistant entries (assistant holder mos), with
|
||||
Researcher's proposed explicit claude-code / claude-opus-5-5 / high vars, and
|
||||
launch.by chief. He then runs migrate from the reviewed new copy, installs its
|
||||
complete output, then the re-pin follows. Sage supplies first-chief-session
|
||||
instructions separately. Assistant's model remains ordinary mapping data,
|
||||
which Jason can change with a correct table entry; no special case in code.
|
||||
|
||||
Jason's edit and the re-pin happen in one window Mos runs, with the PM run idle.
|
||||
|
||||
## F4 / F5: comments and reviewable code
|
||||
|
||||
Corrected business.mjs's obsolete never-writes comment; removed vocabulary.mjs's
|
||||
obsolete family ceiling comment. Reformatted organization.mjs and only the new
|
||||
limits block in broker.mjs, plus the new launch/migration/settings helpers,
|
||||
CLI limits handler and Settings POST handler. Organization and all four business
|
||||
helpers have no lines over 120 characters. Lock/revision/publication behavior
|
||||
remains pinned by the original mutants; recovery changes are separately tested.
|
||||
Broker constructor existing lines and message.send are untouched beyond r1's
|
||||
organization argument/member. No broker edit beyond round1 scope was needed,
|
||||
so Researcher's row120 constructor/send work remains separate.
|
||||
|
||||
## Recovery ruling: uncertainty gates writes only
|
||||
|
||||
Removed bus-start recovery. Organization reads validate the whole file and do
|
||||
not inspect/repair receipts. Atomic publication leaves either old or new whole
|
||||
bytes; normal launch checks still re-read and validate the document. A write
|
||||
holds the existing lock, reconciles prepared receipts by hashes and refuses
|
||||
uncertain/torn evidence. An operator-reconciled fixture can then write again.
|
||||
The runtime integration test starts a bus over uncertain evidence, reads its
|
||||
valid document, proves limits.set refuses without changing it, reconciles the
|
||||
fixture and proves a later write succeeds. The actual sandbox launcher test
|
||||
starts the first chief over uncertain evidence too. No live process is involved.
|
||||
|
||||
## Full gate and mutants
|
||||
|
||||
Sage sage-0274 granted the slot. busy.py returned CLEAR with exit0, chained with
|
||||
&& to the gate. The gate runs all 13 node packages outside queue (ledger direct),
|
||||
and every scripts/test-*.sh; queue's shell runs all its node tests. Each package
|
||||
serializes test files. DOCKER_HOST=unix:///nonexistent.sock except release/task,
|
||||
where it is unset for that run only. No daemon/socket/volume change. Worktree
|
||||
network cleanup and a cwd/path-scoped node/chromium sweep follow all runners.
|
||||
Two recurrences of the same known flake stop the run and are reported to Sage.
|
||||
|
||||
Full gate: 23/23 steps passed. All node cases below passed with zero skips or
|
||||
failures. Gate commands/exits are in gate/results.json; first assertion failure
|
||||
is retained separately and is not a known flake. No known flake recurred.
|
||||
|
||||
| Node package | Passed |
|
||||
| --- | ---: |
|
||||
| business | 86 |
|
||||
| bus | 159 |
|
||||
| seat | 132 |
|
||||
| harness | 84 |
|
||||
| cli | 195 |
|
||||
| webui (browser form included) | 112 |
|
||||
| control-board | 124 |
|
||||
| conversation | 182 |
|
||||
| ledger (direct) | 86 |
|
||||
| tasks | 92 |
|
||||
| runs | 43 |
|
||||
| mosaic | 69 |
|
||||
| discord | 183 |
|
||||
|
||||
| Shell suite | Passed |
|
||||
| --- | ---: |
|
||||
| auth | 15 |
|
||||
| conductor | 17 |
|
||||
| config | 24 |
|
||||
| discord | 78 (+183 embedded node cases) |
|
||||
| extension-package | 18 |
|
||||
| foundation | 44 |
|
||||
| land-work | 84 |
|
||||
| queue | 28 (+156 node cases) |
|
||||
| release | 14 |
|
||||
| task | 98 |
|
||||
|
||||
DOCKER_HOST was unset only for release and task; all Docker cases ran. Every
|
||||
other suite and all mutants used unix:///nonexistent.sock. The queue suite
|
||||
intentionally omits its two canonical-only live verify/render checks in this
|
||||
detached worktree. No other cases were skipped.
|
||||
|
||||
38/38 mutants killed, with no syntax/import kills or timeouts. Original33
|
||||
checks are retained over the reformatted sites; five new faults cover inherited
|
||||
exact model, inherited provider, required validated config, no recovery at
|
||||
startup, and uncertainty gating writes. See MUTANTS.md and per-site logs.
|
||||
Every mutant used its own process group; timeout kills the entire group and
|
||||
is a failure, never a kill. Candidate44/44 hashes and reverse patch check pass.
|
||||
|
||||
The post-run cwd/path-scoped node/chromium sweep was empty before and after.
|
||||
Removed mosaic-stack-rocko-122-r2_default successfully. All runners exited,
|
||||
and slot clear was sent to Sage at 2026-10-15 01:33:50 UTC. No further tests.
|
||||
|
||||
Candidate manifest SHA256:
|
||||
00b84e311475f97ced0d9a9599fba23a28442971ed15d8d489d9422d84a8812e
|
||||
(44 repo-root paths). Source stays uncommitted; build.patch reverse-check
|
||||
and every candidate hash match the frozen worktree.
|
||||
|
||||
Public/ landing requires Mos's go (123); live use requires a separate re-pin (109).
|
||||
@@ -0,0 +1,66 @@
|
||||
# Combined row 119 / row 122 window
|
||||
|
||||
These instructions describe human steps only. No agent reads or edits Jason's
|
||||
organization or system config. Packet values come from Sage sage-0252/0254,
|
||||
Researcher's reviewed row 119 proposal and Sage sage-0269/0273.
|
||||
|
||||
Prepare the reviewed new copy, this map and an unused converted-file destination
|
||||
before the window. The migration command must come from the new copy, with that
|
||||
copy's roles directory, even though the live wrapper still points to the old one.
|
||||
The map lives in the canonical packet, outside the runtime copy's path list.
|
||||
|
||||
Jason's edit and the re-pin happen in one window Mos runs, with the PM run idle.
|
||||
|
||||
1. Jason applies the row 119 entry to his current organization file, keeping the
|
||||
old launch.max until migration. Add chief (chief-of-staff) and assistant
|
||||
(assistant, holder mos), and change launch.by to chief. Researcher's proposal
|
||||
gives each new instance these explicit vars, matching the PM's known model:
|
||||
|
||||
```json
|
||||
"chief": {
|
||||
"definition": "chief-of-staff",
|
||||
"vars": { "harness": "claude-code", "model": "claude-opus-5-5", "thinking": "high" }
|
||||
},
|
||||
"assistant": {
|
||||
"definition": "assistant", "holder": "mos",
|
||||
"vars": { "harness": "claude-code", "model": "claude-opus-5-5", "thinking": "high" }
|
||||
}
|
||||
```
|
||||
|
||||
2. From the reviewed new copy, Jason runs the print-only conversion. Substitute
|
||||
the actual file paths; do not point CONVERTED at either input.
|
||||
|
||||
```sh
|
||||
ORGANIZATION=/path/to/organization.json
|
||||
SYSTEM_CONFIG=/path/to/config.json
|
||||
CONVERTED=/path/to/converted-organization.json
|
||||
MOSAIC_CONFIG="$SYSTEM_CONFIG" scripts/mosaic limits migrate \
|
||||
--file "$ORGANIZATION" \
|
||||
--models /mnt/storage/src/mosaic-stack/agents/rocko/work/queue-122/r2/migration-map.json \
|
||||
--roles-dir roles > "$CONVERTED"
|
||||
```
|
||||
|
||||
3. Jason reviews and installs the complete converted output himself. The adjacent
|
||||
JSON Patch describes the expected changes after step 1; it is not an installer.
|
||||
All six roles map: pm, cto, chief, assistant and reviewer to opus; coder to
|
||||
sonnet. Only exact Anthropic Opus/Sonnet model limits four/four are installed.
|
||||
There is no total or provider-wide cap. Harness, thinking, holder and other
|
||||
existing fields are preserved.
|
||||
4. The re-pin follows in the same Mos window. Old code cannot consume the new
|
||||
schema, and the new role files refuse launch.by pm, so never split the steps
|
||||
across windows. Sage supplies the first-chief-session step separately.
|
||||
|
||||
The assistant model is a proposal, not a code special case. If Jason changes it,
|
||||
he supplies an accurate mapping/table entry. For an explicit old vars.model,
|
||||
conversion must preserve that exact model. For an inherited model, migrate reads
|
||||
and validates the existing system config via the normal loader and requires both
|
||||
provider and exact model to match it. A missing/invalid config or wrong tuple
|
||||
refuses without changing either input; no system setting is written. Fully
|
||||
explicit input needs no config read and no running bus. Every successful run only
|
||||
prints, there is no --write, and already-migrated input is idempotent.
|
||||
|
||||
The raw row 119 example inherits for every role. Its separate regression fixture
|
||||
uses an Anthropic Opus system and therefore maps every role to opus. The Jason
|
||||
fixture retains the four known explicit models, including coder on Sonnet, then
|
||||
checks the shipped six-role map with inherited chief/assistant. Both outputs
|
||||
validate under the post-122 schema and the row 119 role files.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Round 2 mutants
|
||||
|
||||
| Fault / acceptance check | Result | Test |
|
||||
| --- | --- | --- |
|
||||
| 01-whole-document-validation | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 02-atomic-publication | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 03-previous-version | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 04-authenticated-actor | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 05-old-new-receipt | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 06-stale-revision | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 07-uncertain-recovery | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 08-total-limit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 09-provider-limit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 10-model-limit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 11-at-limit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 12-unset-unlimited | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 13-nonnegative-counts | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 14-no-policy-ceiling | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 15-exact-provider-count | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 16-provider-routing | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 17-reread-every-launch | KILLED (exit 1) | packages/cli/tests/launch-limits.test.mjs |
|
||||
| 18-refusal-hit-logged | KILLED (exit 1) | packages/cli/tests/launch-limits.test.mjs |
|
||||
| 19-migration-preserve-counts | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 20-migration-ambiguity | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 21-print-only-migration | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 22-human-only-settings | KILLED (exit 1) | packages/bus/tests/limits.test.mjs |
|
||||
| 23-settings-origin | KILLED (exit 1) | packages/webui/tests/settings-write.test.mjs |
|
||||
| 24-settings-fetch-metadata | KILLED (exit 1) | packages/webui/tests/settings-write.test.mjs |
|
||||
| 25-settings-send-mode | KILLED (exit 1) | packages/webui/tests/settings-write.test.mjs |
|
||||
| 26-settings-strict-keys | KILLED (exit 1) | packages/webui/tests/settings-write.test.mjs |
|
||||
| 27-form-instances | KILLED (exit 1) | packages/webui/tests/settings-form.test.mjs |
|
||||
| 28-form-limit-payload | KILLED (exit 1) | packages/webui/tests/settings-form.test.mjs |
|
||||
| 29-migration-idempotent | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 30-zero-stops-new | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 31-instance-model-edit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 32-model-table-edit | KILLED (exit 1) | packages/business/tests/launch-settings.test.mjs |
|
||||
| 33-runtime-writer-wiring | KILLED (exit 1) | packages/bus/tests/limits.test.mjs |
|
||||
| 34-inherited-exact-model | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 35-inherited-provider | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 36-config-required | KILLED (exit 1) | packages/cli/tests/limits.test.mjs |
|
||||
| 37-recovery-not-at-start | KILLED (exit 1) | packages/bus/tests/limits.test.mjs |
|
||||
| 38-uncertain-writes-refuse | KILLED (exit 1) | packages/bus/tests/limits.test.mjs |
|
||||
|
||||
Each command is node --test TEST with a dead Docker socket in a new process
|
||||
group. A timeout kills the whole group and counts as failure. No timeout,
|
||||
syntax error or missing module contributed a kill. Source hashes restored44/44.
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"base": "0afbd818e784c8306db349e201f3a2451667df0f",
|
||||
"canonicalHead": "07a967aec25337259f314c8be9f43fe9de0f118d",
|
||||
"drift": []
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0afbd818e784c8306db349e201f3a2451667df0f
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
CLEAR
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
import pathlib,os,sys,json
|
||||
busy=[]
|
||||
for p in pathlib.Path('/proc').glob('[0-9]*'):
|
||||
try:
|
||||
cwd=os.readlink(p/'cwd')
|
||||
if not cwd.startswith('/mnt/storage/src/mosaic-stack'):continue
|
||||
args=[a.decode(errors='replace') for a in (p/'cmdline').read_bytes().split(b'\0') if a]
|
||||
if not args:continue
|
||||
exe=pathlib.Path(args[0]).name
|
||||
node=exe=='node' and any(a=='--test' or a.startswith('--test-') or a.endswith('.test.mjs') for a in args[1:])
|
||||
browser='chrom' in exe and any(a.startswith('--headless') for a in args[1:])
|
||||
shell=exe in ['bash','sh'] and len(args)>1 and pathlib.Path(args[1]).name.startswith('test-')
|
||||
if node or browser or shell:busy.append({'pid':int(p.name),'exe':exe,'cwd':cwd})
|
||||
except OSError:pass
|
||||
print('BUSY '+json.dumps(busy) if busy else 'CLEAR')
|
||||
sys.exit(bool(busy))
|
||||
@@ -0,0 +1,44 @@
|
||||
3fd513345988d226dad51e3828ff8f4d9bd819da23e23f29b1193f7bbd6c0169 docs/TOOLS.md
|
||||
1a21f88f956ef0296f6111cda29090351d0cade095d4644e08a772903e1ca6c3 packages/bus/src/broker.mjs
|
||||
72a7bedcc535f2d04e1fb9cab95096e15f9e3c82522c38ca873dca8b9e02710c packages/bus/src/runtime.mjs
|
||||
6a7a397bc884edb0f66dfe424f5c5c1c5f3b0fdb513a933e3883f2e62f82503b packages/bus/tests/limits.test.mjs
|
||||
b6f48fc58c3c5b280d0054216518405ec4c57598f33483d3a6324f507b14f751 packages/business/README.md
|
||||
211ce2b570f4e3034a8de6fc567b4cf7f866e612c26a3dceb327117c85785f1a packages/business/examples/mosaic-stack.example.json
|
||||
6c18b0ce6d526633c666eb8dd10068c29877697e07d5af25801a914466807d7a packages/business/src/business.mjs
|
||||
4c09f9eeba15f5589ad7a3cfcb7547c713d313fb08541e11ce532695cbb24f55 packages/business/src/index.mjs
|
||||
db59811de60e0ba28e8dd5cdfc17e1d1451af7e0c01505a6b6aef764b0abe2a8 packages/business/src/launch-settings.mjs
|
||||
bf245c88b8af624e4c7a3f07142bb527184ee61fe7462a81d77324126681f8a5 packages/business/src/launch.mjs
|
||||
44fa089c9024934a2f9fb5ef99552eb18d616842210cbc0fc860ea32ce0b1524 packages/business/src/migrate-launch.mjs
|
||||
0024f7283bc531cf6de481aa9d6d4666de59047f62013b409ad7d8af8de72422 packages/business/src/organization.mjs
|
||||
f4fd8bc0aa53b2ecafa32c1efeb3634a0b9f58e29885da0503be153444e0341f packages/business/src/vocabulary.mjs
|
||||
712646f1916cb9a53d03126cea11ecdfa24df1d1ffa054692aba1f38da16949e packages/business/tests/assistant.test.mjs
|
||||
816929182ae8a6300ccd658cd7b71d03b6bfd73149cf7e6feb888817c68076a2 packages/business/tests/business.test.mjs
|
||||
c46588b763389cd0e7ce9e129bbed79d9bd415cb3599482b3aa10b82cbeecaec packages/business/tests/chief-of-staff.test.mjs
|
||||
a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1 packages/business/tests/helpers.mjs
|
||||
f3946aaa2bf84886e9ae74a665d66982fbc18ca28969ba122368a7886381903a packages/business/tests/launch-settings.test.mjs
|
||||
b8c918e88228d306f661e1753ba599d39a4d0afcff0613896a8b65e9ffc8c64e packages/business/tests/resolve.test.mjs
|
||||
3b8416fe68a80a3408d9f99a3e4987badcde4f5c76202b4a38afb7f81d1ffc9b packages/cli/README.md
|
||||
20f8c4152e4d49d02695c18fe356556789dcb2ee221bbe7cca427d87e4759f28 packages/cli/src/cli.mjs
|
||||
de3b06388f02839b55d27e0821907994bd5ab2e07447a1bf1ba72c0c8127b194 packages/cli/src/config.mjs
|
||||
d84d7fa771e84b84e5ba510e24f3d952272d59bbfaf2b1b8128e1b26fc078e47 packages/cli/src/launcher.mjs
|
||||
b972a8836462a16d872751006bd99c28b31884514b63a3f1af8deb3855d53ec0 packages/cli/src/limits.mjs
|
||||
a4207650a0ad5d41226c893870a38f20315ff8e8ba53165c5e97d1b9b4a159d6 packages/cli/tests/launch-limits.test.mjs
|
||||
9020e58eeaa68c2650e985818cdf5cb217445f17a5ca1146feca049c94baee0b packages/cli/tests/launcher.test.mjs
|
||||
68120aa6e354a4ee3031ffb45ac704426312c966b3f0119cafe42a5c1501e16b packages/cli/tests/limits.test.mjs
|
||||
00b905170134f7154d1851dabcd93318dbc5446ff29f80b00c459c61df36d525 packages/harness/src/bundle.mjs
|
||||
83a79841e16b996045cc51eba82552104161cb3f2a960f5bb22e7a980032e91e packages/harness/tests/pi-session.test.mjs
|
||||
4085e77fe81093b2938cd1f97ff40cd30dbc6684b5f37ba617cc404763263e2c packages/harness/tests/runner.test.mjs
|
||||
86ed3187d74cc3eecacd641aefaa96cff4a04b39a37069059dbd274914699ac1 packages/seat/src/session.mjs
|
||||
bcbc021d1984f93b9ac682bf53e7dfa6a1e7aa4029bb115bc800b862af40e0e0 packages/seat/tests/session.test.mjs
|
||||
a035076c6596e6de0d634d3fb5a1b2859800ad2346811dc747ff86c0c8b612b4 packages/webui/src/bus.mjs
|
||||
7855d1e29e2561eae21ee6c429f3a8fc085f429cc7a25909185db909e8dc9ee8 packages/webui/src/cli.mjs
|
||||
a75bdd407e379be9ea87741db9413dfc4eb85d8d774f994762f475fcde635e3c packages/webui/src/public/bus.js
|
||||
f6fc93ae58d5af73848567164b6d5c7b6e8d506e9c32b90851247adb9373282f packages/webui/src/reads.mjs
|
||||
e1c289af8498baf26a33bc3e05fb6d972d8779f1cb34d62621c633612a843a14 packages/webui/src/serve.mjs
|
||||
7b9b03f183c603227a53df5a8824348f063a46161ceced32796f459160f9eae1 packages/webui/tests/reads-fixture.mjs
|
||||
04299d42c267547ab56b4b783c1e05e626dcde8955ce98871d1ea5e4114536dd packages/webui/tests/reads.test.mjs
|
||||
955b0c9f8bbc2c7c71dad45aee0890eed54e34198bd7970961bc180b5bff68b2 packages/webui/tests/settings-form.test.mjs
|
||||
b8433e87f04753be7b5ce3cf6f93173a30eada336cf360b8420b8ff75696f2e6 packages/webui/tests/settings-write.test.mjs
|
||||
c55237b952cdd860828e12c6b746cdfeddda6c85a48b986587abaf01a7534963 packages/webui/tests/shell.test.mjs
|
||||
7cef4e9c8caa93dc68a7b2057c540da3eafe07c6258c884c3f52e10a46382cb1 packages/webui/tests/views.test.mjs
|
||||
db18760a6e93c0db45d272da278717af9844e06c2b859607971661b0aee82121 scripts/mosaic
|
||||
@@ -0,0 +1,23 @@
|
||||
pkg-business 0
|
||||
pkg-bus 0
|
||||
pkg-seat 0
|
||||
pkg-harness 0
|
||||
pkg-cli 0
|
||||
pkg-webui 0
|
||||
pkg-control-board 0
|
||||
pkg-conversation 0
|
||||
pkg-ledger 0
|
||||
pkg-tasks 0
|
||||
pkg-runs 0
|
||||
pkg-mosaic 0
|
||||
pkg-discord 0
|
||||
script-auth 0
|
||||
script-conductor 0
|
||||
script-config 0
|
||||
script-discord 0
|
||||
script-extension-package 0
|
||||
script-foundation 0
|
||||
script-land-work 0
|
||||
script-queue 0
|
||||
script-release 0
|
||||
script-task 0
|
||||
@@ -0,0 +1 @@
|
||||
pkg-business 1
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Decision136 builder gate. No live files or services; processes isolated by group."""
|
||||
import os,pathlib,signal,subprocess,sys,json
|
||||
root=pathlib.Path(sys.argv[1] if len(sys.argv)>1 else '/mnt/storage/src/mosaic-stack-rocko-122-r2');out=pathlib.Path(__file__).resolve().parent/'gate';out.mkdir(exist_ok=True)
|
||||
env={**os.environ,'DOCKER_HOST':'unix:///nonexistent.sock'}
|
||||
steps=[('pkg-'+p,['node','--test','--test-concurrency=1','--test-reporter=spec',*map(str,sorted(pathlib.Path('packages',p,'tests').glob('*.test.mjs')))]) for p in []]
|
||||
# Discover paths from the candidate, not the directory from which the runner is invoked.
|
||||
steps=[]
|
||||
for p in ['business','bus','seat','harness','cli','webui','control-board','conversation','ledger','tasks','runs','mosaic','discord']:
|
||||
files=[str(f.relative_to(root)) for f in sorted((root/'packages'/p/'tests').glob('*.test.mjs'))]
|
||||
steps.append(('pkg-'+p,['node','--test','--test-concurrency=1','--test-reporter=spec',*files]))
|
||||
# The changed script dispatcher is read by queue and discord; task resolves changed business code.
|
||||
for p in ['auth','conductor','config','discord','extension-package','foundation','land-work','queue','release','task']:
|
||||
steps.append(('script-'+p,['bash','scripts/test-'+p+'.sh']))
|
||||
results=[]
|
||||
if os.environ.get('GATE_ONLY'):
|
||||
names=set(os.environ['GATE_ONLY'].split(','));steps=[s for s in steps if s[0] in names];results=[r for r in json.loads((out/'results.json').read_text()) if r['suite'] not in names]
|
||||
if len(sys.argv)>2:
|
||||
start=next(i for i,s in enumerate(steps) if s[0]==sys.argv[2]); prior=json.loads((out/'results.json').read_text()); names={s[0] for s in steps[start:]};results=[r for r in prior if r['suite'] not in names];steps=steps[start:]
|
||||
for name,cmd in steps:
|
||||
with (out/(name+'.log')).open('w') as log:
|
||||
step_env=dict(env)
|
||||
if name in ['script-task','script-release']:step_env.pop('DOCKER_HOST',None)
|
||||
child=subprocess.Popen(cmd,cwd=root,env=step_env,stdout=log,stderr=subprocess.STDOUT,start_new_session=True)
|
||||
try:rc=child.wait(timeout=1200)
|
||||
except subprocess.TimeoutExpired:os.killpg(child.pid,signal.SIGKILL);child.wait();rc='timeout'
|
||||
results.append(dict(suite=name,exit=rc,command=cmd));(out/'results.json').write_text(json.dumps(results,indent=2)+'\n');print(name,rc,flush=True)
|
||||
if rc!=0:sys.exit(1)
|
||||
@@ -0,0 +1,167 @@
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.273706ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.210285ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (22.76115ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (9.06431ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.727645ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (10.413382ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.995927ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.636706ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (59.54929ms)
|
||||
✔ agents: stranded is per role and per business (20.990895ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (8.075793ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (13.880375ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (14.680024ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (14.45782ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (9.390769ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (9.321723ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (13.986285ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (8.601101ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (16.177062ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (6.562122ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (10.95286ms)
|
||||
✔ authority never transfers between action, run, target, unresolved or replaced role holder (14.884751ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (8.210455ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (12.130355ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (7.998333ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (13.502075ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (13.130182ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (1.60458ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (10.086438ms)
|
||||
✔ credentials refuses a role session and any argument (9.473605ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (10.330038ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (56.637949ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (2.636979ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (1.296167ms)
|
||||
✔ expiry refuses use and env references never become client data (0.443746ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (0.94615ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.209455ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (23.166437ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (13.178919ms)
|
||||
✔ a human withdraw sends one message with the note (12.680496ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (15.899758ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (16.865496ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (16.426978ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (14.553674ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (13.267639ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (18.847523ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (17.205931ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (16.717639ms)
|
||||
✔ recent stops at RECENT rows (58.562137ms)
|
||||
✔ every row is what trail already gives the same session for that id (24.631855ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (22.806756ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (24.257625ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (11.110997ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (7.262556ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (9.374133ms)
|
||||
✔ endLaunch leaves a claim another run took alone (9.370113ms)
|
||||
✔ refuse records action.refused against the caller with the code only (6.804417ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (10.434083ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (70.568593ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.305507ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.359911ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.499259ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.222672ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (14.545495ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (29.155599ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (21.779229ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (16.476002ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (10.31617ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (13.340339ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (218.879115ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (17.017575ms)
|
||||
✔ views messages passes only its paging arguments through (0.216625ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (9.603901ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (61.141403ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (41.069987ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (55.842183ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (86.021656ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (57.038517ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (37.925547ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (54.12748ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (22.719156ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (11.388021ms)
|
||||
✔ a message with no reply gives an empty list (8.595357ms)
|
||||
✔ replies come oldest first and stop at REPLIES (46.605293ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (19.052981ms)
|
||||
✔ strict arguments; a role session gets human-required (19.943164ms)
|
||||
✔ views passes replies through as one call with the id (0.183904ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (16.814494ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (9.018176ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (10.193968ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (19.081882ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (14.482427ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (16.28598ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (21.177059ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (13.77263ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (17.386805ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (22.748831ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (12.56085ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (48.154143ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (19.839129ms)
|
||||
✔ another run cannot consume an approval; a failed check leaves it usable (13.173748ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (10.00387ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (18.902267ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (12.964652ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (12.455885ms)
|
||||
✔ class drift gated to within-role refuses before consumption (11.845647ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (13.128822ms)
|
||||
✔ class drift within-role to gated refuses before consumption (10.709295ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (10.434478ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (13.112933ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (14.706931ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (11.540426ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (8.724095ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (9.09366ms)
|
||||
✔ a tombstone is not open (7.534023ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (9.6951ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (7.853561ms)
|
||||
✔ a human session reads the same state, with the same cap (9.811687ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (8.543742ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (9.288278ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (8.72549ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (9.277292ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (39.242749ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (6.227968ms)
|
||||
✔ async transactions refuse before invoking their function (4.712434ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (114.220081ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (68.457124ms)
|
||||
✔ each filter, alone and together, and total counts every match (153.042263ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (83.830605ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (70.175054ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (315.548996ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (22.375908ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (25.571235ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (5.706331ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (15.125711ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (5.877828ms)
|
||||
✔ a bad entry refuses the whole record (5.998207ms)
|
||||
✔ taskView reads the projection for one business (7.5591ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (13.273205ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (276.891751ms)
|
||||
✔ without an adapter the server refuses every task verb (16.322971ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (14.959273ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (106.47997ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (43.948266ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (13.474989ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (29.8585ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (12.403699ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (16.755211ms)
|
||||
✔ the tester reads the human views a reader reads (17.126254ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.067168ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.346532ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.194085ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (14.420187ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (607.584294ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (18.154571ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (13.095886ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (7.709096ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.216173ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (9.362134ms)
|
||||
ℹ tests 159
|
||||
ℹ suites 0
|
||||
ℹ pass 159
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5574.253918
|
||||
@@ -0,0 +1,171 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.19713ms)
|
||||
✔ the shipped file is exactly the approved list (0.508571ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.245779ms)
|
||||
✔ a business grant through limits does not widen the role (1.081965ms)
|
||||
✖ a launch block whose by is the assistant is refused (1.531916ms)
|
||||
✔ the instance takes no credential references and no tracker (1.763964ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.384066ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (0.997049ms)
|
||||
✔ the fixture business validates and comes back frozen (3.204703ms)
|
||||
✔ two instances may share a definition (0.996362ms)
|
||||
✔ top-level refusals (2.83973ms)
|
||||
✔ arbiters and projects (4.240097ms)
|
||||
✔ role instances (2.037796ms)
|
||||
✔ Vikunja bots (4.851405ms)
|
||||
✔ a role without Vikunja takes no tracker block (1.733607ms)
|
||||
✔ credential references match the definition's services (2.079505ms)
|
||||
✔ launch (6.350012ms)
|
||||
✔ loadBusiness: file checks (1.692306ms)
|
||||
✔ loadBusiness: not a regular file (39.109212ms)
|
||||
✔ loading writes nothing (1.008537ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.642493ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.614471ms)
|
||||
✖ the role file loads and resolves through loadBusiness (5.536049ms)
|
||||
✔ the shipped file is exactly the approved list (0.243ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.154619ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (0.971474ms)
|
||||
✔ the pm does not hold role.launch (1.068154ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.222645ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (0.761113ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.072055ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.253103ms)
|
||||
✔ the instance takes no credential references and no tracker (1.463068ms)
|
||||
✔ usage errors exit 4 (256.189003ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (64.316494ms)
|
||||
✔ validate: project files (301.887557ms)
|
||||
✔ validate: missing files and a broken system config (235.317245ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (62.603177ms)
|
||||
✔ validate: a token file inside the repository is refused (65.258103ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (190.27832ms)
|
||||
✔ resolve: prints one instance's record (250.244205ms)
|
||||
✔ resolve: refusals (371.818466ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (1.761235ms)
|
||||
✔ check: a good file has no problems (0.623534ms)
|
||||
✔ check never opens the file: a write-only token passes (0.256176ms)
|
||||
✔ check: file problems (0.636432ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (0.596101ms)
|
||||
✔ check: dates and environment references (0.289942ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.97005ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.584508ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (17.127077ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (11.814027ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.815152ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.591941ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.513044ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.496988ms)
|
||||
✔ path and load (1.612337ms)
|
||||
✔ refusals (0.83388ms)
|
||||
✔ systemVars flattens the validated config (1.350195ms)
|
||||
✔ precedence: system, business, project, project role, agent (3.698254ms)
|
||||
✔ limits narrow the definition and never widen it (1.602466ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (3.943698ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (1.502927ms)
|
||||
✔ limits.authority narrows cross-role actions too (0.855132ms)
|
||||
✔ classify (0.871184ms)
|
||||
✔ the record carries what the broker and launcher need (0.914426ms)
|
||||
✔ digest: key order doesn't matter, any value change does (4.708776ms)
|
||||
✔ refusals (1.65855ms)
|
||||
✔ the four shipped version 2 roles load (2.088645ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.666592ms)
|
||||
✔ shipped authority follows the note's table (0.43161ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (0.439149ms)
|
||||
✔ version 1 files keep loading with no authority (0.738607ms)
|
||||
✔ the conductor policy isn't a role (0.129192ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.317065ms)
|
||||
✔ version 2 refusals (0.912649ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (1.547602ms)
|
||||
✔ credentials: Gitea scopes (0.678585ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.752583ms)
|
||||
✔ credentials: services (0.586476ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.553181ms)
|
||||
✔ every key names known layers and a merge rule (0.575399ms)
|
||||
✔ unknown keys and wrong layers refuse (0.490105ms)
|
||||
✔ types (1.296102ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.197063ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.245337ms)
|
||||
✔ merge doesn't change its inputs (0.102234ms)
|
||||
ℹ tests 86
|
||||
ℹ suites 0
|
||||
ℹ pass 84
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2464.566323
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/assistant.test.mjs:86:1
|
||||
✖ a launch block whose by is the assistant is refused (1.531916ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/. Input:
|
||||
|
||||
'/mnt/storage/scratch/tmp/mosaic-business-PjotZW/businesses/acme.json launch.max needs migration: mosaic limits migrate --file FILE --models FILE'
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/assistant.test.mjs:25:12)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.throws (node:assert:728:3)
|
||||
at refuses (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/assistant.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/assistant.test.mjs:87:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '/mnt/storage/scratch/tmp/mosaic-business-PjotZW/businesses/acme.json launch.max needs migration: mosaic limits migrate --file FILE --models FILE',
|
||||
expected: /launch\.by names assistant, whose role assistant doesn't hold role\.launch within-role/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/chief-of-staff.test.mjs:49:1
|
||||
✖ the role file loads and resolves through loadBusiness (5.536049ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
by: 'chief',
|
||||
instances: [
|
||||
'coder',
|
||||
'reviewer'
|
||||
],
|
||||
+ limits: {
|
||||
+ models: {
|
||||
+ zai: {
|
||||
+ 'claude-opus-5-5': 2,
|
||||
+ 'claude-sonnet-5-5': 4
|
||||
+ }
|
||||
+ }
|
||||
- max: {
|
||||
- opus: 2,
|
||||
- sonnet: 4
|
||||
},
|
||||
+ models: {
|
||||
+ 'claude-opus-5-5': {
|
||||
+ model: 'claude-opus-5-5',
|
||||
+ provider: 'zai'
|
||||
+ },
|
||||
+ 'claude-sonnet-5-5': {
|
||||
+ model: 'claude-sonnet-5-5',
|
||||
+ provider: 'zai'
|
||||
+ },
|
||||
+ 'glm-5.3-flash': {
|
||||
+ model: 'glm-5.3-flash',
|
||||
+ provider: 'zai'
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/chief-of-staff.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: { by: 'chief', instances: [ 'coder', 'reviewer' ], models: { 'claude-opus-5-5': [Object], 'claude-sonnet-5-5': [Object], 'glm-5.3-flash': [Object] }, limits: { models: [Object] } },
|
||||
expected: { by: 'chief', instances: [ 'coder', 'reviewer' ], max: { opus: 2, sonnet: 4 } },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
✔ the role file loads and resolves through loadBusiness (4.116629ms)
|
||||
✔ the shipped file is exactly the approved list (0.496668ms)
|
||||
✔ the assistant's authority is message.send within role and nothing else (1.197366ms)
|
||||
✔ a business grant through limits does not widen the role (1.076217ms)
|
||||
✔ a launch block whose by is the assistant is refused (1.109967ms)
|
||||
✔ the instance takes no credential references and no tracker (1.759494ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.370914ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (1.035413ms)
|
||||
✔ the fixture business validates and comes back frozen (3.334766ms)
|
||||
✔ two instances may share a definition (1.036032ms)
|
||||
✔ top-level refusals (2.800897ms)
|
||||
✔ arbiters and projects (4.042024ms)
|
||||
✔ role instances (2.07081ms)
|
||||
✔ Vikunja bots (4.643027ms)
|
||||
✔ a role without Vikunja takes no tracker block (1.723174ms)
|
||||
✔ credential references match the definition's services (1.941622ms)
|
||||
✔ launch (5.96233ms)
|
||||
✔ loadBusiness: file checks (1.638834ms)
|
||||
✔ loadBusiness: not a regular file (35.027047ms)
|
||||
✔ loading writes nothing (0.988518ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.5937ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.627936ms)
|
||||
✔ the role file loads and resolves through loadBusiness (4.622382ms)
|
||||
✔ the shipped file is exactly the approved list (0.153475ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (1.137452ms)
|
||||
✔ the chief of staff holds role.launch and message.send; every other action is gated (0.904108ms)
|
||||
✔ the pm does not hold role.launch (1.045885ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (1.026951ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (0.959617ms)
|
||||
✔ a launch block whose by is the pm instance is refused (1.028561ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.237306ms)
|
||||
✔ the instance takes no credential references and no tracker (1.443873ms)
|
||||
✔ usage errors exit 4 (266.357127ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (67.856084ms)
|
||||
✔ validate: project files (307.208825ms)
|
||||
✔ validate: missing files and a broken system config (239.05926ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (60.051358ms)
|
||||
✔ validate: a token file inside the repository is refused (66.181062ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (186.738942ms)
|
||||
✔ resolve: prints one instance's record (247.705106ms)
|
||||
✔ resolve: refusals (351.026522ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (1.69921ms)
|
||||
✔ check: a good file has no problems (0.548426ms)
|
||||
✔ check never opens the file: a write-only token passes (0.238733ms)
|
||||
✔ check: file problems (0.606059ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (0.548208ms)
|
||||
✔ check: dates and environment references (0.264152ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.648173ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.537471ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (17.662801ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.98254ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.767865ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (16.518142ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.643236ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.871674ms)
|
||||
✔ path and load (1.615489ms)
|
||||
✔ refusals (0.834332ms)
|
||||
✔ systemVars flattens the validated config (1.277012ms)
|
||||
✔ precedence: system, business, project, project role, agent (3.586447ms)
|
||||
✔ limits narrow the definition and never widen it (1.511462ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (3.606427ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (1.366905ms)
|
||||
✔ limits.authority narrows cross-role actions too (0.75666ms)
|
||||
✔ classify (0.821163ms)
|
||||
✔ the record carries what the broker and launcher need (0.888479ms)
|
||||
✔ digest: key order doesn't matter, any value change does (4.565032ms)
|
||||
✔ refusals (1.618229ms)
|
||||
✔ the four shipped version 2 roles load (2.081975ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (0.684376ms)
|
||||
✔ shipped authority follows the note's table (0.422962ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (0.442703ms)
|
||||
✔ version 1 files keep loading with no authority (0.754792ms)
|
||||
✔ the conductor policy isn't a role (0.134886ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.316368ms)
|
||||
✔ version 2 refusals (0.908752ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (1.572068ms)
|
||||
✔ credentials: Gitea scopes (0.664536ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (0.746695ms)
|
||||
✔ credentials: services (0.615553ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.477351ms)
|
||||
✔ every key names known layers and a merge rule (0.606628ms)
|
||||
✔ unknown keys and wrong layers refuse (0.506669ms)
|
||||
✔ types (1.306182ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.189276ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.234223ms)
|
||||
✔ merge doesn't change its inputs (0.1023ms)
|
||||
ℹ tests 86
|
||||
ℹ suites 0
|
||||
ℹ pass 86
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2445.579364
|
||||
@@ -0,0 +1,205 @@
|
||||
✔ every screen and overlay fits 120x36, 80x24 and the narrow layout, row for row (1203.543172ms)
|
||||
✔ width counts terminal cells: wide CJK and emoji 2, U+FE0F after a one-cell base 1, marks 0 (67.249917ms)
|
||||
✔ broker text is shown, never interpreted: no raw control character or bidi override reaches the terminal (154.764641ms)
|
||||
✔ NO_COLOR: no escape codes, except reverse video on the selected row (230.942705ms)
|
||||
✔ 1-9 shows the decide flow's own lines and question; only y resolves (50.301151ms)
|
||||
✔ the app shows the same decide text as mosaic decide (20.398532ms)
|
||||
✔ any key but y or Y at the question answers No; nothing is sent (180.341445ms)
|
||||
✔ below 40x10 the question is hidden, so every key answers it No, y included (Filbert R3) (63.48235ms)
|
||||
✔ under 40 columns a tall terminal shows the too-small screen even where the decide box would fit; y sends nothing (Filbert N10) (246.427982ms)
|
||||
✔ a hidden decide box names the way out, and the status line under it does not promise y (Filbert N12) (29.075242ms)
|
||||
✔ a throw while answering the question goes to crash, sends nothing and leaves no job pending (18.809867ms)
|
||||
✔ type-ahead never answers the question: a paste, keys typed before it is drawn, keys inside askMs (390.601518ms)
|
||||
✔ quitting at the question answers No and sends nothing, armed or not (29.678232ms)
|
||||
✔ a timer tick reads nothing under an overlay, never answers the question, and keeps a resolved status (27.056425ms)
|
||||
✔ a long question is cut inside the question; the action, target, choice and prompt stay (Dewey B1) (42.638503ms)
|
||||
✔ a decide box too big for the terminal says so, and every key answers it No, y included (Dewey B1, round 3) (266.79613ms)
|
||||
✔ at every size the decide box shows each line y depends on, or says it is hidden (8056.346299ms)
|
||||
✔ outcome unknown: the CLI's sentence, no retry, then the trail or a re-read (61.96219ms)
|
||||
✔ refused and failed reads keep the last list, marked stale; a refused decide says refused (30.83768ms)
|
||||
✔ help or a detail box cut to fit keeps its last line, Esc included (Dewey) (14.842645ms)
|
||||
✔ keys: views, moving, trail of a selection, the command line, help and quit (73.105473ms)
|
||||
✔ one option: the status line says Press 1, not 1-1 (14.559658ms)
|
||||
✔ no business: the app says so and :business picks one (7.834825ms)
|
||||
✔ mosaic with no argument: exit 3 in an agent run, exit 4 with the usage off a terminal, the app on one (1.767567ms)
|
||||
✔ scripts/mosaic with no argument reaches the app entry; the seat usage it printed before has not drifted (165.954523ms)
|
||||
✔ strings to keep exactly live once, in the decide flow and the transport; the app does not restate them (0.45494ms)
|
||||
✔ decide with --note still asks; a No sends nothing (9.136362ms)
|
||||
✔ the app's business comes from a live bus host only (1.011432ms)
|
||||
✔ runApp leaves the terminal as it found it on q, end of input, SIGTERM, SIGINT, SIGHUP and an error, the first frame's included (6.736315ms)
|
||||
✔ draw is pure: same state, same frame (0.719527ms)
|
||||
✔ inbox lists only decisions routed to the human, with what approving authorizes and how to decide (14.502066ms)
|
||||
✔ decide resolves by id prefix with --yes, and the trail shows it in broker order with the task to follow (11.042935ms)
|
||||
✔ decide refuses without a terminal or --yes, on an unknown option and on a short reference (9.07596ms)
|
||||
✔ decide prints a declining choice as declining (8.824994ms)
|
||||
✔ an unknown outcome is reported once and never resent (7.862408ms)
|
||||
✔ a decision closed before the answer arrives exits 2 and points at its trail (8.048127ms)
|
||||
✔ a prefix that matches two open decisions exits 2 and resolves neither (8.297708ms)
|
||||
✔ without --business a command uses the live host's business, and a stale host.json is not a host (6.761914ms)
|
||||
✔ every human command refuses inside an agent run before it touches the bus (6.468217ms)
|
||||
✔ usage errors exit 4; no business and no host is a usage error (7.242753ms)
|
||||
✔ agents and tasks print through the broker (7.280007ms)
|
||||
✔ notify.json: missing, loose, malformed and extra keys refuse; a binding or null passes (1.100526ms)
|
||||
✔ bootConfig builds the broker's boot message for one business, with no trackers key when no project names one (31.249945ms)
|
||||
✔ trackers come from the tracker.* variables of the one project that names a tracker project (53.213322ms)
|
||||
✔ with two projects, the one that sets tracker.project supplies the tracker and the other is no conflict (24.895187ms)
|
||||
✔ two projects that each name a tracker project refuse, since the boot shape holds one (27.943701ms)
|
||||
✔ a business without tracker.baseUrl gets no trackers entry (25.597514ms)
|
||||
✔ an unknown business and a broken system config refuse with exit 3 (48.441903ms)
|
||||
✔ follow prints an unsolicited message after plain talk returned (23.941261ms)
|
||||
✔ talk --follow continues after reply and prints a later unsolicited message (22.340942ms)
|
||||
✔ inbox lists all unread human messages under decisions, does not deliver or read them (203.648819ms)
|
||||
✔ follow refuses agent context and bad arguments (8.776132ms)
|
||||
✔ follow Ctrl-C wakes the poll sleep and removes its handler; transport errors also clean up (8.959481ms)
|
||||
✔ plain talk leaves the process SIGINT handlers unchanged (9.123445ms)
|
||||
✔ empty views say so (0.561091ms)
|
||||
✔ the trail keeps the broker's order and names a decision's task without its rows (0.71445ms)
|
||||
✔ tasks print the tracker fields the snapshot carries (0.12008ms)
|
||||
✔ the review loop: the coder pushes and asks, the reviewer fetches and approves, and the task's trail holds each step (273.103812ms)
|
||||
✔ refusals: no action, non-fast-forward, an unknown commit or request, and a push for another task moves only that task's ref (272.386069ms)
|
||||
✔ the size cap refuses a push before any byte (138.72674ms)
|
||||
✔ a fetch over the cap refuses before any byte reaches the reviewer (279.19195ms)
|
||||
✔ the socket refuses a request with no capability, an unknown one, and a bad request line (135.966967ms)
|
||||
✔ a rigged clone runs nothing: hooks, fsmonitor, a filter, a gitlink and a symlinked .git/config leave no marker (221.755046ms)
|
||||
✔ an identity with no role, or of another business, refuses not-a-role and moves no ref (172.03645ms)
|
||||
✔ a review of a project the business no longer has refuses unknown-project (202.609469ms)
|
||||
✔ past maxActive connections the socket refuses git-busy, and a hung-up connection frees its slot (119.549904ms)
|
||||
✔ close() answers host-closing to a connection still sending its request line (116.912461ms)
|
||||
✔ a bundle that trickles in refuses body-timeout at its deadline and frees its slot (527.827499ms)
|
||||
✔ a reviewer gone before its bundle was sent is filed fetch-aborted, not as the host's fault (388.323172ms)
|
||||
✔ a reviewer that hangs up the moment it has the whole bundle was served, not aborted (416.385963ms)
|
||||
✔ send: a close after every byte left is served; one that fails a queued write is fetch-aborted (42.180427ms)
|
||||
✔ a bundle with no bytes for bodyIdle refuses body-timeout long before its deadline (429.021585ms)
|
||||
✔ send: a close once the loop is past its last chunk is served, and a failed write there is fetch-aborted (44.025517ms)
|
||||
✔ letGo waits for an answer to leave for at most its cap, then destroys the socket (302.106847ms)
|
||||
✔ a record that fails and can't be undone refuses rollback-failed, which the host logs (320.029056ms)
|
||||
✔ the host boots the broker, binds a launch in process, and the notifier DMs a blocking decision exactly once (818.209899ms)
|
||||
✔ a notifier that dies takes the host down with exit 1, so the unit restarts the pair (137.178364ms)
|
||||
✔ a second host for the same data root refuses with exit 3 while the first runs (77.142025ms)
|
||||
✔ two bus starts racing for one data root leave one host running; the other refuses that a host already runs (443.00641ms)
|
||||
✔ a host takes over a host.lock its dead host left, and puts back a live claim that replaced it meanwhile (1.663915ms)
|
||||
✔ a host.lock that goes between the check and the read is tried again; one that can't be parsed still refuses as unreadable (0.679063ms)
|
||||
✔ a live host's lock stays, however old the file is (0.464589ms)
|
||||
✔ a host.lock left by a host killed with SIGKILL doesn't stop the next bus start (652.968146ms)
|
||||
✔ while a host boots, a reader sees no host: the human commands still ask for --business, stop and status find none (187.284934ms)
|
||||
✔ a host started before host.lock existed, holding only host.json, still refuses a second start, which leaves no lock (25.37505ms)
|
||||
✔ a broker fork that throws leaves no host.lock and no host.json (28.708358ms)
|
||||
✔ a broker send that throws leaves no host.lock and no host.json (29.747655ms)
|
||||
✔ a broker that misses its boot wait leaves no host.lock and no host.json (28.121147ms)
|
||||
✔ a notifier fork that throws stops the broker and leaves no host.lock and no host.json (74.590602ms)
|
||||
✔ a notifier send that throws stops the broker and leaves no host.lock and no host.json (75.042238ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, before the notifier starts, and leaves no host.lock and no live broker (77.398697ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, with no notifier, and leaves no host.lock and no live broker (77.880556ms)
|
||||
✔ a host.json that can't be written stops both children and leaves no host.lock (170.847577ms)
|
||||
✔ an error event on the broker before it replies fails the start at once, and leaves no host.lock and no live child (28.965818ms)
|
||||
✔ an error event on the notifier before it replies fails the start at once, and leaves no host.lock and no live child (76.582842ms)
|
||||
✔ an error event on the broker while the notifier starts fails the start once the notifier replies (172.162959ms)
|
||||
✔ an error event on the broker once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (174.32808ms)
|
||||
✔ an error event on the notifier once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (175.33442ms)
|
||||
✔ a broker reply that misses the wait breaks the channel: the late reply answers nothing, later requests refuse, the host exits 1 (1080.248625ms)
|
||||
✔ a broker reply with another request's id, or none, breaks the channel and the host exits 1 (154.403726ms)
|
||||
✔ a broker reply with no request waiting breaks the channel and the host exits 1 (76.461249ms)
|
||||
✔ a notifier that refuses stops the broker and the host refuses with exit 3 (126.191845ms)
|
||||
✔ a notifier that refuses after the broker died still refuses with exit 3, without a send to the dead broker (118.742562ms)
|
||||
✔ a notifier that dies before it replies, after the broker died, still refuses, without a send to the dead broker (81.891333ms)
|
||||
✔ a close send that fails with EPIPE after the notifier refuses still gives the notifier's refusal, exit 3 (123.584452ms)
|
||||
✔ a close send that fails with EPIPE after the notifier dies unanswered still gives the notifier's error (75.444335ms)
|
||||
✔ close() whose stop and close sends fail with EPIPE still finishes, with exit 1 (138.642376ms)
|
||||
✔ watchChildren reports a child that died before it was called, and one that dies later (21.864306ms)
|
||||
✔ bus stop refuses to signal a live pid that is not a bus host (202.847529ms)
|
||||
✔ bus start refuses with exit 3 and the code when the broker refuses to boot; bus status names the lock (227.047837ms)
|
||||
✔ bus start refuses with exit 3 without a notifier config (99.039265ms)
|
||||
✔ bus start runs until bus stop; status reports it while it runs (635.785828ms)
|
||||
✔ bus-service.sh renders the unit and installs it into a given directory (54.542688ms)
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (66.913608ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (12.549946ms)
|
||||
✔ bus-service.sh refuses a default claude without the execute bit, or in a PATH dir with a space (7.802639ms)
|
||||
✔ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (18.283877ms)
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1183.459452ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (402.167141ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3509.516355ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (117.889115ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (189.067899ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (93.708352ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (173.149763ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (245.736051ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (93.959997ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1137.316361ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (588.197941ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3550.081292ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (82.399354ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (84.230104ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (89.587441ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1204.800041ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.258036ms)
|
||||
✔ migration needs no bus/config, prints whole converted document, is idempotent and never writes (8.402449ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (0.959652ms)
|
||||
✔ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (150.285915ms)
|
||||
✔ zoned uses the IANA zone across DST (11.084352ms)
|
||||
✔ each open blocking decision is DM'd once, across polls and a restart; non-blocking ones are not (14.795665ms)
|
||||
✔ two blocking decisions get two DMs with different nonces (8.861029ms)
|
||||
✔ the digest nonce differs per business and per day and fits Discord's 25 characters (0.161452ms)
|
||||
✔ a failed DM is journaled, backs off, and is retried until it lands (9.311247ms)
|
||||
✔ five definite refusals stop a DM: one gave-up line, one log line, and a restart keeps the count (11.153911ms)
|
||||
✔ 429s, 5xx-style unknowns and refusals without a status never count toward the limit (12.120244ms)
|
||||
✔ a crash between the fifth refusal and its gave-up line: the next poll appends it and sends nothing (7.913568ms)
|
||||
✔ polled every POLL_MS against a permanent 403, a DM is sent at 0, 30, 60, 90 and 120 min and gives up only then (60.79991ms)
|
||||
✔ a restart after the second refusal does not send before that refusal's 30 min are up (33.975392ms)
|
||||
✔ the digest goes at 08:00 Chicago once a day, with blocking ones marked as DM'd (9.412852ms)
|
||||
✔ a late start with no digest for the day sends one at once; an empty inbox gets one line (6.729716ms)
|
||||
✔ an inbox read failure is logged and the next poll retries (0.561298ms)
|
||||
✔ no Discord id reaches the journal or the log (7.208476ms)
|
||||
✔ the journal: a torn tail is copied out and truncated, so an append after it reopens cleanly (1.742807ms)
|
||||
✔ the journal: a crash between the copy and the truncate leaves a tail the next open repairs (2.109205ms)
|
||||
✔ the journal: a whole file that is one torn line truncates to empty (1.223976ms)
|
||||
✔ the journal: a malformed complete line refuses and leaves the file and any torn tail alone (0.437368ms)
|
||||
✔ the journal: a loose file mode, a loose directory or a symlinked journal refuses (0.523078ms)
|
||||
✔ the journal: a line with a wrong type refuses with exit 3 and names the field (1.701655ms)
|
||||
✔ the journal: a symlinked directory refuses and says it is a link (1.431599ms)
|
||||
✔ the journal: a dangling directory link, a parent that is a file and a journal that is a directory each refuse with exit 3 (0.455702ms)
|
||||
✔ the journal: an append after the file was swapped for a symlink refuses and writes nothing through it (0.341624ms)
|
||||
✔ the journal: a directory it cannot write or create refuses with exit 3 and names the path (0.422879ms)
|
||||
✔ digest content stays within Discord's 2000 characters (0.241084ms)
|
||||
✔ runLoop never overlaps ticks and stops after the one in flight (111.239749ms)
|
||||
✔ a human command refused with human-required prints the other-tree line and exits 3 (1.838069ms)
|
||||
✔ a --tester command refused with tester-required prints the other-tree line and exits 3 (0.688307ms)
|
||||
✔ other exit-3 refusals print no other-tree line (0.916722ms)
|
||||
✔ the line names no path (0.072571ms)
|
||||
✔ shared copy: npm ci, pushed reachability, readonly/existing copy, webui delegation (364.919922ms)
|
||||
✔ wrapper preserves Q81 lease and marker, rejects foreign/symlink; check uses effective roots (369.254057ms)
|
||||
✔ bus unit copy/pm pins, install refuses all busy states and failed reads, drop-in refusal (362.367939ms)
|
||||
✔ missing package manifest refuses before npm; npm failure removes the unpublished temp copy (238.112101ms)
|
||||
✔ real pinned install loads bus and Console; same-copy mosaic talk passes proof, other trees refuse (3250.121966ms)
|
||||
✔ bus status reads effective copy/pm/drop-ins without writes; check refuses an overridden ExecStart (545.097141ms)
|
||||
✔ drop-ins in either override field and malformed metadata refuse; uninstall also checks --no-reload (178.408679ms)
|
||||
✔ install never shows a template name on systemd 261; template drop-ins still refuse (156.646914ms)
|
||||
✔ unlisted instance drop-in is found in another unit lookup directory; path discovery errors refuse (132.601902ms)
|
||||
✔ inherited mosaic-.service.d override refuses without changing the unit (153.33906ms)
|
||||
✔ inherited service.d override refuses without changing the unit (157.96836ms)
|
||||
✔ inherited drop-in unreadable directory or file refuses before writing (119.942425ms)
|
||||
✔ talk --tester sends a [mos test] message as tester from inside an agent and prints the role's reply (21.737245ms)
|
||||
✔ talk --tester refuses text without the [mos test] prefix before any call (7.787528ms)
|
||||
✔ the read verbs take --tester inside an agent, and the trail shows the tester as the sender (11.83856ms)
|
||||
✔ decide, stop and launches take no --tester (8.483003ms)
|
||||
✔ the tester transport runs tester-cli.mjs, and the tester's refusals exit 3 (0.303382ms)
|
||||
✔ with no stand-in transport, --tester runs tester-cli.mjs on the data root's socket (0.483868ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (233.411038ms)
|
||||
✔ the transport writes {business, verb, args} to the child and reads its JSON (25.566392ms)
|
||||
✔ a bus code on stderr becomes the exit code; garbage and timeouts are outcome problems (2125.35124ms)
|
||||
✔ busExit and refuseInsideAgent (0.553647ms)
|
||||
✔ talk sends a REQUEST, prints and reads everything that arrives, and stops at the reply (40.217339ms)
|
||||
✔ talk --wait 0 only sends; no reply within --wait exits 1 and says where it will show (1010.027978ms)
|
||||
✔ a late reply the Console has listed still reaches the next talk (2033.625777ms)
|
||||
✔ talk, stop and launches off/on refuse inside an agent run; bad arguments are usage errors (10.260021ms)
|
||||
✔ launches off and on go to the broker and change the business's launch state (7.766989ms)
|
||||
✔ launches list reads sessions.json and marks a stale entry; stop reports it and refuses a non-runner (8.087887ms)
|
||||
ℹ tests 195
|
||||
ℹ suites 0
|
||||
ℹ pass 195
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 49207.533141
|
||||
@@ -0,0 +1,132 @@
|
||||
✔ explicit request, Seen, ordinary completion and a new request have distinct attention states (3.302878ms)
|
||||
✔ attention convention ignores reasoning/quoted examples and permits leading blank lines (0.189833ms)
|
||||
✔ completed smoke replies and ordinary questions are idle, not human blockers (0.645232ms)
|
||||
✔ only an explicit first-line input request makes a finished reply waiting (0.1558ms)
|
||||
✔ tool activity, user text, errors and unfinished turns override attention text (0.114889ms)
|
||||
✔ STOP access failure is unknown, not absence, under a non-root identity (29.356874ms)
|
||||
✔ connector Task never inherits Discord routing envelopes; ordinary Task still uses user text (2.437306ms)
|
||||
✔ connector discovery keeps only safe identity; rejects modes, mismatches, links and traversal (1.221617ms)
|
||||
✔ canonical owner identity and STOP are independent; no tmux fallback or forged registration (4.521829ms)
|
||||
✔ connector reply refusal precedes forged live tmux registration; ordinary agent still sends (0.523063ms)
|
||||
✔ server rescans connector discovery and refuses HTTP reply without transport (27.739677ms)
|
||||
✔ connector session links and linked directories are not read (0.878184ms)
|
||||
✔ newer live matching launch marks old activity, preserves history/attention/attribution, then clears on new activity (2.05261ms)
|
||||
✔ CLI print uses the relaunch notice instead of old current preview (48.517257ms)
|
||||
✔ connector owner and fixed task never inherit a native relaunch notice (1.852194ms)
|
||||
✔ equality, stale/unknown/offline, mismatched registration and unknown activity do not assert relaunch (1.574721ms)
|
||||
✔ loadConfig: missing file throws ConfigError (1.22741ms)
|
||||
✔ loadConfig: invalid JSON throws ConfigError (0.234081ms)
|
||||
✔ loadConfig: missing dataRoot throws ConfigError (0.187863ms)
|
||||
✔ loadConfig: relative dataRoot throws ConfigError (0.1924ms)
|
||||
✔ loadConfig: valid config returns dataRoot (0.516261ms)
|
||||
✔ findNewestSession: picks the newest by mtime among two files (0.417677ms)
|
||||
✔ findNewestSession: finds files in nested subdirectories (0.247258ms)
|
||||
✔ findNewestSession: returns null for a missing dir (0.115086ms)
|
||||
✔ readSession: extracts fields, collapses/truncates text, counts a truncated final line (0.52923ms)
|
||||
✔ readSession: model and provider follow the latest model_change entry or assistant turn; null when the log names neither; scanAgent carries them (1.022736ms)
|
||||
✔ readSession: lastError carries the assistant errorMessage only when the last assistant turn errored (0.448434ms)
|
||||
✔ findNewestSession/scan: never read sibling auth or secrets next to a sessions dir (0.989537ms)
|
||||
✔ deriveState: full state table (0.142224ms)
|
||||
✔ rule: newest entry is an assistant message with a tool call, after a question-looking text, is working (0.297115ms)
|
||||
✔ rule: newest entry is a tool result with no assistant text after it is working (0.230934ms)
|
||||
✔ rule: a finished ordinary turn is idle, even if it says your move (0.24342ms)
|
||||
✔ task: the first user message of the session, from text blocks (0.228396ms)
|
||||
✔ task: a plain-string user content is accepted, whitespace collapsed and long text capped (0.259693ms)
|
||||
✔ task: no user message in the log means null (shown as unknown), never a guess (0.236876ms)
|
||||
✔ workspace: the live tmux pane path wins; the session cwd is the fallback; neither means null (0.309087ms)
|
||||
✔ activeProject: basename of the nearest .git directory or .git file above the workspace; none means null (0.45901ms)
|
||||
✔ scan: the written record carries task, workspace and activeProject (0.395289ms)
|
||||
✔ registration: overrides task, project and workspace; every source says registration; registered carries the launch fields; the grouping column is untouched (0.49411ms)
|
||||
✔ registration: empty task and null project/workspace leave the derived values in place; registered is still non-null (0.306829ms)
|
||||
✔ registration: a record whose pid is gone is stale; derived values win, sources say derived, registered stays with alive false; a pid the probe cannot decide is not stale; pidAlive itself (0.811774ms)
|
||||
✔ registration: no registration leaves the Gate A fields exactly as before, and registered is null (0.358055ms)
|
||||
✔ loadRegistrations: a missing seatsDir gives empty lists (0.129979ms)
|
||||
✔ loadRegistrations: one good record, one malformed JSON, one with an unknown field; a stray file under seatsDir is ignored (0.619848ms)
|
||||
✔ matchRegistration: matches by sessionsDir, and by realpath through a symlink; sessionsDir null never matches; same seat name with a different sessionsDir does not match (fleet vs repo darkwing) (0.259637ms)
|
||||
✔ scan: writes the registration override to disk; index.json carries registered and registrationErrors (0.639922ms)
|
||||
✔ scan: a relative seatsDir throws ConfigError; an omitted seatsDir behaves as before (0.570679ms)
|
||||
✔ scanAgent: waitingOnYou is true for waiting/error and false otherwise (0.41313ms)
|
||||
✔ scanAgent: ageSeconds is computed from the injected now (0.209496ms)
|
||||
✔ scanAgent: sessionFile null and state idle when sessions dir is empty but alive (0.129476ms)
|
||||
✔ discoverRepoAgents: finds agents with a sessions dir, skips those without, sorted by name (0.283055ms)
|
||||
✔ discoverFleetAgents: finds agents with a sessions dir, sorted by name, fleet tmux fields (0.389995ms)
|
||||
✔ scan: writes per-agent files and index.json, rerun overwrites, no leftover tmp files (0.806139ms)
|
||||
✔ scan: relative boardDir throws ConfigError (0.076236ms)
|
||||
✔ CLI: scan with assume-alive liveness exits 0, prints board summary, writes board files (49.618441ms)
|
||||
✔ CLI: missing config exits 2 with a refused: message (44.436197ms)
|
||||
✔ CLI: unknown command exits 2 (45.805376ms)
|
||||
✔ CLI: unknown --liveness value exits 2 (44.554996ms)
|
||||
✔ panesRunPi: true when any trimmed line equals 'pi' (0.184919ms)
|
||||
✔ panesRunPi: false for bash-only, claude, empty, or node-pi-style lines (0.070759ms)
|
||||
✔ tmuxIsAlive: a pane running pi is alive (0.153388ms)
|
||||
✔ tmuxIsAlive: session exists but pi has exited is not alive (0.061904ms)
|
||||
✔ tmuxIsAlive: no such tmux session is not alive (0.044464ms)
|
||||
✔ tmuxIsAlive: tmux could not be run at all is unknown (null), never assumed alive (0.057599ms)
|
||||
✔ tmuxIsAlive: passes -L <socket> only when a socket is given (0.083183ms)
|
||||
✔ parsePanes: one pane per line, command and optional tab-separated path (0.085566ms)
|
||||
✔ tmuxInspect: reports the path of the pane running pi, not of a shell pane (0.07682ms)
|
||||
✔ tmuxInspect: no pi pane, no session, or no tmux gives no workspace and the matching liveness (0.081359ms)
|
||||
✔ loadSeen: missing file returns {} (0.137796ms)
|
||||
✔ loadSeen: invalid JSON throws ConfigError (0.171609ms)
|
||||
✔ loadSeen: a JSON array throws ConfigError (0.134001ms)
|
||||
✔ loadSeen: a non-string value throws ConfigError (0.148924ms)
|
||||
✔ markSeen: seen true adds the key and writes seen.json mode 0600, no leftover tmp files (0.312966ms)
|
||||
✔ markSeen: seen false deletes the key (0.235435ms)
|
||||
✔ markSeen: missing, empty, or non-string fields throw ConfigError (0.17449ms)
|
||||
✔ markSeen: project containing '/' throws ConfigError (0.125742ms)
|
||||
✔ markSeen: non-boolean seen throws ConfigError (0.132316ms)
|
||||
✔ scanAgent: a seen mark matching the waiting session's lastTimestamp clears waitingOnYou (0.288515ms)
|
||||
✔ scanAgent: a stale mark (agent wrote something newer) is not seen and waitingOnYou is true (0.205325ms)
|
||||
✔ scanAgent: a working session with a matching mark is not seen (marks only apply to waiting/error) (0.212687ms)
|
||||
✔ scanAgent: an error-state session with a matching mark is seen (0.208361ms)
|
||||
✔ scan: index.seen and waitingOnYou reflect seen.json, which scan never rewrites or deletes (0.447094ms)
|
||||
✔ scan: a corrupt seen.json makes scan throw ConfigError (fail closed) (0.174598ms)
|
||||
✔ taskSetBy: a registered task carries the record's setter; a record without the field (pre-#1511) reads unknown; the value is not copied into registered (0.583986ms)
|
||||
✔ taskSetBy: null whenever the task shown is not the registered one: no registration, an empty registered task, a stale registration; the field is always present (0.538247ms)
|
||||
✔ taskSetBy: scan() reads the field from disk through the seat package (bounded there), writes it to the per-agent record and index, and an invalid on-disk value is a registrationError, never a row value (1.351605ms)
|
||||
✔ isLoopbackHost: recognizes loopback hosts (1.009372ms)
|
||||
✔ isLoopbackHost: rejects non-loopback hosts (3.839494ms)
|
||||
✔ startServer: refuses a non-loopback host with ConfigError, never opens a socket (2.485197ms)
|
||||
✔ startServer: serves page, healthz, and a rescanning /api/board (27.66894ms)
|
||||
✔ startServer: a seatsDir registration overrides the row and index.registered reflects it (4.701709ms)
|
||||
✔ startServer: /api/board returns 500 JSON with an error field when scan throws (1.872708ms)
|
||||
✔ CLI: serve refuses a non-loopback host with exit 2 and a refused: message (47.865018ms)
|
||||
✔ CLI: serve rejects a non-numeric --port with exit 2 (46.962074ms)
|
||||
✔ CLI: scan still works after the async cli refactor (43.454843ms)
|
||||
✔ CLI: live serve prints its URL and answers /healthz (57.337031ms)
|
||||
✔ page.html: esc() escapes every HTML-significant character (0.595049ms)
|
||||
✔ POST /api/seen marks a row; GET /api/board still shows it seen; seen:false clears it (7.778953ms)
|
||||
✔ POST /api/seen without a JSON content-type returns 400 and does not write a mark (2.88977ms)
|
||||
✔ POST /api/seen with invalid JSON returns 400 (1.518926ms)
|
||||
✔ POST /api/seen with a body over 4096 bytes returns 400 (or resets the connection) and writes no mark (1.975286ms)
|
||||
✔ POST /api/seen with a missing agent returns 400 (1.283889ms)
|
||||
✔ POST /api/board returns 405; PUT /api/seen returns 405 (1.684274ms)
|
||||
✔ CLI: scan --print marks a seen row with 's' and the summary line ends with 'N seen)' (48.014207ms)
|
||||
✔ page.html: seenControl() escapes rec.project/agent/lastActivity, and the POST uses a JSON content-type (0.291264ms)
|
||||
✔ page.html: has a collapsed Seen section that lists seen rows with the shared row builder (0.252489ms)
|
||||
✔ page.html: each project has a Hide seen checkbox (default on) beside Hide offline, with a hidden-count note (0.176304ms)
|
||||
✔ page.html: a project header reads "N of N" only while a checkbox hides rows (0.165091ms)
|
||||
✔ page.html: every row shows Task and Active project, derived or the word unknown, with the workspace in the detail (0.278927ms)
|
||||
✔ page.html: task and active project cells show their source via sourceTag(); the detail has a Registered row via registeredText(); SOURCE_LABEL maps registration to registered; every dynamic value in sourceTag/fromSource/registeredText is escaped (0.533415ms)
|
||||
✔ POST /api/reply: runs agent-send.sh with -s from the registration, -S <host>:control-board, -m text plus the fixed trailer, no -L on the default socket, MOSAIC_TMUX_SOCKET stripped; answers delivered with the exit code and both streams (24.657326ms)
|
||||
✔ POST /api/reply: a registration with a tmux socket adds -L <socket> (26.504081ms)
|
||||
✔ POST /api/reply: a non-zero tool exit is a 200 with delivered false, the exit code and the stderr verbatim (30.269703ms)
|
||||
✔ POST /api/reply: refusals before the tool runs: empty or blank or long text 400, unknown row 404, no registration 409, stale registration 409, no tmux session 409, bad JSON 400; the tool is never called (13.642702ms)
|
||||
✔ POST /api/reply: a missing agent-send.sh is a 500 with the path in the error, not a crash (4.373748ms)
|
||||
✔ replyToRow: DEFAULT_AGENT_SEND is the repository's tools/tmux/agent-send.sh and it is executable (0.176057ms)
|
||||
✔ page.html: the reply box appears only where canReply() holds (live registration with a tmux session), the detail has a Reply row, the submit posts JSON to /api/reply, receipts and drafts survive a refresh, and every receipt value is escaped (0.607977ms)
|
||||
✔ startServer: /api/board carries taskSetBy from a live registration and null for the derived rows (2.191136ms)
|
||||
✔ page.html: the task cell and detail show who set a registered task via setByTag()/setByText(), both escaped, only from rec.taskSetBy; the reply gate does not read it (0.271357ms)
|
||||
✔ Host/Origin guard: GET /api/board and POST /api/reply refuse a foreign Host, a wrong port and a cross-origin Origin with 403 JSON, before any scan or send, and never send CORS headers (7.33593ms)
|
||||
✔ Host/Origin guard: loopback names on this port are accepted, with or without a same-origin Origin (31.785264ms)
|
||||
✔ conversation routes (F16): a foreign Host, a wrong port and a cross-origin Origin get 403 before the reader runs, with no CORS headers (4.443313ms)
|
||||
✔ every refusal code the reader can raise has an HTTP status (0.899543ms)
|
||||
✔ conversation routes: catalogue, first page, next page and follow over HTTP; refusals map to 4xx with their code; nothing is written (44.981136ms)
|
||||
ℹ tests 124
|
||||
ℹ suites 0
|
||||
ℹ pass 124
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1138.402063
|
||||
@@ -0,0 +1,190 @@
|
||||
✔ W1: two processes acquire the same pair at once; exactly one claim (89.128339ms)
|
||||
✔ W1: two writers publish the same revision at once: one wins, the other gets null, the winner's record stays (5.888571ms)
|
||||
✔ W1: a revision name appears only after its bytes are synced; before that, only a temp file exists (2.826664ms)
|
||||
✔ W2: acquire while a claim is reserved or active refuses already-active (94.505629ms)
|
||||
✔ W3: acquire while stopping, uncertain, or stopped without proof refuses unsafe-replacement (149.706483ms)
|
||||
✔ W4: same session with another seat tuple, and the reverse, both refuse; a loser on the seat key closes it no-unit (129.110641ms)
|
||||
✔ W4: a hard link of one session under another seat is the same session: the second controller refuses already-active and launches nothing (16.210959ms)
|
||||
✔ W4: a copy of one session under another seat is the same session: the second controller refuses already-active and launches nothing (14.196341ms)
|
||||
✔ W4: a session header ID that changes after construction refuses target; nothing is claimed or launched (2.306698ms)
|
||||
✔ W5: SIGKILL between every publication barrier of acquire and transition; restart never finds two holders or a lost claim (5391.011686ms)
|
||||
✔ W5: SIGKILL between every publication barrier of release; restart finishes or holds the release (24241.833355ms)
|
||||
✔ W6: controller killed mid-turn while the engine lives; restart is uncertain, no launch, prompts refuse (147.082543ms)
|
||||
✔ W12: a live owner paused with SIGSTOP; a second controller refuses already-active and changes nothing (87.25443ms)
|
||||
✔ W13: crash after the engine spawns, before active; restart finds the live unit: uncertain, no second spawn, force stop only (263.126308ms)
|
||||
✔ W14: crash after reservation, before the spawn marker: stopped with a no-unit observation; the pair is free (177.788543ms)
|
||||
✔ W20: crash after the spawn marker, scope collected; uncertain in both runs, the marker is copied, no launch until a boot proof (200.483602ms)
|
||||
✔ W15: crash between the two keys during release; restart finishes it under the same claim ID (33.185623ms)
|
||||
✔ W7: recorded boot ID differs on the same machine: stopped with a boot proof; open tool calls become uncertain (104.382303ms)
|
||||
✔ W8: resume after a proven stop with the same pins: new claim ID, generation +1, same conversation, branch and leaf (31.413216ms)
|
||||
✔ W9: resume with a changed binary, argv digest, branch or leaf is refused and the claim is unchanged (88.175036ms)
|
||||
✔ W11: the controller writes no session file; only the fake engine's own appends appear (23.161375ms)
|
||||
✔ W16: a highest revision that won't parse holds the pair uncertain; the older stopped revision is not reused (48.144677ms)
|
||||
✔ W17: a claim root copied from another host refuses foreign-host and promotes nothing (51.471694ms)
|
||||
✔ G1: a session path or claim root under .pi/state, ~/.claude, the data root or a registration refuses at construction (3.531697ms)
|
||||
✔ G2: a symlink inside the fixture root to a live session file is refused by the real-path check (1.071299ms)
|
||||
✔ G3: a fixture path swapped for a live path after construction is refused at bind (1.744235ms)
|
||||
✔ no shim from this file's tests is left running for the after hook (5.408677ms)
|
||||
✔ K1: force stop kills a tool child that called setsid; stopped with a verified proof (258.956819ms)
|
||||
✔ K2: K1 on the process-group fallback ends uncertain, never stopped (141.138558ms)
|
||||
✔ K3: SIGTERM acknowledged while a member lives: stopping until the kill phase, never stopped from TERM (258.8513ms)
|
||||
✔ K4: two engines; force stop one; the other survives by independent observation (2278.674673ms)
|
||||
✔ K5: a stop during a tool call leaves the effect uncertain, and it is shown (168.610784ms)
|
||||
✔ K12: a member forking in a loop: the freeze stops it, enumeration is complete, populated 0 after cgroup.kill (268.043274ms)
|
||||
✔ K13: a member writing its pid into another cgroup is refused by the namespace; the kill is complete (178.480176ms)
|
||||
✔ K15: the shim gone, engine/cgroup.events unreadable, or the engine cgroup missing: evidence unavailable, not empty; uncertain (4366.69628ms)
|
||||
✔ K10: controller killed between the TERM and kill phases: restart checks the invocation ID and re-runs from TERM for the same stop (426.711404ms)
|
||||
✔ K11: controller killed after the confirmation is recorded, before TERM: restart checks the invocation ID and re-runs from TERM for the same stop (346.04341ms)
|
||||
✔ K14: a unit with the recorded name but another invocation ID: evidence unavailable, no signals, uncertain (265.886607ms)
|
||||
✔ K6: recover without proof, without confirmation, or with changed pins is refused (59.294043ms)
|
||||
✔ K7: recover after proof, then launch: new claim and execution, generation +1, same leaf; the cancelled prompt is not replayed (30.765394ms)
|
||||
✔ K8: an engine that loads another leaf on resume is refused before admission; it stays claimed until a proven stop (41.635981ms)
|
||||
✔ K9: an interrupt that never settles stays uncertain; force stop stays available; takeover is refused while fenced (3030.372154ms)
|
||||
✔ K16: a claim from another machine ID refuses foreign-host; no boot proof is issued (4.320596ms)
|
||||
✔ K17: two launcher calls with one eligibility record: one launch, the other refuses, no second engine (30.305262ms)
|
||||
✔ K18: the leaf changes after eligibility: launch refused; the reservation stays until released with proof (27.253466ms)
|
||||
✔ K19: a scope launched with only the engine environment still reaches the user manager; the engine sees no other names (82.631567ms)
|
||||
✔ R1: after a proven force stop the controller releases the scope; the shim and the unit are gone (182.712845ms)
|
||||
✔ R2: close releases the scope of a binding proven stopped, once, when the stop's own release hasn't run (280.417741ms)
|
||||
✔ R3: no release after an unavailable stop or an unverified proof: the scope and its shim stay as evidence (741.824275ms)
|
||||
✔ E1: a natural engine exit with no member left: an engine-exit stop, stopped on a proof naming the engine, and the scope released (197.786389ms)
|
||||
✔ E2: an engine exit with a tool child alive: the stop ends uncertain and nothing is released; a force stop then ends it (2264.60208ms)
|
||||
✔ E3: an engine exit and a force stop take one escalation slot, in either order (633.917621ms)
|
||||
✔ E4: a shim that doesn't answer: the engine-exit stop misses its deadline, ends uncertain and frees the slot (683.532295ms)
|
||||
✔ E5: an engine exit after a force stop ended uncertain starts no engine-exit stop; the force stop stays current (2445.254199ms)
|
||||
✔ E6: the engine-exit observation refuses a reaped process that isn't the recorded engine: another PID or start ticks (184.670515ms)
|
||||
✔ R5: the harness finds a running shim and reaps it, and never signals a shim outside a mosaic-chat- scope (Filbert N1 and N2 on #1533) (387.703565ms)
|
||||
✔ R6: releaseCohort releases nothing while the engine runs, for another invocation ID, or for a cohort without a scope (128.58331ms)
|
||||
✔ R7: controller killed after the claim is stopped, before the release: the restart releases the scope (2322.255245ms)
|
||||
✔ R8: controller killed between the two keys' stopped revisions: the restart releases the scope (246.150471ms)
|
||||
✔ R9: a release that ended unavailable is tried again on a confirmed recover, not a refused one (216.401469ms)
|
||||
✔ R10: close releases and signals nothing for a stopped binding whose proof no longer verifies (Filbert N3 on #1536) (158.501329ms)
|
||||
✔ R11: close({ killEngine: true }) after a proven stop sends no signal to the recorded engine PID; a restart releases nothing more (2272.793293ms)
|
||||
✔ R12: a restart onto a claim stopped on a boot proof releases nothing, though its scope is listed (161.593868ms)
|
||||
✔ no shim from this file's tests is left running for the after hook (4.512666ms)
|
||||
✔ S1: `/goal x`, with leading spaces or a tab, refuses text-policy at admission; zero engine bytes (30.143194ms)
|
||||
✔ S2: every prefix pinned Pi interprets is refused, from the list the code uses; the rest reach the engine exactly (18.899905ms)
|
||||
✔ S3: `/goal` on the second line is pinned from the source: Pi checks only index 0, so it is admitted and sent exactly (15.042591ms)
|
||||
✔ S4: a `/` left in the composer is cleared when control transfers and returns; the next submit sends only the new text (24.791694ms)
|
||||
✔ S5: an observer terminal gets a paste then Enter, as send-message.sh does: not admitted: controller, nothing sent (13.513875ms)
|
||||
✔ S6: a mediated-shaped registration (no tmux) passed to the board's replyToRow: 409 no tmux session; exec never runs (0.386997ms)
|
||||
✔ S7: ESC, bracketed-paste markers and U+2028/U+2029 travel as one JSON string; the engine receives the exact text in one record (13.520105ms)
|
||||
✔ P3: a Pi confirm, select, input or editor dialog is shown disabled with a reason and never answered (118.455051ms)
|
||||
✔ E1: send, ack, user, toolCall, toolResult, final answer: shown once, no refresh, draft and reading position kept (33.716733ms)
|
||||
✔ E2: U+2028, U+2029 inside JSON strings and CRLF line ends each parse as one record, on the splitter and through the controller (14.222891ms)
|
||||
✔ E3: a multipart final, two blocks, null request correlation and duplicate delivery (28.482746ms)
|
||||
✔ E4: a page read after message_end but before its entry is persisted: marker at the seam, re-read after run-settled, each message once (24.070559ms)
|
||||
✔ E4: a gap or a new epoch also reconciles; nothing is concatenated across a gap (10.731415ms)
|
||||
✔ E5: an unknown native event gives no client event; evidence records its type and bytes; the terminal count goes up (24.213256ms)
|
||||
✔ E6: a tool result delayed across a pause and a reconnect is reconciled without a manual refresh (40.021734ms)
|
||||
✔ E7: the terminal renders the same stream as the library client, as observer and then as controller, and submits only as controller (35.749668ms)
|
||||
✔ terminal: engine control characters are made visible; a lost connection refuses submit (20.278328ms)
|
||||
✔ terminal: outcome unknown is shown as such, with no resend offer, and nothing is resent (0.347097ms)
|
||||
✔ terminal: text after Enter in the same input chunk starts the next message; it never joins the one submitted (0.281248ms)
|
||||
✔ terminal: a paste-start marker split right after its ESC still opens the paste; the Enter inside it never submits (0.292326ms)
|
||||
✔ terminal: Ctrl-T then Enter in one chunk is judged after the takeover, as if typed one key at a time (Filbert F2, #1507) (0.440393ms)
|
||||
✔ terminal: input held behind Ctrl-T waits for that takeover while an earlier action is still pending (Darkwing T1 on #1522) (31.219765ms)
|
||||
✔ terminal: a hold inside held input holds again, and once it is drained later input and Ctrl-C still reach the terminal (Darkwing note 1 on #1522) (0.399173ms)
|
||||
✔ terminal: an action that throws still releases the input held behind it, in order, then rethrows (4.769418ms)
|
||||
✔ terminal: after an action throws, later input still runs; input() puts the error in the status line (Filbert N1 on #1522) (0.363675ms)
|
||||
✔ terminal: input() reports an error when it happens, so it never overwrites a later status; held input's promise doesn't carry the holder's error (Filbert N4 on #1522) (0.354012ms)
|
||||
✔ terminal: invisible and bidi characters are made visible; head, status and notice lines stay one line (0.098828ms)
|
||||
✔ every record these fixtures produced is a valid CHAT-01 record (E5: no record fails the schema) (173.936415ms)
|
||||
✔ H1: two takeovers with the same expected generation: one wins, +1; the other refuses generation (38.141412ms)
|
||||
✔ H2: the old controller's prompt after a takeover commits is refused with zero engine bytes (73.653524ms)
|
||||
✔ H3: a takeover while a prompt holds the dispatch lock: written under the old actor, or refused; never both (121.156446ms)
|
||||
✔ H4: self-takeover is refused (13.968262ms)
|
||||
✔ H9: Interrupt racing a prompt's dispatch: before the write, dispatch-refused and no-turn; after, §3 rules (81.383138ms)
|
||||
✔ H10: Interrupt and force stop together: one stop chain, force stop supersedes (62.076056ms)
|
||||
✔ H10: an overlap during the pause before the abort: no abort, the stop ends uncertain (19.078058ms)
|
||||
✔ H10: a no-turn Interrupt lifts only its own fence; admission stays closed under force stop, overlap or revocation (61.39802ms)
|
||||
✔ H11: the controller disconnects mid-turn: work continues, the claim is unchanged, control stays put (127.750864ms)
|
||||
✔ H12: an exact retry after reconnecting to the same incarnation returns the same receipt; one dispatch (16.036103ms)
|
||||
✔ H13: a retry with the same request ID and different text is refused (13.088168ms)
|
||||
✔ H14: late stdout from the old engine after a replacement is dropped by incarnation, counted, never rendered (130.988661ms)
|
||||
✔ H15: a revoked connection's command is refused; the revocation fence holds (68.690663ms)
|
||||
✔ H16: a second controller for the same session refuses already-active; the first is untouched (16.328561ms)
|
||||
✔ H10: a second force stop while the first escalation runs refuses fenced; one escalation, and the claim records only the first stop's phases (49.103674ms)
|
||||
✔ a force stop whose fence throws leaves no escalation flag behind, so the next force stop runs (Darkwing F2, #1507) (19.725492ms)
|
||||
✔ H17: a confirmation reused, answered from another connection, or used after the stop changed is refused (50.788525ms)
|
||||
✔ H18: two prompts before any native output: the second refuses busy; one engine write (12.613325ms)
|
||||
✔ H19: the pipe fails mid-line under a large prompt: delivery-unknown transport-unknown, poisoned, no later write (116.172472ms)
|
||||
✔ H19: the link itself never writes again after an unknown outcome, whoever calls it (0.683954ms)
|
||||
✔ H19: the controller dies mid-write of a large line: after restart the outcome is unknown and nothing is resent (460.63673ms)
|
||||
✔ H20: the line is written but the ack is lost when the controller dies: orphan, outcome unknown, nothing resent (355.167071ms)
|
||||
✔ H21: a retry of the exact request with the old token after a crash is stale-incarnation; no second write (322.417347ms)
|
||||
✔ H22: after H21 and a valid recovery, a new request with the new token is admitted (2375.973198ms)
|
||||
✔ H23: requests pending at a restart are not resent; each shows outcome unknown (459.57665ms)
|
||||
✔ no shim from this file's tests is left running for the after hook (4.561507ms)
|
||||
✔ a plain conversation: catalogue row, one page, CHAT-01 records (4.906635ms)
|
||||
✔ native entries map to blocks: tools, thinking, bash, notices, ids that do not fit (1.299434ms)
|
||||
✔ F1: a malformed line is an unavailable part at its position, and reading continues (1.399298ms)
|
||||
✔ F1: a missing parent stops the history with a notice that names the unreadable lines (2.170906ms)
|
||||
✔ F1: an unreadable fork is never merged into another branch's history (1.304067ms)
|
||||
✔ F1: a follow stays on its branch when the next entry's parent is unreadable (1.575693ms)
|
||||
✔ F1: a file whose entries are all unreadable shows a notice per line (0.609119ms)
|
||||
✔ F2: a truncated trailing line marks the view incomplete, not an error (1.027221ms)
|
||||
✔ pagination: 100 parts, then the rest; parts concatenate to the whole branch (2.903442ms)
|
||||
✔ F3: a replaced file (new inode) refuses old cursors with reconcile (3.308129ms)
|
||||
✔ F4: a same-inode rewrite of the prefix refuses old cursors with reconcile (4.043266ms)
|
||||
✔ F5: growth between pages keeps the epoch and the page stops at the pinned length (3.783605ms)
|
||||
✔ F6: unknown, foreign and expired cursors refuse and leave the cursor usable (6.045374ms)
|
||||
✔ F7: a symlinked file and a symlinked directory component are refused, never opened (6.508454ms)
|
||||
✔ F8: a file swapped for a symlink after the catalogue is refused (1.538462ms)
|
||||
✔ F9: registrations never add or redirect a root (1.204078ms)
|
||||
✔ F10: a header cwd naming another project is refused (2.724055ms)
|
||||
✔ F11: parentSession renders with a marker and the parent is never opened (0.646815ms)
|
||||
✔ F12: two leaves: the default leaf is shown and the other branch reads alone (3.818164ms)
|
||||
✔ F12: a follow refuses when an appended duplicate id changes the branch's earlier parts (2.015393ms)
|
||||
✔ F12: a second root (Pi's resetLeaf) starts its own branch (1.01494ms)
|
||||
✔ F13: compaction is a marker in place, then the retained content (0.567531ms)
|
||||
✔ F14: long strings split into fragments and parts, reassemble exactly, and pages respect the byte cap (451.23899ms)
|
||||
✔ fragments never cut a surrogate pair and keep an empty string (4.18052ms)
|
||||
✔ F15: a Claude seat is an unsupported-harness placeholder whose directory is never read (1.341478ms)
|
||||
✔ unknown conversations, empty files and non-Pi files refuse (2.022362ms)
|
||||
✔ an unreadable file or root inside the roots is refused per row, not a failed catalogue (0.958755ms)
|
||||
✔ a seat directory without search permission refuses that root, not the catalogue (1.654924ms)
|
||||
✔ every page and cursor is a valid CHAT-01 record (654.73763ms)
|
||||
✔ the engine pin holds for the installed package (1.589059ms)
|
||||
✔ pinned Pi, sealed and without credentials, answers the controller's commands with the shapes the fake models (225.058278ms)
|
||||
✔ sealed, pinned Pi ignores a trusted project's .pi resources; --approve past the seal would load them, and checkSeal refuses it (Filbert F2 on #1522) (455.744459ms)
|
||||
✔ pinned Pi appends thinking_level_change at start when the branch lacks one, so the leaf moves (K8 then fails closed) (214.046013ms)
|
||||
✔ N25: ordinary Interrupt reconciles; a non-empty queue_update in the window is O5 (59.490053ms)
|
||||
✔ N1: an extension's follow-up queued after the fence is cleared before any abort; O5, Unknown (29.869305ms)
|
||||
✔ N1: a follow-up queued before the fence is O5 at once; the Interrupt refuses fenced (15.50807ms)
|
||||
✔ N2: with abort first, the fake runs the external item (the ordering guard has teeth) (21.677266ms)
|
||||
✔ N3: the fence lands in preflight, preflight errors, no run: failed, No run, uncertain (25.449774ms)
|
||||
✔ N4: the ack arrives after the first abort and a run starts: clear and abort again; Interrupted (18.155355ms)
|
||||
✔ N5: an input handler takes the prompt: ack, no run, delivery-unknown handled-without-run (114.405832ms)
|
||||
✔ N6: an extension queues between clear_queue and abort: O5 and O6, Unknown (36.044731ms)
|
||||
✔ N7: clear_queue times out: no abort, nativeQueue unknown, force stop still ends it (1526.152531ms)
|
||||
✔ N7: clear_queue answers an error: no abort, nativeQueue unknown, the link not poisoned (14.50946ms)
|
||||
✔ N8: an extension prompt starts a run during Mosaic preflight; the losing settle is O3 (70.754941ms)
|
||||
✔ N9: a run that started before the fence and ends aborted: failed interrupted, Interrupted (15.675912ms)
|
||||
✔ N9: decision 34: a run that ends aborted with no stop in progress: aborted-without-stop, uncertain, outcome unknown (16.23356ms)
|
||||
✔ N9: an aborted that lands after the fence but before any abort is written: aborted-without-stop, Unknown (30.462228ms)
|
||||
✔ N10: fake conformance (31.272977ms)
|
||||
✔ N11: the run fails before any user message_start: delivery-unknown ack-without-start, never failed (30.073368ms)
|
||||
✔ N12: input that starts a run after the final empty clear is O1 and not part of the stop's proof (18.535948ms)
|
||||
✔ N13: agent_start with no slot held is O1; a later prompt refuses with zero engine bytes (66.4181ms)
|
||||
✔ N14: the run completes while clear_queue is in flight: finished, Completed first, uncertain (27.820319ms)
|
||||
✔ N14: the run completes after the abort is written, before Pi applies it: finished, never relabelled (26.07024ms)
|
||||
✔ N15: the fence lands in preflight, then an input handler takes it: handled-without-run, No run (19.949151ms)
|
||||
✔ N16: Interrupt with no slot and no run refuses no-turn: no stop, no bytes, admission open (13.918188ms)
|
||||
✔ N17: the run fails on its own during the exchange: failed, Failed on its own (25.627202ms)
|
||||
✔ N18: no final assistant message_end, or a lost line: working stays working; before working, transport-unknown (106.759663ms)
|
||||
✔ N19: a losing extension prompt settles inside the Mosaic run before its user message: O3, run-overlap (133.114987ms)
|
||||
✔ N20: an extension triggerTurn during Mosaic preflight starts first; while streaming it queues with no signal (81.673775ms)
|
||||
✔ N21: a losing settle after the receipt settled finished is O2; the receipt stays finished (15.52735ms)
|
||||
✔ N22: an agent-level custom message is dropped by the clear with no signal; evidence names the seal (12.367065ms)
|
||||
✔ N23: a nextTurn message survives clear and abort and attaches to the next prompt, with no signal (13.814769ms)
|
||||
✔ N24: the seal is an allow-list: --extension, a missing --no-* flag, a second --mode or --session, a session or output flag, or a stray word refuses unsealed-engine; no engine starts (38.129341ms)
|
||||
✔ N24b: the seal covers the engine command and environment: config can't name either, the env is built from names, and a mutated command is refused at bind (26.652363ms)
|
||||
ℹ tests 182
|
||||
ℹ suites 0
|
||||
ℹ pass 182
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 75108.02449
|
||||
@@ -0,0 +1,191 @@
|
||||
✔ approvals: a request is validated before anything is posted; the rendering shows names and never ids (1.579959ms)
|
||||
✔ approvals: the ledger is appended and folded into open requests with bind and approval states (0.758897ms)
|
||||
✔ approvals: a reply approves only when it points at a request, says exactly approve, and comes from a listed approver once (0.283961ms)
|
||||
✔ approvals: a button approves only on its own request message with the matching custom id (0.243609ms)
|
||||
✔ approvals flow: a turn that opened a request posts the message with the button, records it, binds it, and both approvers approve (7.14839ms)
|
||||
✔ approvals flow: a non-approver, a repeat, a wrong custom id and a service refusal each get their fixed line and a drop entry (5.115489ms)
|
||||
✔ approvals flow: an invalid request from the model, a refused post, and no api client are recorded and post nothing (7.216258ms)
|
||||
✔ approvals flow: start retries a bind and an approval left as unknown, under their original keys (1.875179ms)
|
||||
✔ authorize: open channel, listed user (0.983642ms)
|
||||
✔ authorize: wrong guild (0.087771ms)
|
||||
✔ authorize: no guild (DM) (0.079436ms)
|
||||
✔ authorize: unlisted channel (0.219244ms)
|
||||
✔ authorize: unknown channel, no info (0.077904ms)
|
||||
✔ authorize: thread of listed parent (0.101089ms)
|
||||
✔ authorize: thread of unlisted parent (0.067004ms)
|
||||
✔ authorize: text channel that is not a thread and not listed (0.060564ms)
|
||||
✔ authorize: unlisted user (0.095707ms)
|
||||
✔ authorize: no author (0.122795ms)
|
||||
✔ authorize: bot author (listed id, bot flag) (0.076507ms)
|
||||
✔ authorize: system author (0.064406ms)
|
||||
✔ authorize: the bot itself (0.04337ms)
|
||||
✔ authorize: webhook (0.040334ms)
|
||||
✔ authorize: mention channel without mention (0.062203ms)
|
||||
✔ authorize: mention channel with bot mention (0.066353ms)
|
||||
✔ authorize: mention channel with @everyone only (0.044522ms)
|
||||
✔ authorize: mention channel mentioning someone else (0.047ms)
|
||||
✔ authorize: mention channel, content says @bot but mentions empty (0.043385ms)
|
||||
✔ authorize: private thread under mention channel, mentioned (0.038538ms)
|
||||
✔ authorize: private thread under mention channel, not mentioned (0.029732ms)
|
||||
✔ authorize: thread in another guild per channel info (0.033783ms)
|
||||
✔ authorize: not an object (0.029845ms)
|
||||
✔ authorize: no id (0.028179ms)
|
||||
✔ authorize: oversize content is accepted and flagged (0.031224ms)
|
||||
✔ authorize: exactly the limit is not oversize (0.027655ms)
|
||||
✔ authorize: a user's channel allowlist drops them outside it, threads count as the parent, others are unaffected (0.263642ms)
|
||||
✔ authorize: order puts wrong guild before user, and user before channel (no channel lookup for strangers) (0.072788ms)
|
||||
✔ binding: a complete binding validates and is frozen (1.43389ms)
|
||||
✔ binding: unknown key, missing field, wrong type refuse with exit 2 (0.730451ms)
|
||||
✔ binding: empty allowlists refuse (0.216505ms)
|
||||
✔ binding: a user's channel allowlist must be non-empty, listed and unique; absent means every listed channel (0.733684ms)
|
||||
✔ reloadDiff: reloadable keys are summarised by id; every fixed key refuses with exit 2 (0.897545ms)
|
||||
✔ binding: dmRecipient is optional, a snowflake, one of the listed users, and a fixed key (0.258014ms)
|
||||
✔ binding: file must be 0600, regular, not a symlink (0.853155ms)
|
||||
✔ binding: token file mode, symlink, emptiness and shape are checked; token never appears in errors (0.775047ms)
|
||||
✔ cli: check refuses a non-0600 token file with exit 2 before any network use (55.411264ms)
|
||||
✔ context files: absolute paths, traversal, symlinks and out-of-repo targets refuse; in-repo files resolve (1.610379ms)
|
||||
✔ cli: check refuses a missing context file and a missing binding with exit 2; usage is exit 4 (256.495918ms)
|
||||
✔ cli: reload validates the file first (exit 2), then needs a live owner (exit 1); usage is exit 4 (153.240573ms)
|
||||
✔ cli: run refuses when STOP is present, before any network use (102.914762ms)
|
||||
✔ binding: tools is optional, validated strictly, a fixed key for reload, and its roots are resolved against the data root (1.579457ms)
|
||||
✔ binding: a git key is validated at load and reaches the extension whole, and only on a writable root (1.030132ms)
|
||||
✔ delivery: an accepted message is in the inbox before the turn, the reply is chunked with one nonce per chunk, and the turn record is write-once (7.605759ms)
|
||||
✔ delivery: refused and unknown outcomes are journaled; a later chunk is not sent after a failure (8.923793ms)
|
||||
✔ delivery: restart with an unknown entry re-sends the same nonce once and reconciles before accepting traffic (0.663478ms)
|
||||
✔ delivery: an unknown entry older than the dedupe window is marked refused, not re-sent; a still-unknown one refuses start (0.573128ms)
|
||||
✔ delivery: repeated unknown reconciliations never refresh the dedupe window; the original intent time decides (0.636872ms)
|
||||
✔ turn: a failed engine turn posts the fixed line, never model output, and writes a failed record (2.211347ms)
|
||||
✔ turn: a second message during a turn is held by the engine, both get their own reply and record (31.007851ms)
|
||||
✔ turn: a thread under a listed channel is answered in the thread; an unknown thread is looked up once (2.378052ms)
|
||||
✔ drop: an unlisted user gets silence and one drop line; no inbox entry, no REST call, no engine call (0.487088ms)
|
||||
✔ drop: an oversize message is accepted into the inbox, answered with the fixed line and journaled as a drop (0.490636ms)
|
||||
✔ restart: an inbox with three ids and a replay of the same three produces zero turns (41.871775ms)
|
||||
✔ stop: STOP present refuses start; STOP written while running refuses new turns and the current one finishes (31.061728ms)
|
||||
✔ ceiling: the ceiling plus one is refused and journaled; one fixed line per UTC day; a new day accepts again (4.854631ms)
|
||||
✔ ceiling: a burst arriving while turns are still running cannot queue past the ceiling (3.327357ms)
|
||||
✔ ceiling: a turn interrupted by a crash still counts after restart; admissions are durable (2.084407ms)
|
||||
✔ ceiling: the daily notice survives a same-day restart; one delivery attempt in total, even when the first attempt crashed mid-flight (3.584815ms)
|
||||
✔ duplicate: the same event delivered twice while the thread lookup is held yields one prompt, one admission and one reply (1.89471ms)
|
||||
✔ journal: no token-shaped string and no model output on the drop path reaches disk (0.346369ms)
|
||||
✔ receipt: an admitted message gets one eyes reaction on the inbound message; drops and refusals get none; a failed reaction is recorded and does not fail the turn (1.946421ms)
|
||||
✔ receipt: Discord refusing the reaction leaves the turn intact and records ok false (1.692926ms)
|
||||
✔ reload: a new user is silent before and answered after; a removed channel goes silent; a lower ceiling applies at once (3.27299ms)
|
||||
✔ reload: a fixed key refuses with exit 2 and the old binding stays in force (1.747781ms)
|
||||
✔ tools: with a tools binding the turn record lists every read and its outcome; without one the field is null (3.420895ms)
|
||||
✔ context: the Discord block names the server, channels and modes, and states the rules from Q15 and Q16 (1.253496ms)
|
||||
✔ context: with tools the block names the roots, keeps file content as data, and says to state refusals plainly (0.399275ms)
|
||||
✔ context: a writable root adds the write rules and says a write is real only once Jason commits (0.929925ms)
|
||||
✔ context: the envelope is one bracketed line then the text; names cannot break the line (0.596504ms)
|
||||
✔ context: a git root swaps the terminal-commit line for the git verbs, and a vault root adds the id protocol (0.710975ms)
|
||||
✔ context: assembleContext concatenates files in launcher format and appends the block; sha256 is stable (0.575199ms)
|
||||
✔ context: splitReply keeps paragraphs together under the limit and splits long ones at lines, spaces, then hard (0.342309ms)
|
||||
✔ pinned Discord render/install and missing prerequisites; checkout bytes unchanged (38.188261ms)
|
||||
✔ Discord status reports effective WorkingDirectory from a fake user manager (29.582954ms)
|
||||
✔ engine: buildPiArgs carries the fixed flags, engine settings, session dir and prompt file (1.219049ms)
|
||||
✔ engine: with tools, buildPiArgs turns pi's own tools off, loads the extension explicitly and allowlists exactly our three (0.198954ms)
|
||||
✔ engine: a run with tool turns settles once, on the answer, with every tool call in the result (27.522115ms)
|
||||
✔ engine: a run that ends on a tool-only turn fails the prompt as empty; a retried run settles on the real end (27.135499ms)
|
||||
✔ engine: one prompt, one turn, text and usage come back (23.886192ms)
|
||||
✔ engine: a prompt while streaming is held until pi settles, then sent as its own run, and answered in order (328.080395ms)
|
||||
✔ engine: a held prompt that times out before pi settles fails on its own and is never sent (224.272545ms)
|
||||
✔ engine: timeout sends abort and fails only that turn; the process stays (114.218336ms)
|
||||
✔ engine: tool events from a run that outlived its timeout never land in the next prompt's record (226.589418ms)
|
||||
✔ engine: a prompt after a turn that timed out before its agent_start waits for pi to settle instead of being refused (124.966879ms)
|
||||
✔ engine: when pi has not started a timed-out turn by the end of the abort grace, the engine stops pi and fails held prompts (212.783112ms)
|
||||
✔ engine: a timed-out turn pi starts only after the grace never answers a later prompt (615.188363ms)
|
||||
✔ engine: late events of a run past its grace, before pi exits, answer nothing and nothing more is sent (early prompt response) (1.501927ms)
|
||||
✔ engine: late events of a run past its grace, before pi exits, answer nothing and nothing more is sent (late prompt response) (0.577995ms)
|
||||
✔ engine: a timed-out run pi did start outlives the grace; the next prompt goes out when it ends (427.998703ms)
|
||||
✔ engine: a malformed JSONL line fails the turn, not the process (26.514474ms)
|
||||
✔ engine: a turn that ends in error rejects with the error code; process exit fails pending turns (45.318163ms)
|
||||
✔ gateway: hello -> identify with intents, ready, heartbeat with jitter, ack (1.250684ms)
|
||||
✔ gateway: missed ack closes the socket and resumes with the last sequence (0.803347ms)
|
||||
✔ gateway: op 7 reconnect resumes; op 9 non-resumable re-identifies (0.230335ms)
|
||||
✔ gateway: op 9 resumable resumes (0.206799ms)
|
||||
✔ gateway: close 4014 is fatal, reports the missing intent, never reconnects (0.447506ms)
|
||||
✔ gateway: 4004 and 4013 are fatal too; 1006 reconnects with identify when no session (0.257544ms)
|
||||
✔ gateway: close() is final and unparseable frames are ignored (0.196761ms)
|
||||
✔ git: config validation is strict, needs write: true, a work tree and a private token file (30.406891ms)
|
||||
✔ git: the child environment drops every host git config, names one helper, and carries the token path only for origin (25.287485ms)
|
||||
✔ git: status reports the branch, ahead/behind and changed paths, and refuses off the named branch or mid-merge (48.592342ms)
|
||||
✔ git: parseStatus reads porcelain v2 including renames and conflicts (0.231563ms)
|
||||
✔ git: a commit stages exactly the named files, carries the seat author and the requester trailer, and pushes at once (60.589188ms)
|
||||
✔ git: commit refusals: message, paths, requester, nothing to commit, and an index that already holds other work (68.094034ms)
|
||||
✔ git: a commit whose push fails is still a commit, says so, and the next commit's push carries both (D6) (66.839341ms)
|
||||
✔ git: pull is fast-forward only; a diverged origin or dirty local files refuse with nothing merged (138.41509ms)
|
||||
✔ git: push pushes the named branch only and reports up to date (51.388275ms)
|
||||
✔ git: no token value or token path ever reaches a git argument list; outputs are masked and capped (68.659049ms)
|
||||
✔ git: the credential helper answers get over https from a private file and nothing else (186.048008ms)
|
||||
✔ git: the vault protocol validates before a commit, honours another owner's lock, reserves ids, and locks around writes (341.274374ms)
|
||||
✔ lock: the claim is exclusive; a second start against a live owner refuses (2.307219ms)
|
||||
✔ lock: a stale lock (dead owner, reused pid, or record without start) refuses run and is never signaled; only unlock clears it (44.342094ms)
|
||||
✔ lock: an incomplete claim (directory without owner record) is busy and refuses run; unlock clears it (1.163447ms)
|
||||
✔ lock: an owner record that exists but cannot be read is invalid: never signaled, never removed, never claimed over (1.301609ms)
|
||||
✔ lock: legacy upgrade; a live connector holding a {pid, start} record is unknown, unlock refuses and nothing changes; after it exits, unlock clears it (29.37348ms)
|
||||
✔ lock: a live pid whose record carries a malformed or noncanonical start or boot string is unknown, not a mismatch; nothing signals, removes, or claims over it (249.989327ms)
|
||||
✔ lock: identity syntax; only canonical unsigned decimal start ticks and lowercase boot uuids are identities (0.337574ms)
|
||||
✔ lock: a process whose start marker or boot id cannot be read refuses to claim (19.200579ms)
|
||||
✔ lock: a live pid whose identity cannot be read right now is unknown: never signaled, never removed, never claimed over (0.836242ms)
|
||||
✔ lock: four processes racing for the same binding; exactly one claims it and the others refuse (30.893462ms)
|
||||
✔ lock: stale handoff; concurrent starts over a stale lock all refuse, nothing reclaims, one unlock then exactly one live owner (105.141232ms)
|
||||
✔ lock: four-party schedule; claims landing inside an unlock's gap never survive, one unlock leaves no owner and no residue (69.92893ms)
|
||||
✔ notices: a kind is recorded per UTC day and found again (0.39667ms)
|
||||
✔ notify: the DM channel opens once, every send carries the nonce, and only the message id comes back (2.484512ms)
|
||||
✔ notify: refusals and unknowns surface as RestOutcome without ids; a refused send reopens the channel next time (1.001158ms)
|
||||
✔ notify: no dmRecipient, a non-0600 binding or token, or a missing binding refuse before any network use (0.753569ms)
|
||||
✔ check --offline validates local fixture without REST or gateway calls (110.658565ms)
|
||||
✔ check --offline refuses token mode and missing context under the selected repo (124.8283ms)
|
||||
✔ run --offline is a usage refusal before reading config or networking (53.962735ms)
|
||||
✔ recover: nothing to do is clean; a lock whose owner is gone or that has no record is cleared and STOP ends up absent (24.97744ms)
|
||||
✔ recover: an operator STOP refuses with exit 3 and is never removed, whatever the lock says (24.74025ms)
|
||||
✔ recover: a brake written during the unlock wins; STOP stays with both lines and the start is refused (23.844193ms)
|
||||
✔ recover: a held binding refuses with exit 3 and writes no STOP: live owner, alive pid without verifiable identity, unreadable record (62.919925ms)
|
||||
✔ cli: recover exits 0 when ready, 3 behind a brake or a held binding, and run's own STOP refusal is 3 (607.303443ms)
|
||||
✔ rest: createMessage sends nonce, enforce_nonce, empty allowed_mentions and a soft reply reference (1.296315ms)
|
||||
✔ rest: 429 waits retry_after and retries; 4xx is refused; 5xx and socket errors are unknown (4.420922ms)
|
||||
✔ rest: content and nonce limits are enforced locally; typing never throws (0.359874ms)
|
||||
✔ rest: react PUTs the encoded emoji on the inbound message for @me; 2xx is true, anything else is false and never throws (0.389762ms)
|
||||
✔ rest: createDm posts the recipient and resolves the channel id; 4xx refused, 5xx unknown, bad id never sent (0.444538ms)
|
||||
✔ setspark config: a bare https or loopback origin, a private key file, a principal (2.944217ms)
|
||||
✔ setspark config: reaches the tools config and the binding as a fixed key (2.009998ms)
|
||||
✔ setspark config: the binding's key survives resolveToolRoots and the engine's JSON hand-off to the extension (0.89185ms)
|
||||
✔ setspark config: approvers come from the binding's users, never from the binding's setspark key (1.107736ms)
|
||||
✔ setspark verbs: required_approvers go out as discord ids from names and come back as names (14.008638ms)
|
||||
✔ setspark verbs: no Discord user id reaches tool text, whatever shape the service returns it in (6.348988ms)
|
||||
✔ setspark contract: a decision made with names opens a request the connector accepts; names stored by an old record still refuse (3.778605ms)
|
||||
✔ setspark keys: read per call, one printable token per file, rotation without a restart (2.379873ms)
|
||||
✔ setspark idempotency keys: principal, turn id, call index; connector keys name a step (0.346923ms)
|
||||
✔ setspark http core: json in and out, bearer header, idempotency header, fixed user agent, no key anywhere else (1.508424ms)
|
||||
✔ setspark http core: error bodies become fixed refusals with code and the 409 fields; server text is data, cut (1008.070684ms)
|
||||
✔ setspark verbs: a setspark key enables the eight verbs and no counters (1.022992ms)
|
||||
✔ setspark verbs: writes carry the turn's key and the asserted requester, reads carry no key, and the api key never appears in text or details (6.604452ms)
|
||||
✔ setspark verbs: no turn refuses every write before any request; bad arguments refuse before any request; reads still work (1.225162ms)
|
||||
✔ setspark verbs: renderRecord caps long output and hides the accepted snapshot (0.202415ms)
|
||||
✔ setspark api: bind, add_approval (button and reply) and get use integer request ids and the connector's keys (2.268987ms)
|
||||
✔ tools: config refuses a missing, symlinked, dotted, non-directory or duplicate root and bad limits (2.079177ms)
|
||||
✔ tools: every escape is refused with a fixed reason and nothing outside the root is read (2.004351ms)
|
||||
✔ tools: happy paths list, read a window, and search case-insensitively; dotfiles and symlinks never appear (2.508878ms)
|
||||
✔ tools: the tool set renders text for the model, records details for the journal, and enforces the per-run budget (2.134287ms)
|
||||
✔ tools: listing and search caps hold (5.338412ms)
|
||||
✔ tools: credential shapes are caught; ordinary prose and ids are not (0.590913ms)
|
||||
✔ tools: the read uses the checked file itself; a symlink, a swapped file, a FIFO, a grown file or a hard link at read time is refused (3.309865ms)
|
||||
✔ tools: an unreadable file under the root is skipped by search and refused by read (0.711307ms)
|
||||
✔ tools: config accepts write: true only as a boolean, and enables the write tools only then (0.710201ms)
|
||||
✔ tools: every write outside the fence is refused before any byte lands, and no temp file remains (3.64714ms)
|
||||
✔ tools: write_file leaves the exact bytes, edit_file replaces one exact match, and the set renders the change as uncommitted (1.735504ms)
|
||||
✔ tools: a target that changed between the check and the rename is refused and the temp file is removed (0.991696ms)
|
||||
✔ web: config takes an https or loopback-http SearXNG base url and a bounded fetch cap (2.25294ms)
|
||||
✔ web: address rules refuse every private, loopback, link-local, mapped and multicast form (1.548688ms)
|
||||
✔ web: web_fetch refuses bad urls, private hosts, rebinding names, non-https redirects, too many hops, error status, non-text bodies, and times out (1023.737556ms)
|
||||
✔ web: web_fetch returns html as text with the title, follows an https redirect, keeps plain text and json, and cuts at the cap (4.061909ms)
|
||||
✔ web: html to text drops scripts, styles and comments, decodes entities and keeps block breaks (0.199726ms)
|
||||
✔ web: web_search asks the instance for json, returns at most ten clean results, and refuses a bad query, a down instance or an unusable answer (2.514379ms)
|
||||
✔ web: the tool set enables the web tools only with a web key, counts them in the budget, and records url, status and hits (2.108089ms)
|
||||
ℹ tests 183
|
||||
ℹ suites 0
|
||||
ℹ pass 183
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 9147.33449
|
||||
@@ -0,0 +1,92 @@
|
||||
✔ sessionModel: agent vars win, then the system's execution settings (8.336262ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (3.73651ms)
|
||||
✔ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (1.83352ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (1.960877ms)
|
||||
✔ the prompt's built-in tools line is the harness's own names, as the manifest lists them (6.365162ms)
|
||||
✔ the prompt names the project clones in the workspace, and none when there are none (4.178899ms)
|
||||
✔ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (5.321894ms)
|
||||
✔ a bundle is written once: an existing file refuses (1.195191ms)
|
||||
✔ a path with a single quote can't go into the hook command (1.627967ms)
|
||||
✔ allow exits 0, a deny exits 2 with the reason on stderr (91.785693ms)
|
||||
✔ a missing or wrong policy, or a bad event, exits 2 (70.197842ms)
|
||||
✔ the bundle's wrapped command: a missing gate or node still blocks (1081.759522ms)
|
||||
✔ claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist (630.039285ms)
|
||||
✔ claude: the hook alone blocks a path outside the workspace (372.91978ms)
|
||||
✔ claude: a second turn resumes the first turn's session (629.321399ms)
|
||||
✔ claude adapter: --restricted is always passed (5.60668ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (15.415489ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (5.654092ms)
|
||||
✔ claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do (655.381315ms)
|
||||
✔ claude: a missing hook or MCP file refuses before claude starts (7.387197ms)
|
||||
✔ pi: policy tools and typed tools pass, anything else is blocked (2.307652ms)
|
||||
✔ claude: builtins map from pi names, typed tools need the mcp prefix (0.50058ms)
|
||||
✔ file tool paths must resolve inside the workspace (0.864654ms)
|
||||
✔ pi's own path normalisation can't be used to step out (0.707123ms)
|
||||
✔ a symlink inside the workspace that points out is outside (0.619251ms)
|
||||
✔ a dangling symlink is refused at any depth, in both harnesses (1.997468ms)
|
||||
✔ read is checked under every spelling pi's read would open, in both harnesses (10.015755ms)
|
||||
✔ other spellings cover directories, dangling links and pi's cwd (0.953892ms)
|
||||
✔ a relative path climbs from the workspace's real path, in both harnesses (3.099227ms)
|
||||
✔ claude path fields per tool (0.432944ms)
|
||||
✔ glob patterns stay inside the workspace (0.440722ms)
|
||||
✔ a path that can't be checked is blocked (0.248403ms)
|
||||
✔ fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX (158.003536ms)
|
||||
✔ fetch_review's have orders the working refs newest first within each clone, one clone after another (113.915448ms)
|
||||
✔ a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period (1809.588064ms)
|
||||
✔ once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (303.912453ms)
|
||||
✔ initialize, ping and tools/list (32.054718ms)
|
||||
✔ tools/call goes through the tool socket; a refusal is an isError result (28.373541ms)
|
||||
✔ replies are compact JSON; over the cap a tool error names the size and the cap (31.650781ms)
|
||||
✔ unknown tools and methods are JSON-RPC errors and never reach the socket (24.213877ms)
|
||||
✔ a missing argument is a usage error (23.282202ms)
|
||||
✔ pi: typed tools reach the socket, the gate blocks, agent_end writes the marker (304.751435ms)
|
||||
✔ pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks (311.459536ms)
|
||||
✔ pi: a write through a dangling symlink is blocked, and nothing appears outside (297.277741ms)
|
||||
✔ pi: a read is refused when pi would open another spelling outside (307.711166ms)
|
||||
✔ pi: a relative path climbs from the real path of a workspace behind a symlink (316.537035ms)
|
||||
✔ pi: a relative path climbs from the real path of a dataRoot behind a symlink (289.241357ms)
|
||||
✔ pi: a missing extension refuses before any model call (6.119421ms)
|
||||
✔ pi: an extension without its configuration fails pi's start (240.388238ms)
|
||||
✔ founderCheck: founder variables, then a needed service without a usable token (0.885229ms)
|
||||
✔ turnRequest names the sender, class, reply and decision (0.151317ms)
|
||||
✔ turnRequest says a tester's message is a test and never Jason's instruction (0.168317ms)
|
||||
✔ turnRequest shows the message's own sent time, a day old as well as new (0.112311ms)
|
||||
✔ stateBlock names the launch state with its time and event, and the open tasks with the cap (0.200779ms)
|
||||
✔ a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0 (149.506174ms)
|
||||
✔ launches revoked and then restored: the turn's block reads allowed and gives the restore time (165.502176ms)
|
||||
✔ a task closed on the tracker is missing from the next turn's open list (167.53618ms)
|
||||
✔ a message read a day after it was sent shows the time it was sent (86.091424ms)
|
||||
✔ a decision the human resolves becomes a turn citing the decision and the answer (138.823674ms)
|
||||
✔ a failed state read fails the turn: no adapter runs, the sender hears why, the message is read (61.373189ms)
|
||||
✔ a SIGTERM before the claim stops the runner with exit 0 and no claim (42.595564ms)
|
||||
✔ typed tools carry the runner's capability; launch goes to the host's launch socket (271.992761ms)
|
||||
✔ a RESULT gets no automatic reply; failed turns reply with the reason (1164.476662ms)
|
||||
✔ SIGTERM during a turn kills the turn's process group and still exits 0 (92.1364ms)
|
||||
✔ founder credentials stop before the claim (20) (87.106671ms)
|
||||
✔ a refused claim exits 21; an ended run's capability exits 22 (84.848762ms)
|
||||
✔ the launch ending under a running session exits 22 (96.356717ms)
|
||||
✔ a broker that stays unreachable exits 23 after brokerRetries polls (198.700381ms)
|
||||
✔ a broker that is down at the claim exits 23, not 21 (46.62532ms)
|
||||
✔ no capability, or a malformed one, on stdin exits 2 (151.119305ms)
|
||||
✔ a missing or malformed policy exits 2 before the claim (81.296412ms)
|
||||
✔ the PM gets its task verbs and the reads, and no launch (5.103995ms)
|
||||
✔ the chief of staff gets launch and send_message, and no task verbs (1.403783ms)
|
||||
✔ the assistant gets send_message and the reads, no launch (1.628825ms)
|
||||
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (2.257009ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (1.108602ms)
|
||||
✔ a coder with a tracker gets its own task tools and no task_reassign (0.920281ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (1.638031ms)
|
||||
✔ an action outside the instance's authority has no tool (1.260173ms)
|
||||
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (2.801425ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (6.532995ms)
|
||||
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (1.889571ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (2.027402ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (0.64468ms)
|
||||
ℹ tests 84
|
||||
ℹ suites 0
|
||||
ℹ pass 84
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 19149.464181
|
||||
@@ -0,0 +1,94 @@
|
||||
✔ a raw token file, with or without one trailing newline, reaches curl only through the config stream (114.769037ms)
|
||||
✔ the raw path accepts nothing else, and refuses before curl runs (351.52401ms)
|
||||
✔ the file checks still apply on the raw path: mode, symlink, missing, directory (257.78324ms)
|
||||
✔ the raw path base URL has no override (55.446751ms)
|
||||
✔ the JSON path is unchanged, and JSON never falls through to the raw path (217.308833ms)
|
||||
✔ a file that changes between the two reads refuses before curl runs, with or without a body (683.972091ms)
|
||||
✔ the token reaches no child environment, even with an inherited CFG or SHELLOPTS=allexport (670.240751ms)
|
||||
✔ real helper GET HTTP 200 preserves exit 0 without credentials (11.969409ms)
|
||||
✔ real helper POST HTTP 201 preserves exit 0 without credentials (10.609028ms)
|
||||
✔ real helper GET HTTP 403 preserves exit 1 without credentials (9.247749ms)
|
||||
✔ fixture git subjects only, follow-ups and three session kinds (98.953703ms)
|
||||
✔ text and JSON carry same numbers, open and truncated title (161.665906ms)
|
||||
✔ missing credentials exit 2, no-issues never calls API and shows unknown (128.995968ms)
|
||||
✔ empty range gives no rows and zero totals (92.176014ms)
|
||||
✔ inclusive UTC dates, first-line preamble only, role and seat boundaries (99.254887ms)
|
||||
✔ close-only issue included, even median, missing metadata stays unknown (94.79863ms)
|
||||
✔ unique commits but per-issue links count multiple tags once each (91.836417ms)
|
||||
✔ issue pages of 50, 50 and 7 read 107 issues in 3 pages (254.261729ms)
|
||||
✔ one short page reads 1 page; --no-issues reads none and says so (184.264112ms)
|
||||
✔ a short page 10 is read; a full page 10 refuses at the ceiling (600.332692ms)
|
||||
✔ an issue number on two pages refuses (106.174215ms)
|
||||
✔ a failing page 2 refuses the whole read without its stderr (108.955578ms)
|
||||
✔ page 2 with a malformed record refuses (102.251166ms)
|
||||
✔ page 2 with more than 50 rows refuses (107.904085ms)
|
||||
✔ bad API payload not JSON refuses (84.828358ms)
|
||||
✔ bad API payload {} refuses (84.675221ms)
|
||||
✔ bad API payload [{"number":1}] refuses (93.499868ms)
|
||||
✔ partial or malformed session log refuses with location, not content (93.899532ms)
|
||||
✔ a U+2028 or U+2029 inside a session string is one line, not a malformed record (107.670101ms)
|
||||
✔ no sessions is an empty table; symlink source refuses (153.991108ms)
|
||||
✔ reads only refactor even when another branch is checked out (98.108684ms)
|
||||
✔ invalid dates, reverse dates and duplicate options refuse (59.214391ms)
|
||||
✔ T3 agent assignments do not count as human in Table 2 (92.817192ms)
|
||||
✔ preamble parsing and issue number boundaries (0.419486ms)
|
||||
✔ T3 header: agent, or board from control-board; anything short of the full header is human (0.133433ms)
|
||||
✔ no closed issues with human messages means undefined ratio, not invented zero (0.19503ms)
|
||||
✔ T3: seat, archived, unmapped and Researcher threads count; imported, deleted and other-project threads do not (182.879836ms)
|
||||
✔ T3: the default path is read from HOME and prints no path line; --no-t3 says so (372.054401ms)
|
||||
✔ T3: a HOME with no database exits 1 and names --no-t3 (86.337908ms)
|
||||
✔ T3: a file that is not a database exits 1 and names --no-t3 (83.840835ms)
|
||||
✔ T3: a seat thread renamed to another seat exits 1 naming thread, title and roles (111.899528ms)
|
||||
✔ T3: an unmapped thread addressed as a seat exits 1 (112.810901ms)
|
||||
✔ T3: a header to another thread id is not cross-checked (116.739502ms)
|
||||
✔ T3: no project, or two, for this root exits 1 (283.671598ms)
|
||||
✔ T3: a removed column exits 1 and names it (105.206601ms)
|
||||
✔ T3: a missing table exits 1 and names it (100.977757ms)
|
||||
✔ T3: a counted row with an unknown role exits 1 without its text (111.925313ms)
|
||||
✔ T3: a counted row with role reasoning without the reasoning: id prefix exits 1 without its text (113.93479ms)
|
||||
✔ T3: a counted row with non-text content exits 1 without its text (107.000509ms)
|
||||
✔ T3: a counted row with an unparseable created_at exits 1 without its text (112.091349ms)
|
||||
✔ T3: a reasoning summary is skipped before any check and counted as excluded (297.66867ms)
|
||||
✔ T3: a missing orchestration_events makes the diagnostic unknown and keeps the counts (198.561095ms)
|
||||
✔ T3: a human message with no event counts in humanWithoutEvent (115.735145ms)
|
||||
✔ T3: an unparseable event makes the diagnostic unknown and keeps the counts (205.892647ms)
|
||||
✔ T3: an event with no string messageId makes the diagnostic unknown and keeps the counts (201.754692ms)
|
||||
✔ T3: an error that is not from SQLite is rethrown, not reported as a database failure (58.911181ms)
|
||||
✔ T3: a symlink at ~/.t3 exits 1 (84.401042ms)
|
||||
✔ T3: a symlink at ~/.t3/userdata exits 1 (83.12447ms)
|
||||
✔ T3: a symlink at ~/.t3/userdata/state.sqlite exits 1 (83.452846ms)
|
||||
✔ T3: with --t3-db, a symlinked file or directory exits 1 (168.003603ms)
|
||||
✔ T3 WAL: the newest message only in -wal, writer attached, is counted (127.822832ms)
|
||||
✔ T3 WAL: stopped cleanly, counts are correct and the main file is unchanged (115.601771ms)
|
||||
✔ T3 WAL: -wal without -shm in a writable directory is read (136.409349ms)
|
||||
✔ T3 WAL: -wal without -shm in a read-only directory exits 1 (129.580309ms)
|
||||
✔ T3 WAL: stopped cleanly in a read-only directory exits 1 (113.301388ms)
|
||||
✔ T3: a lock held past the 5 s busy timeout exits 1 and names --no-t3 (5117.897554ms)
|
||||
✔ a done row whose closing issue is open is a violation; a row that is not done is not (1.706932ms)
|
||||
✔ an issue several rows close is expected closed only once all of them are done (0.473947ms)
|
||||
✔ closure needs positive evidence: unknown is undecided, and so is a skipped or short issue check (0.376148ms)
|
||||
✔ each owner of an in-progress or in-review row gets one liveness class (6.838097ms)
|
||||
✔ a required row not done after 14 days is a violation; a legacy row uses genesis as its lower bound (0.308972ms)
|
||||
✔ an ISO requiredSince, as `set required` writes it, ages from its UTC day; one that does not parse is a violation (0.211499ms)
|
||||
✔ the text section always ends in a count and a result, and never prints a full pass (0.280461ms)
|
||||
✔ pidAlive: a running pid is present, an exited one is gone, and EPERM still means present (23.951892ms)
|
||||
✔ issue states: open list first, then the metric page, then at most 10 lookups (263.323798ms)
|
||||
✔ a full open list: lookups settle what it leaves out, and only an unsettled issue keeps it undecided (347.913818ms)
|
||||
✔ the open list refuses on a failed call or a bad record, and never echoes the helper (156.404191ms)
|
||||
✔ a helper call past the deadline is killed with its child, and the call reports it (2008.646993ms)
|
||||
✔ readQueue loads queue.json through the queue validator and refuses anything else (89.557913ms)
|
||||
✔ protected changes list every in-range entry that changes a required or parked row (247.92154ms)
|
||||
✔ the CLI prints the queue section above the weekly table and under a queue key in --json (461.867205ms)
|
||||
✔ a queue with nothing wrong prints 0 violations and a reduced pass, never a full pass (189.503547ms)
|
||||
✔ --no-issues makes no call and leaves the issue checks undecided; --no-queue skips the section (253.845638ms)
|
||||
✔ the CLI refuses a bad queue before any call, and a failed open list with exit 2 (225.538946ms)
|
||||
✔ --unsupported-runtime repeats once per seat and takes a seat name (306.386754ms)
|
||||
✔ an unreadable config makes every owner invalid instead of passing them (125.025032ms)
|
||||
ℹ tests 86
|
||||
ℹ suites 0
|
||||
ℹ pass 86
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 19593.622121
|
||||
@@ -0,0 +1,77 @@
|
||||
✔ pure resolution selects current default or explicit enrolled account (1.915384ms)
|
||||
✔ scope is explicit, bounded and never inferred (1.561375ms)
|
||||
✔ fork pin is preserved against default change, override, missing account and revocation (0.718536ms)
|
||||
✔ unenrolled account/provider, missing harness, model expansion and native model ceiling refuse (0.75861ms)
|
||||
✔ only explicit synthetic credential forms and internal fixture stores admitted (5.592817ms)
|
||||
✔ two concurrent workspaces of the same agent publish distinct complete private generations (58.230889ms)
|
||||
✔ same execution ID is exclusively claimed and cannot overwrite a published generation (32.488919ms)
|
||||
✔ failed generation after-auth preserves prior files, records failure and refuses blind same-ID retry (46.174264ms)
|
||||
✔ failed generation before-publish preserves prior files, records failure and refuses blind same-ID retry (56.31119ms)
|
||||
✔ credential lock contention refuses without duplicate side effects (11.480802ms)
|
||||
✔ symlinked pre-existing final target is refused and never followed (27.620146ms)
|
||||
✔ invalid registry cannot resolve; no fallback to supplied partial entries (0.222626ms)
|
||||
✔ post-publication failure records uncertainty, preserves complete generation and prevents replay (29.209323ms)
|
||||
✔ expired credentials refresh under transaction and subsequent generation reuses rotation (86.687247ms)
|
||||
✔ refresh failure retains prior generation and store state (65.617986ms)
|
||||
✔ refresh timeout retains prior generation and store state (142.606944ms)
|
||||
✔ refresh malformed retains prior generation and store state (56.750994ms)
|
||||
✔ concurrent refresh on same account refuses contention while unrelated account proceeds (221.631676ms)
|
||||
✔ invalid refresh options refuse before burning claim (35.608691ms)
|
||||
✔ fixed fake process rotates both OAuth fields without mutating caller input (26.655244ms)
|
||||
✔ concurrent isolated processes preserve separate provider credentials (25.456972ms)
|
||||
✔ fake failure is refused with fixed diagnostics (21.096348ms)
|
||||
✔ fake malformed is refused with fixed diagnostics (21.640565ms)
|
||||
✔ fake timeout is refused with fixed diagnostics (103.686709ms)
|
||||
✔ fake unchanged is refused with fixed diagnostics (27.929896ms)
|
||||
✔ caller executable/environment injection is rejected before spawning (0.293384ms)
|
||||
✔ valid fixture tree validates and lists without secrets (65.431764ms)
|
||||
✔ unknown-field refuses (0.372447ms)
|
||||
✔ invalid-id refuses uppercase and traversal shapes (0.260255ms)
|
||||
✔ plain-http baseUrl requires allowInsecureTransport (0.290976ms)
|
||||
✔ native provider rejects allowInsecureTransport (0.128234ms)
|
||||
✔ unsupported credential type and kind refuse (0.591791ms)
|
||||
✔ account provider-path mismatch refuses (0.142042ms)
|
||||
✔ profile account refs must be provider/account shaped (0.241463ms)
|
||||
✔ seat selection accepts fork pin field, validates account refs (0.233797ms)
|
||||
✔ harness manifest id must equal executable (gate 1) (0.195862ms)
|
||||
✔ CLI validate: duplicate provider id across files refuses (29.369941ms)
|
||||
✔ CLI validate: missing referenced provider/account refuse (31.271588ms)
|
||||
✔ CLI validate: broken JSON refuses without secret echo (29.715725ms)
|
||||
✔ CLI usage errors exit 2 (49.806288ms)
|
||||
✔ credential.json sibling presence does not break validation and is never read (62.398678ms)
|
||||
✔ D1 missing, empty and structurally empty roots refuse, no list projection (157.531989ms)
|
||||
✔ D1 required directory auth cannot be absent (56.114517ms)
|
||||
✔ D1 required directory auth/providers cannot be absent (51.741272ms)
|
||||
✔ D1 required directory auth/accounts cannot be absent (60.527421ms)
|
||||
✔ D1 required directory auth/settings cannot be absent (57.279266ms)
|
||||
✔ D1 required directory harnesses cannot be absent (66.08356ms)
|
||||
✔ D1 root file and unreadable metadata refuse (105.454238ms)
|
||||
✔ D2 no symlink traversal at auth/providers/openai-codex.json (52.340626ms)
|
||||
✔ D2 no symlink traversal at auth/accounts/openai-codex/homelab-openai (60.579558ms)
|
||||
✔ D2 no symlink traversal at auth/providers (53.196605ms)
|
||||
✔ D2 no symlink traversal at auth (53.155092ms)
|
||||
✔ D2 root and ancestor symlinks and lexical traversal refuse (167.154527ms)
|
||||
✔ private filesystem modes enforced for root (51.921414ms)
|
||||
✔ private filesystem modes enforced for auth (48.571446ms)
|
||||
✔ private filesystem modes enforced for auth/providers/openai-codex.json (57.341317ms)
|
||||
✔ private filesystem modes enforced for auth/accounts/openai-codex/homelab-openai/account.json (56.140042ms)
|
||||
✔ D3 numeric version 1 only across all record kinds (1.223905ms)
|
||||
✔ D4 nested unknown keys and missing per-kind required fields refuse (58.34476ms)
|
||||
✔ D5 unenrolled default refuses even when account exists (62.015275ms)
|
||||
✔ D6 provider/account credential type must match (64.626112ms)
|
||||
✔ D7 every harness endpoint enforces HTTP opt-in and shape (0.444092ms)
|
||||
✔ D8 URLs reject embedded credentials and unsupported protocols without echo (162.610135ms)
|
||||
✔ D9 malformed JSON diagnostics contain no content excerpt (62.077894ms)
|
||||
✔ D10 missing metadata is missing-path, not invalid-json (64.522105ms)
|
||||
✔ D10 library returns no partial entries on any invalid record (70.770488ms)
|
||||
✔ null/scalar/array metadata refuses without stack or echo (217.349679ms)
|
||||
✔ credential sibling is never opened, even when an unreadable symlink (30.886234ms)
|
||||
✔ oversized metadata refuses before parsing (54.278949ms)
|
||||
ℹ tests 69
|
||||
ℹ suites 0
|
||||
ℹ pass 69
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 3547.463304
|
||||
@@ -0,0 +1,51 @@
|
||||
✔ isRunId accepts the run id shape and nothing else (0.796425ms)
|
||||
✔ a missing data root or runs directory lists nothing (1.214759ms)
|
||||
✔ runs as a regular file lists nothing, as before (0.499312ms)
|
||||
✔ listRunIds keeps r- names only, sorted oldest first (0.643352ms)
|
||||
✔ listRunRecords returns each result, or null for an incomplete or unreadable one (1.618353ms)
|
||||
✔ readRunRecord returns documents and artifacts in directory order (0.839686ms)
|
||||
✔ readRunRecord is null for a missing run, a dangling link or a file (0.532378ms)
|
||||
✔ readRunRecord and readRunDocument refuse an invalid run id before touching the disk (0.546198ms)
|
||||
✔ readRunDocument reads only the three run documents (0.418018ms)
|
||||
✔ a link inside the data root is followed (0.785133ms)
|
||||
✔ a data root that is itself a link is trusted as configured (0.479919ms)
|
||||
✔ a run directory linked out of the data root is never read (0.48238ms)
|
||||
✔ a document linked out of the data root reads as null (0.807519ms)
|
||||
✔ a runs directory linked out of the data root refuses (0.484797ms)
|
||||
✔ a relative link that climbs out of the data root refuses (0.348218ms)
|
||||
✔ a sibling whose name starts with the data root's name is outside it (0.40394ms)
|
||||
✔ a link loop refuses instead of reading as missing (0.507846ms)
|
||||
✔ an unreadable runs directory refuses instead of listing nothing (0.339779ms)
|
||||
✔ an unreadable run directory refuses instead of reading as missing (0.421441ms)
|
||||
✔ a link to the data root's parent is outside it (0.348348ms)
|
||||
✔ listRunIds sorts whatever order the directory returns (0.644355ms)
|
||||
✔ listRunRecords lists an r- name that isn't a valid run id, as before (0.381274ms)
|
||||
✔ the readers write nothing (1.58464ms)
|
||||
✔ no pointer is null (1.446738ms)
|
||||
✔ the pointer release.sh writes reads back (0.933055ms)
|
||||
✔ a pointer that isn't the version 1 shape refuses with exit 2 (1.869464ms)
|
||||
✔ a pointer that is a directory refuses with exit 4 (0.46746ms)
|
||||
✔ a state file linked out of the data root refuses (1.196546ms)
|
||||
✔ a state directory linked out of the data root refuses (0.435641ms)
|
||||
✔ a state directory linked out to nothing reads as no release and an empty log (0.398125ms)
|
||||
✔ a missing log is empty (0.28292ms)
|
||||
✔ the log reads oldest first and counts malformed lines (0.784545ms)
|
||||
✔ last must be a positive integer (3.525327ms)
|
||||
✔ the state readers write nothing (0.65018ms)
|
||||
✔ list prints each run in the established format (63.847603ms)
|
||||
✔ list prints a damaged result.json as unknown and keeps listing the runs after it (61.111368ms)
|
||||
✔ list prints each result field that isn't a string as unknown or - (61.675224ms)
|
||||
✔ show prints the run in the established format (62.92771ms)
|
||||
✔ show of a missing run and an invalid id exit 4 as before (93.055191ms)
|
||||
✔ list and show refuse a runs directory linked out of the data root (130.723304ms)
|
||||
✔ show refuses a run linked out of the data root; list reports it unknown (141.473342ms)
|
||||
✔ list shows an r- name that isn't a valid run id, as before (63.965869ms)
|
||||
✔ show refuses an invalid id before reading the config (39.342102ms)
|
||||
ℹ tests 43
|
||||
ℹ suites 0
|
||||
ℹ pass 43
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 871.795556
|
||||
@@ -0,0 +1,145 @@
|
||||
✔ a first launch clones the root at its branch, with the root's path as origin (30.465864ms)
|
||||
✔ the clone is not at its place until git clone has finished (19.535626ms)
|
||||
✔ a later launch fast-forwards a clean clone after a commit to the root, then finds it current (57.664871ms)
|
||||
✔ a clone ahead of the root keeps its commits and counts as current (35.802407ms)
|
||||
▶ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves
|
||||
✔ a modified file (41.6465ms)
|
||||
✔ an untracked file (41.998747ms)
|
||||
✔ a staged file (44.037871ms)
|
||||
✔ another branch (42.485078ms)
|
||||
✔ a detached HEAD (41.605191ms)
|
||||
✔ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves (212.891184ms)
|
||||
✔ a diverged clone gets the fetch into refs/remotes and is kept, not-fast-forward (41.937074ms)
|
||||
▶ a clone kept before the branch check, or for a failed status, gets no fetch
|
||||
✔ not-a-clone (22.571431ms)
|
||||
✔ hooks-present (23.358059ms)
|
||||
✔ submodule (29.755738ms)
|
||||
✔ config-changed (26.782133ms)
|
||||
✔ root-unreadable (27.082002ms)
|
||||
✔ root-detached (33.025258ms)
|
||||
✔ status-failed, on the root's branch and clean (35.536529ms)
|
||||
✔ status-failed, dirty (36.106185ms)
|
||||
✔ a clone kept before the branch check, or for a failed status, gets no fetch (235.368508ms)
|
||||
✔ a dirty clone whose fetch fails is kept, fetch-failed, exactly as it was (38.912889ms)
|
||||
✔ every git call the host makes, for a new clone and an existing one, carries maintenance.auto=false and gc.auto=0 (44.13586ms)
|
||||
✔ a clone with loose objects enough for gc --auto gets no maintenance or gc from the fetch and the merge (72.299287ms)
|
||||
▶ a clone with user.name or user.email in its config is kept, and git runs nothing in it
|
||||
✔ user.name (24.960511ms)
|
||||
✔ user.email (24.768972ms)
|
||||
✔ a clone with user.name or user.email in its config is kept, and git runs nothing in it (50.143557ms)
|
||||
✔ a commit git can't read after the fast-forward is null (45.333531ms)
|
||||
✔ a new clone whose commit can't be read refuses the launch and leaves nothing behind (18.69944ms)
|
||||
▶ a clone the session rigged is kept, and git runs nothing and writes nothing outside it
|
||||
✔ core.fsmonitor (33.724778ms)
|
||||
✔ core.hooksPath (32.562327ms)
|
||||
✔ a hook file (30.586659ms)
|
||||
✔ include.path (32.51932ms)
|
||||
✔ includeIf (33.113745ms)
|
||||
✔ a filter driver (33.947149ms)
|
||||
✔ origin moved (33.516198ms)
|
||||
✔ a second origin url (33.068947ms)
|
||||
✔ the origin url twice, both the root (34.454669ms)
|
||||
✔ an ext:: origin (32.76077ms)
|
||||
✔ a branch tracking another remote (33.47843ms)
|
||||
✔ a branch merging a tag (33.594982ms)
|
||||
✔ a fetch line onto local branches (33.525554ms)
|
||||
✔ no origin (33.124921ms)
|
||||
✔ a config file over the size cap (31.027568ms)
|
||||
✔ config a symlink to /dev/zero (30.915436ms)
|
||||
✔ the clone a symlink to the bait (30.722403ms)
|
||||
✔ the clone a file (30.966617ms)
|
||||
✔ the clone a plain directory (30.427326ms)
|
||||
✔ .git a gitdir: file (30.207347ms)
|
||||
✔ .git a symlink (31.364567ms)
|
||||
✔ .git/logs a symlink (31.813241ms)
|
||||
✔ .git/refs/heads a symlink (32.261827ms)
|
||||
✔ .git/objects a symlink (31.698025ms)
|
||||
✔ a reflog hard-linked to a file outside (30.930961ms)
|
||||
✔ HEAD a fifo (32.040489ms)
|
||||
✔ a commondir file (31.24185ms)
|
||||
✔ an alternates file (32.030286ms)
|
||||
✔ a gitlink staged, no .gitmodules (43.880635ms)
|
||||
✔ a gitlink and .gitmodules staged (44.845395ms)
|
||||
✔ a gitlink to a repository with its own gitlink (52.469603ms)
|
||||
✔ a gitlink and .gitmodules committed (47.886282ms)
|
||||
✔ a gitlink and submodule.active in config (45.225705ms)
|
||||
✔ a .git/modules with no gitlink (33.5377ms)
|
||||
✔ a clone the session rigged is kept, and git runs nothing and writes nothing outside it (1173.801024ms)
|
||||
▶ a root that can't be cloned refuses with the project id and leaves nothing behind
|
||||
✔ missing (10.830802ms)
|
||||
✔ not a repository (10.071669ms)
|
||||
✔ a plain directory inside another repository (14.581948ms)
|
||||
✔ unreadable (9.894331ms)
|
||||
✔ on no branch (12.188231ms)
|
||||
✔ missing an object (15.311099ms)
|
||||
✔ a root that can't be cloned refuses with the project id and leaves nothing behind (73.746687ms)
|
||||
✔ a clone whose root is on no branch, or gone, is kept and named (28.466899ms)
|
||||
✔ no credential or forge remote of the root reaches a clone (47.327257ms)
|
||||
✔ every project in the business file gets its own clone at its own branch (34.276223ms)
|
||||
✔ a clone past its time gets SIGTERM and refuses the launch, with nothing left in the workspace (513.778389ms)
|
||||
✔ a clone that ignores SIGTERM gets SIGKILL once the grace period is over (1033.83343ms)
|
||||
✔ a timeout signals git's process group, so a process git started dies with it (514.342437ms)
|
||||
✔ once a signalled git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (516.221119ms)
|
||||
✔ RUNNER_FILES is exactly what the runner and the harness sources it starts import (1.438981ms)
|
||||
✔ sandboxProblem names a missing bwrap and a bwrap that fails (9.251858ms)
|
||||
✔ every bind says why; the bundle and session file stay read-only over the run directory (1.172128ms)
|
||||
✔ the host's git socket is bound only when given, read-only and before the writable binds (0.598047ms)
|
||||
✔ the git identity is the instance's, at <instance>@<business>.mosaic.invalid, and sandboxArgv refuses without it (1.026396ms)
|
||||
✔ a confined session's shell reaches its own workspace and run directory and nothing of the founder's or another session's (1852.965965ms)
|
||||
✔ a bind that exposes a stand-in, or a missing workspace bind, fails the matching check (2756.754595ms)
|
||||
✔ a confined session that runs tester-cli.mjs is refused as tester, and the same shim outside the sandbox binds (242.14813ms)
|
||||
✔ resolveSeat: by name under --repo resolves the repo layout (1.581962ms)
|
||||
✔ resolveSeat: by path resolves the fleet layout (0.368645ms)
|
||||
✔ resolveSeat: refusals for missing dir, missing launch.sh, non-executable launch.sh, invalid name, and unknown layout (0.738852ms)
|
||||
✔ tmuxContext: outside tmux, default socket, custom socket, and exec failure (0.669534ms)
|
||||
✔ makeRegistration produces a record that validates; each shape violation throws SeatError (0.891815ms)
|
||||
✔ writeRegistration/readRegistration: round trip, permissions, absence, and malformed records (1.398879ms)
|
||||
✔ updateTask: changes task, taskSetBy and updatedAt only, and refuses appropriately (1.214569ms)
|
||||
✔ CLI launch: registers, execs the fake launch script, and passes args through (32.902514ms)
|
||||
✔ CLI launch: --harness lands in the record (28.029253ms)
|
||||
✔ CLI launch: the launch script's own exit code passes through (28.472404ms)
|
||||
✔ CLI launch: relaunching a seat rewrites the one registration record (53.840628ms)
|
||||
✔ CLI launch: omitting --task records an empty string, not null (25.782879ms)
|
||||
✔ CLI seat task: updates only the task after a launch, and refuses on an unlaunched seat (80.025977ms)
|
||||
✔ CLI refusals: no args, unknown flag, missing config, already-registered env, and exec failure (132.597395ms)
|
||||
✔ samePath: equal paths, symlinked dirs, distinct dirs, and non-strings (0.377759ms)
|
||||
✔ resolveSetBy: explicit --by wins over the environment; absent or empty environment gives unknown; invalid explicit or environment values refuse with exit 4 (0.561756ms)
|
||||
✔ validateRegistration/readRegistration: taskSetBy is optional; a record without it (written before #1511) still loads unchanged; an invalid one is refused; the version does not change (0.682211ms)
|
||||
✔ updateTask: records setBy, preserves startedAt and every unrelated field, upgrades an old record in place only when the task is set, and replaces a previous attribution (1.12297ms)
|
||||
✔ CLI seat task: --by beats MOSAIC_AGENT_NAME, the environment beats nothing, empty environment is unknown, invalid --by or environment refuses with exit 4 and leaves the record byte for byte (257.783649ms)
|
||||
✔ REQ-LIMIT-1: family substring matching is no longer exported (0.667715ms)
|
||||
✔ sessionEnv passes only the allowlist, the repo's bin on PATH, and the run id (0.634177ms)
|
||||
✔ sessionExit gives a runner's signal death back as the signal; a session credential is one whole set of nonempty variables (0.23792ms)
|
||||
✔ newRun: short ids, 0700 directories, and a refusal when the socket path won't fit (1.360737ms)
|
||||
✔ session file and launch log: 0600, the session file written once (0.932952ms)
|
||||
✔ endReason maps the runner's exit codes; a signal is killed (0.111239ms)
|
||||
✔ Registry mirrors to sessions.json; readSessions marks live entries; bad files refuse (1.363534ms)
|
||||
✔ stopSession refuses an unknown run, reports a stale one, and won't signal a pid that isn't a runner (0.972918ms)
|
||||
✔ a session runs in its sandbox as pid 1 of its namespace, claims, answers, and stops on mosaic stop (189.303516ms)
|
||||
✔ workRef and validBranch take only what a ref name can hold (1.054103ms)
|
||||
✔ a push lands as the task's work ref, a fast-forward lands after it, and main is the root's (96.405013ms)
|
||||
✔ a rewritten branch refuses non-fast-forward and the work ref stays (81.742312ms)
|
||||
✔ a branch with no history in common with main refuses unrelated-history (43.806933ms)
|
||||
✔ a bundle that needs commits the working repository lacks refuses missing-prerequisite (38.14496ms)
|
||||
✔ main is fetched from the root again before each push, so a clone of a newer root pushes (90.241834ms)
|
||||
✔ a root moved back after the clone leaves the push's base unknown: missing-prerequisite (59.842111ms)
|
||||
✔ a commit with a broken object refuses invalid-bundle, and only because fsck is on (60.263362ms)
|
||||
✔ only a v2 bundle with the named branch is read (57.904832ms)
|
||||
✔ a branch named main, or named for another task, moves only this task's work ref (77.392178ms)
|
||||
✔ a record that throws moves the work ref back, or removes a new one (99.845087ms)
|
||||
✔ a work ref that can't go back refuses rollback-failed, naming the ref and the commit (362.527409ms)
|
||||
✔ a root that can't be read refuses root-unreadable (29.366988ms)
|
||||
✔ a git past its time gets SIGTERM, leaves no ref lock, and the next push lands (2123.542673ms)
|
||||
✔ a git that ignores SIGTERM gets SIGKILL once the grace period is over (1038.075379ms)
|
||||
✔ a working repository path that isn't a directory refuses (29.411001ms)
|
||||
✔ review bundles a pushed commit as refs/mosaic/review, leaving out what the reviewer has (135.964681ms)
|
||||
✔ review of a project with no working repository refuses unknown-commit (13.587398ms)
|
||||
✔ the runner's git tools hold the host's limits and branch rule (1.391235ms)
|
||||
ℹ tests 132
|
||||
ℹ suites 0
|
||||
ℹ pass 132
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 15229.359008
|
||||
@@ -0,0 +1,100 @@
|
||||
✔ the boot config is checked before anything starts (11.481505ms)
|
||||
✔ a business with no tracker entry refuses task verbs (10.793975ms)
|
||||
✔ credential.expiring and .expired are recorded once per instance (21.439952ms)
|
||||
✔ a token file that changes on disk records credential.changed (8.893736ms)
|
||||
✔ autostart polls, reconciles and retries a startup the tracker was down for (31.091469ms)
|
||||
✔ a refusal a restart must clear is not retried by the poll (6.42898ms)
|
||||
✔ a poll that fires while two are queued is dropped (8.121134ms)
|
||||
✔ close waits for a running verb and refuses one that has not started (36.110973ms)
|
||||
✔ the bundled Vikunja is the pinned upstream image the runbook names (0.666969ms)
|
||||
✔ every published port is on 127.0.0.1, and no secret is in the file (0.265322ms)
|
||||
✔ the committed table loads frozen; its verbs are the broker task verbs (1.289714ms)
|
||||
✔ a write names a verb the table has as its own key, not one it inherits (0.443114ms)
|
||||
✔ the schema refuses any other shape (2.727779ms)
|
||||
✔ the Field table in the slice 1 plan names the verbs each field is written by (0.553977ms)
|
||||
✔ each verb refuses, asks for a decision and writes as the table and the role files say (133.707275ms)
|
||||
✔ the list holds the PRD's requirement ids, in its order, at its version (1.261469ms)
|
||||
✔ the committed list loads frozen (0.562415ms)
|
||||
✔ the schema refuses any other shape (2.230843ms)
|
||||
✔ the fake answers each route with the statuses and shapes Vikunja v2.7.0 sent (85.235042ms)
|
||||
✔ the project list holds recorded project objects in the recorded list envelope (6.830209ms)
|
||||
✔ the recorded task bodies pass the checks S3 applies to every read (0.457768ms)
|
||||
✔ the client works against the fake over real HTTP with the platform fetch (92.441454ms)
|
||||
✔ a correct install starts, and the first reconcile records tasks that already exist (22.361985ms)
|
||||
✔ verbs refuse while a business is starting and after startup refused it (11.375274ms)
|
||||
✔ startup refuses a token that can do more than its role needs (28.424694ms)
|
||||
✔ startup refuses an unsupported version and flags an untested one (21.639968ms)
|
||||
✔ startup refuses a board that the runbook did not install (25.074024ms)
|
||||
✔ startup refuses a project the sync bot cannot read (6.124627ms)
|
||||
✔ startup refuses a configured label the pm bot cannot see (7.466957ms)
|
||||
✔ startup refuses an expired credential and a missing sync credential (11.744713ms)
|
||||
✔ an unreachable tracker refuses with tracker-unavailable (6.027577ms)
|
||||
✔ an edit in the UI is recorded once, with the fields that changed (74.237624ms)
|
||||
✔ a move between open buckets is seen on the board, though updated does not change (36.348269ms)
|
||||
✔ a person's comment is counted and a bot's is not (61.449556ms)
|
||||
✔ the hourly reconcile catches a comment through comment_count (74.35114ms)
|
||||
✔ a task closed in the UI leaves the open view with its done bucket (109.474522ms)
|
||||
✔ a task that leaves the board is recorded as deleted, moved or out of reach (61.572625ms)
|
||||
✔ a poll that read before a verb wrote does not overwrite the verb (34.251961ms)
|
||||
✔ a tracker fault during a tick is reported and the next tick catches up (33.932921ms)
|
||||
✔ a malformed answer refuses the tick with tracker-shape (11.61061ms)
|
||||
✔ no token value reaches the database, the log or a refusal (43.610774ms)
|
||||
✔ the first look at a task counts only comments inside the window (33.49487ms)
|
||||
✔ with descendants off the adapter reads no project list and no child, as in v0 (41.04664ms)
|
||||
✔ a three-level tree is read per project, and a project outside it is not (17.122806ms)
|
||||
✔ a watch-only child keeps the business ready, and a failed child read refuses as transient (16.724125ms)
|
||||
✔ a root without the installed buckets refuses with descendants on (5.766292ms)
|
||||
✔ the project list refuses without read_all, and skips archived projects and saved filters (14.015614ms)
|
||||
✔ descendants must be true or false (5.604653ms)
|
||||
✔ a move inside the tree is a moved tombstone plus a snapshot under the new ref (56.715201ms)
|
||||
✔ a child made after startup joins the tree at the next reconcile (54.034076ms)
|
||||
✔ a child that leaves the tree has its tasks recorded missing, and the ledger keeps their history (55.98471ms)
|
||||
✔ a child deleted or hidden between reconciles drops out at the next tick, and the root still refuses (78.774326ms)
|
||||
✔ a reconcile that fails keeps the previous tree (30.859445ms)
|
||||
✔ a closed task the cursor missed takes its own project's done bucket (32.151677ms)
|
||||
✔ closed tasks read at startup take their own project's done bucket (8.582657ms)
|
||||
✔ a closed task the cursor returns takes its own project's done bucket (34.030768ms)
|
||||
✔ a task moved out of a child that leaves the tree at the same time is moved, not no-access (31.181803ms)
|
||||
✔ a task in a bucket outside the five keeps its raw bucket id (28.82932ms)
|
||||
✔ bucket 0 on a watch-only task never becomes a bucket or a state (76.875935ms)
|
||||
✔ a child whose kanban view is deleted still refuses the tick, and the reconcile reads it watch-only (55.942963ms)
|
||||
✔ a child dropped at a tick comes back at the next reconcile once the bot reads it again (33.745047ms)
|
||||
✔ task.create needs a recorded human request and a requirement id (29.015049ms)
|
||||
✔ task.create takes only an approved requirement id (16.290855ms)
|
||||
✔ task.create cites the request a received message carries, not the message's id (12.814124ms)
|
||||
✔ only labels named in the business file can be written (18.524806ms)
|
||||
✔ task.schedule sets and clears a due date and relations (23.352519ms)
|
||||
✔ assign and reassign move the role bots and record task.assigned (47.661925ms)
|
||||
✔ task.update.assigned is for the assignee and records task.state (43.390106ms)
|
||||
✔ a wrong expected digest records task.conflict and writes nothing (15.18951ms)
|
||||
✔ a cross-role verb needs a resolved decision, used once (19.801082ms)
|
||||
✔ task.close needs a verdict; after it every verb refuses with task-done (19.21022ms)
|
||||
✔ a task with pushed work closes only citing an approve verdict for its latest push, and a refusal writes nothing (24.760862ms)
|
||||
✔ a lost answer is settled by a re-read and never retried (21.621996ms)
|
||||
✔ a create whose answer is lost is reported uncertain, and the poll finds the task (34.323687ms)
|
||||
✔ a task the sync bot cannot read refuses and records nothing (14.386355ms)
|
||||
✔ verbs and polls for one business run one at a time (82.920088ms)
|
||||
✔ a due date with milliseconds is written to the second (63.188833ms)
|
||||
✔ every write landed and the final read failed: the verb succeeds and records what it wrote (36.436532ms)
|
||||
✔ some writes landed and the final read failed: write-uncertain, and nothing is recorded (13.481544ms)
|
||||
✔ a create whose final read fails succeeds and records task.created (31.073985ms)
|
||||
✔ an edit between the last write and the final read shows as external on the next poll (36.357666ms)
|
||||
✔ task.created is recorded when a later label write fails (11.635223ms)
|
||||
✔ every verb acts in an installed child, on the child's own board (41.400488ms)
|
||||
✔ task.create refuses a project outside the tree, a watch-only one and one that is not an id (22.011931ms)
|
||||
✔ with descendants off, task.create takes only the root project (11.493659ms)
|
||||
✔ a verb on a watch-only task, or a relation to one, refuses with project-not-installed (15.768123ms)
|
||||
✔ a related task is read before authority: in another project than its ref names, task-moved; missing, task-not-found (21.926924ms)
|
||||
✔ a task moved to another project of the tree refuses its old ref with task-moved and takes its new one (14.629555ms)
|
||||
✔ a verb and a create in the child record the final read of the child's board (12.976167ms)
|
||||
✔ a create in the child whose final read fails records the child's todo bucket (33.022679ms)
|
||||
✔ a lost answer in the child is settled by a re-read of the child's board (20.352095ms)
|
||||
✔ every related task is read before authority, not only the first (14.255766ms)
|
||||
ℹ tests 92
|
||||
ℹ suites 0
|
||||
ℹ pass 92
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 3213.070727
|
||||
@@ -0,0 +1,122 @@
|
||||
✔ the Board: held roles with no machine sessions, a claim with no address, the toggle kept across a reload, and Message addressed to the role (2784.258845ms)
|
||||
✔ a redirect answer on a Board read, a bus read, a conversation read, a board POST, a module read and a send signs the page out: one line, nothing stale, no further reads (4805.072053ms)
|
||||
✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (1035.656677ms)
|
||||
Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
|
||||
✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (1112.627916ms)
|
||||
✔ the README says a refused field table names the file or the key at fault, never a path (0.794303ms)
|
||||
✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (2723.297075ms)
|
||||
✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (55.070939ms)
|
||||
✔ decisions route serves the roles and recent lists from the reader view (27.21381ms)
|
||||
✔ credentials route serves the broker credential status from the reader view (7.888685ms)
|
||||
✔ replies route serves the replies to one message from the reader view (23.613285ms)
|
||||
✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (49.259538ms)
|
||||
✔ bus refusals map to statuses and never carry a path or a stack (24.16068ms)
|
||||
✔ humanCall speaks the human transport protocol without blocking the server (1644.338783ms)
|
||||
✔ busReader takes --business, else the live bus host, else refuses (143.103196ms)
|
||||
✔ humanCall kills a transport that runs past its timeout (528.057898ms)
|
||||
✔ serve refuses a --business value that is not a business id (204.325523ms)
|
||||
✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (888.415089ms)
|
||||
✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (1263.270722ms)
|
||||
✔ conversation view: a newer session with no readable history keeps the marker (822.27817ms)
|
||||
✔ conversation view: seats without history say so and offer no reply (513.768645ms)
|
||||
✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (609.73057ms)
|
||||
✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (51633.633571ms)
|
||||
✔ messages HTTP read pages and preserves metadata; bad arguments refuse before a read; other reads unchanged (70.249131ms)
|
||||
✔ Console Messages lists late unsolicited messages on polling with sender class time read state and trail; nav count includes beyond the page; reads never deliver (741.585895ms)
|
||||
✔ Messages nav count polls on Tasks and Board and clears on a Board refusal; messages 403 refuses local pages (1553.335889ms)
|
||||
✔ copy writes the Console paths at the full id, read-only, and leaves an existing copy alone (550.561133ms)
|
||||
✔ copy refuses a commit off refactor, an unknown one, a worktree and a bad copies directory (492.825015ms)
|
||||
✔ copy writes nothing when an archived path is missing at the commit (169.701623ms)
|
||||
✔ a copy that loses the rename race leaves no read-only temp directory behind (320.406279ms)
|
||||
✔ a copy whose rename fails with no target refuses, writes no copy and leaves no temp directory (320.383985ms)
|
||||
✔ a copy that meets a target holding files says exists: and moves nothing into it (320.294905ms)
|
||||
✔ a copy that meets an empty target directory replaces it by rename, not by moving into it (317.542738ms)
|
||||
✔ serve runs from a copy: /healthz 200, the config check, roles and RELEASE from the copy, the queue from --checkout (606.924858ms)
|
||||
✔ serve refuses a --checkout that is not an absolute directory path (207.641202ms)
|
||||
✔ consoleReads runs the queue read under queueRoot and reads RELEASE under root (48.313744ms)
|
||||
✔ preview options are all three or none, and each is checked (5.552974ms)
|
||||
✔ the CLI refuses a partial or invalid preview flag set at start (495.293057ms)
|
||||
✔ the CLI with all three flags serves the preview mode (104.019233ms)
|
||||
✔ a request for the public name needs the header equal to the user id, else 401 and nothing read (14.108996ms)
|
||||
✔ the header name matches without regard to case, and the value compare is exact (3.002494ms)
|
||||
✔ the public name with the header reads the bus views, and the Host and Origin are checked first (21.354681ms)
|
||||
✔ in preview mode every write answers 403 read-only, from the public name and loopback, and reaches nothing (8.361416ms)
|
||||
✔ loopback requests are unchanged in preview mode, and the bus views work with the board down (3.379374ms)
|
||||
✔ a proxy that rewrites Host to the loopback port gets 403 on its first request, whatever the user (12.827287ms)
|
||||
✔ a repeated Host is 400 before any other check, in preview mode and without it (6.165584ms)
|
||||
✔ without the preview flags the public name is refused and writes still reach the board (3.822911ms)
|
||||
✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.040429ms)
|
||||
✔ credential state from the date alone, as the bus states it (0.118342ms)
|
||||
✔ queue: rows, one row, ids and methods, notes; no path or id from a row (301.443861ms)
|
||||
✔ queue: a refused read fails closed with the store's text, redacted (157.004771ms)
|
||||
✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (689.260775ms)
|
||||
✔ business: names, vars on the allowlist, authority, credential metadata only (7.439042ms)
|
||||
✔ business: missing or invalid file refuses with the module's text, redacted (5.843761ms)
|
||||
✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.24913ms)
|
||||
✔ settings: release, board, loopback address, notifier binding name only (89.56549ms)
|
||||
✔ task fields: the committed table with no reads configured, GET only; a bad table refuses with no path (15.83265ms)
|
||||
✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (559.145711ms)
|
||||
✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (20592.546971ms)
|
||||
✔ the send box: held roles, the draft and caret across a refresh, each receipt, one POST per Send, and the trail link; the board Reply on a 4xx and a 5xx (2179.592367ms)
|
||||
✔ a sent receipt lists its replies as the page refreshes, oldest first and capped, and marks none delivered or read (10914.498401ms)
|
||||
✔ startServer takes send only as a function and only with the preview mode (5.309287ms)
|
||||
✔ the CLI refuses --send without the preview flags, and without a configured bus (336.022051ms)
|
||||
✔ the CLI with --send and a configured bus sends through the human transport and logs one line (107.135007ms)
|
||||
✔ without --send the route is read-only like every other write, and config says no send (6.528442ms)
|
||||
✔ with --send every other write is still 403 read-only, and nothing reaches the board or bus (5.051911ms)
|
||||
✔ config says send only on the public name with --send on (1.680833ms)
|
||||
✔ a send without the signed-in user is 401 and is neither sent nor logged, loopback included (3.278823ms)
|
||||
✔ each request check refuses before anything is sent, and logs the refusal without the body (10.8905ms)
|
||||
✔ a send passes exactly to, body and in_reply_to, answers the id, and logs it (2.233324ms)
|
||||
✔ a crafted role name cannot forge a log line (1.626555ms)
|
||||
✔ a bus refusal is not sent, with its status; an outcome the bus could not confirm is unknown and never retried (5.386978ms)
|
||||
✔ through the human transport the request is exactly the business, message.send and the keys (70.085491ms)
|
||||
✔ against a real broker: the message is written once as a human send, and its refusals map (18.605755ms)
|
||||
✔ loopback host and board origin fail closed (5.047057ms)
|
||||
✔ real board fixture passes through WebUI; assets and isolated seen/reply work (60.847828ms)
|
||||
✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (39.25573ms)
|
||||
✔ unreachable board reports URL; CLI rejects unsupported options (302.046814ms)
|
||||
✔ render prints the unit without the preview flags (8.415793ms)
|
||||
✔ render carries every serve flag, the preview set included (6.034116ms)
|
||||
✔ a partial preview set is refused (13.063837ms)
|
||||
✔ a value the unit cannot carry is refused, for every flag (211.475167ms)
|
||||
✔ the rendered unit names none of the human proof agent markers and sets no agent variable (15.467489ms)
|
||||
✔ install into --dir with --no-reload writes the file whole, then reports unchanged (46.024444ms)
|
||||
✔ install without --no-reload runs daemon-reload and nothing that starts the unit (19.126517ms)
|
||||
✔ uninstall refuses while the unit is running, with or without --no-reload, and removes it once it is not (117.495092ms)
|
||||
✔ status prints the unit state and GET /healthz on the installed port (179.39781ms)
|
||||
✔ usage: an unknown verb or flag, and start or enable, exit 4 (64.025138ms)
|
||||
✔ without --send, render is the template with its placeholders filled, byte for byte (26.434362ms)
|
||||
✔ render --send with the preview set ends ExecStart with --send and changes nothing else (47.090925ms)
|
||||
✔ --send without the whole preview set is refused and writes nothing (124.775473ms)
|
||||
✔ install --send into --dir with --no-reload writes the sending unit, and status says whether it sends (216.946898ms)
|
||||
✔ uninstall and status take no --send (33.905451ms)
|
||||
✔ install refuses while the unit is running, in any state but inactive or failed, and changes nothing (223.900029ms)
|
||||
✔ when the state read fails, install and uninstall refuse with one line and change nothing (60.367055ms)
|
||||
✔ install needs --copy naming a copy that exists, and refuses outside the canonical checkout without --allow-worktree (58.963684ms)
|
||||
✔ install refuses unless the bus unit runs from the same copy, naming both paths, and changes nothing (206.504667ms)
|
||||
✔ render --copy runs the copy and reads the queue in the checkout; without --copy the unit is unchanged (16.984667ms)
|
||||
✔ the uid header takes only an Authentik uid; the username header still takes a username (298.425351ms)
|
||||
✔ a preview value cannot start with - or . (34.662031ms)
|
||||
✔ status names the copy and whether refactor has moved past it, and says when the unit runs from no copy (422.219556ms)
|
||||
✔ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (967.984467ms)
|
||||
2026-10-15T01:28:50.965Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (13.383895ms)
|
||||
✔ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (5.44995ms)
|
||||
✔ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (4.188066ms)
|
||||
✔ tokens.css and icons.svg are byte copies of docs/design (0.885278ms)
|
||||
✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.751882ms)
|
||||
✔ shipped strings are unchanged, and the web keeps its write boundary (1.902696ms)
|
||||
✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5339.510412ms)
|
||||
✔ five states on Board, Inbox, Tasks, Agents and Trail (2218.320833ms)
|
||||
✔ Queue, Business and Settings in their five states, with no move button (2878.184565ms)
|
||||
✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (935.038937ms)
|
||||
✔ the server log names no config path when the system config refuses (211.839641ms)
|
||||
ℹ tests 112
|
||||
ℹ suites 0
|
||||
ℹ pass 112
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 130800.342877
|
||||
@@ -0,0 +1,350 @@
|
||||
[
|
||||
{
|
||||
"suite": "pkg-business",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/business/tests/assistant.test.mjs",
|
||||
"packages/business/tests/business.test.mjs",
|
||||
"packages/business/tests/chief-of-staff.test.mjs",
|
||||
"packages/business/tests/cli.test.mjs",
|
||||
"packages/business/tests/credentials.test.mjs",
|
||||
"packages/business/tests/launch-settings.test.mjs",
|
||||
"packages/business/tests/project.test.mjs",
|
||||
"packages/business/tests/resolve.test.mjs",
|
||||
"packages/business/tests/role.test.mjs",
|
||||
"packages/business/tests/vars.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-bus",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/bus/tests/agents.test.mjs",
|
||||
"packages/bus/tests/broker.test.mjs",
|
||||
"packages/bus/tests/business.test.mjs",
|
||||
"packages/bus/tests/credential-status.test.mjs",
|
||||
"packages/bus/tests/credentials.test.mjs",
|
||||
"packages/bus/tests/decision-close.test.mjs",
|
||||
"packages/bus/tests/decisions.test.mjs",
|
||||
"packages/bus/tests/end-launch.test.mjs",
|
||||
"packages/bus/tests/human.test.mjs",
|
||||
"packages/bus/tests/limits.test.mjs",
|
||||
"packages/bus/tests/message-citation.test.mjs",
|
||||
"packages/bus/tests/messages.test.mjs",
|
||||
"packages/bus/tests/process.test.mjs",
|
||||
"packages/bus/tests/replies.test.mjs",
|
||||
"packages/bus/tests/requirements.test.mjs",
|
||||
"packages/bus/tests/review.test.mjs",
|
||||
"packages/bus/tests/schema.test.mjs",
|
||||
"packages/bus/tests/single-use.test.mjs",
|
||||
"packages/bus/tests/state.test.mjs",
|
||||
"packages/bus/tests/store.test.mjs",
|
||||
"packages/bus/tests/task-page.test.mjs",
|
||||
"packages/bus/tests/task-read.test.mjs",
|
||||
"packages/bus/tests/tasks.test.mjs",
|
||||
"packages/bus/tests/tester.test.mjs",
|
||||
"packages/bus/tests/transport.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-seat",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/seat/tests/checkout.test.mjs",
|
||||
"packages/seat/tests/sandbox.test.mjs",
|
||||
"packages/seat/tests/seat.test.mjs",
|
||||
"packages/seat/tests/session.test.mjs",
|
||||
"packages/seat/tests/working.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-harness",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/harness/tests/bundle.test.mjs",
|
||||
"packages/harness/tests/claude-gate.test.mjs",
|
||||
"packages/harness/tests/claude-session.test.mjs",
|
||||
"packages/harness/tests/gate.test.mjs",
|
||||
"packages/harness/tests/git-tools.test.mjs",
|
||||
"packages/harness/tests/mcp-server.test.mjs",
|
||||
"packages/harness/tests/pi-session.test.mjs",
|
||||
"packages/harness/tests/runner.test.mjs",
|
||||
"packages/harness/tests/tools.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-cli",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/cli/tests/app.test.mjs",
|
||||
"packages/cli/tests/cli.test.mjs",
|
||||
"packages/cli/tests/config.test.mjs",
|
||||
"packages/cli/tests/follow.test.mjs",
|
||||
"packages/cli/tests/format.test.mjs",
|
||||
"packages/cli/tests/git-socket.test.mjs",
|
||||
"packages/cli/tests/host.test.mjs",
|
||||
"packages/cli/tests/launch-limits.test.mjs",
|
||||
"packages/cli/tests/launcher.test.mjs",
|
||||
"packages/cli/tests/limits.test.mjs",
|
||||
"packages/cli/tests/notifier.test.mjs",
|
||||
"packages/cli/tests/other-tree.test.mjs",
|
||||
"packages/cli/tests/stack-copy.test.mjs",
|
||||
"packages/cli/tests/tester.test.mjs",
|
||||
"packages/cli/tests/trackers-boot.test.mjs",
|
||||
"packages/cli/tests/transport.test.mjs",
|
||||
"packages/cli/tests/verbs.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-webui",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/webui/tests/board-held.test.mjs",
|
||||
"packages/webui/tests/browser-edge.test.mjs",
|
||||
"packages/webui/tests/browser.test.mjs",
|
||||
"packages/webui/tests/bus-browser.test.mjs",
|
||||
"packages/webui/tests/bus.test.mjs",
|
||||
"packages/webui/tests/conversation.test.mjs",
|
||||
"packages/webui/tests/discord.test.mjs",
|
||||
"packages/webui/tests/history-return-flow.test.mjs",
|
||||
"packages/webui/tests/messages.test.mjs",
|
||||
"packages/webui/tests/pinned-copy.test.mjs",
|
||||
"packages/webui/tests/preview.test.mjs",
|
||||
"packages/webui/tests/reads.test.mjs",
|
||||
"packages/webui/tests/relaunch.test.mjs",
|
||||
"packages/webui/tests/return-flow.test.mjs",
|
||||
"packages/webui/tests/send-browser.test.mjs",
|
||||
"packages/webui/tests/send.test.mjs",
|
||||
"packages/webui/tests/serve.test.mjs",
|
||||
"packages/webui/tests/service.test.mjs",
|
||||
"packages/webui/tests/settings-form.test.mjs",
|
||||
"packages/webui/tests/settings-write.test.mjs",
|
||||
"packages/webui/tests/shell.test.mjs",
|
||||
"packages/webui/tests/views.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-control-board",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/control-board/tests/attention-flow.test.mjs",
|
||||
"packages/control-board/tests/attention.test.mjs",
|
||||
"packages/control-board/tests/discord.test.mjs",
|
||||
"packages/control-board/tests/relaunch.test.mjs",
|
||||
"packages/control-board/tests/scan.test.mjs",
|
||||
"packages/control-board/tests/serve.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-conversation",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/conversation/tests/claim.test.mjs",
|
||||
"packages/conversation/tests/cohort.test.mjs",
|
||||
"packages/conversation/tests/flows.test.mjs",
|
||||
"packages/conversation/tests/races.test.mjs",
|
||||
"packages/conversation/tests/reader.test.mjs",
|
||||
"packages/conversation/tests/smoke.test.mjs",
|
||||
"packages/conversation/tests/turns.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-ledger",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/ledger/tests/gitea-helper-raw.test.mjs",
|
||||
"packages/ledger/tests/gitea-helper.test.mjs",
|
||||
"packages/ledger/tests/ledger.test.mjs",
|
||||
"packages/ledger/tests/queue-checks.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-tasks",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/tasks/tests/adapter.test.mjs",
|
||||
"packages/tasks/tests/deploy.test.mjs",
|
||||
"packages/tasks/tests/fields.test.mjs",
|
||||
"packages/tasks/tests/requirements.test.mjs",
|
||||
"packages/tasks/tests/shapes.test.mjs",
|
||||
"packages/tasks/tests/startup.test.mjs",
|
||||
"packages/tasks/tests/sync.test.mjs",
|
||||
"packages/tasks/tests/tree.test.mjs",
|
||||
"packages/tasks/tests/verbs.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-runs",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/runs/tests/runs.test.mjs",
|
||||
"packages/runs/tests/state.test.mjs",
|
||||
"packages/runs/tests/task-cli.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-mosaic",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/mosaic/tests/materialize.test.mjs",
|
||||
"packages/mosaic/tests/refresh.test.mjs",
|
||||
"packages/mosaic/tests/registry.test.mjs",
|
||||
"packages/mosaic/tests/safety.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "pkg-discord",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"node",
|
||||
"--test",
|
||||
"--test-concurrency=1",
|
||||
"--test-reporter=spec",
|
||||
"packages/discord/tests/approvals.test.mjs",
|
||||
"packages/discord/tests/authorize.test.mjs",
|
||||
"packages/discord/tests/binding.test.mjs",
|
||||
"packages/discord/tests/connector.test.mjs",
|
||||
"packages/discord/tests/context.test.mjs",
|
||||
"packages/discord/tests/copy-service.test.mjs",
|
||||
"packages/discord/tests/engine.test.mjs",
|
||||
"packages/discord/tests/gateway.test.mjs",
|
||||
"packages/discord/tests/git.test.mjs",
|
||||
"packages/discord/tests/journal.test.mjs",
|
||||
"packages/discord/tests/notify.test.mjs",
|
||||
"packages/discord/tests/offline-check.test.mjs",
|
||||
"packages/discord/tests/recover.test.mjs",
|
||||
"packages/discord/tests/rest.test.mjs",
|
||||
"packages/discord/tests/setspark.test.mjs",
|
||||
"packages/discord/tests/tools.test.mjs",
|
||||
"packages/discord/tests/web.test.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-auth",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-auth.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-conductor",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-conductor.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-config",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-config.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-discord",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-discord.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-extension-package",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-extension-package.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-foundation",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-foundation.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-land-work",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-land-work.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-queue",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-queue.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-release",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-release.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"suite": "script-task",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"bash",
|
||||
"scripts/test-task.sh"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
OK status with missing harness credential exits 3 and still lists accounts
|
||||
OK status reports harness credential (read-only) + mosaic accounts
|
||||
OK api key material never reaches output
|
||||
OK oauth token material never reaches output
|
||||
OK unparseable credential file exits 2
|
||||
OK symlinked credential file exits 4
|
||||
OK env-side credential names reported
|
||||
OK env var values never reach output
|
||||
OK accounts without an accounts dir reports none and creates nothing
|
||||
OK accounts lists files and marks the active one
|
||||
OK loose account perms flagged in listing
|
||||
OK agent --auth with missing account file refuses (exit 4)
|
||||
OK agent --auth with non-0600 account file refuses
|
||||
OK agent --auth with invalid account name refuses
|
||||
OK auth.sh without valid config refuses
|
||||
|
||||
selftest: 15 passed, 0 failed
|
||||
@@ -0,0 +1,55 @@
|
||||
Note: switching to '0afbd818e784c8306db349e201f3a2451667df0f'.
|
||||
|
||||
You are in 'detached HEAD' state. You can look around, make experimental
|
||||
changes and commit them, and you can discard any commits you make in this
|
||||
state without impacting any branches by switching back to a branch.
|
||||
|
||||
If you want to create a new branch to retain commits you create, you may
|
||||
do so (now or later) by using -c with the switch command. Example:
|
||||
|
||||
git switch -c <new-branch-name>
|
||||
|
||||
Or undo this operation with:
|
||||
|
||||
git switch -
|
||||
|
||||
Turn off this advice by setting config variable advice.detachedHead to false
|
||||
|
||||
Not currently on any branch.
|
||||
nothing to commit, working tree clean
|
||||
Note: switching to '0afbd818e784c8306db349e201f3a2451667df0f'.
|
||||
|
||||
You are in 'detached HEAD' state. You can look around, make experimental
|
||||
changes and commit them, and you can discard any commits you make in this
|
||||
state without impacting any branches by switching back to a branch.
|
||||
|
||||
If you want to create a new branch to retain commits you create, you may
|
||||
do so (now or later) by using -c with the switch command. Example:
|
||||
|
||||
git switch -c <new-branch-name>
|
||||
|
||||
Or undo this operation with:
|
||||
|
||||
git switch -
|
||||
|
||||
Turn off this advice by setting config variable advice.detachedHead to false
|
||||
|
||||
OK dry-run: allowed change, exit 0, nothing committed (exit 0)
|
||||
OK dry-run committed nothing
|
||||
OK apply: allowed change exits 0 (exit 0)
|
||||
OK apply: attribution in commit subject
|
||||
OK apply: target tree clean after commit
|
||||
OK disallowed path refused (exit 1)
|
||||
OK disallowed path: target untouched
|
||||
OK syntax gate refused broken .mjs (exit 1)
|
||||
OK syntax gate: target untouched
|
||||
OK suite failure refused (exit 1)
|
||||
OK suite failure: target reverted to clean
|
||||
OK disabled policy refused (exit 2)
|
||||
OK disabled policy: target untouched
|
||||
OK failed run refused (exit 1)
|
||||
OK failed run: target untouched
|
||||
OK missing run exits 4 (exit 4)
|
||||
OK invalid policy exits 2 (exit 2)
|
||||
|
||||
selftest: 17 passed, 0 failed
|
||||
@@ -0,0 +1,26 @@
|
||||
OK absent adapter defaults to pi
|
||||
OK adapter mock validates (exit 0)
|
||||
OK unsupported adapter exits 2 (exit 2)
|
||||
OK env exports adapter
|
||||
OK bootstrap creates default when absent (exit 0)
|
||||
OK bootstrap wrote config file
|
||||
OK bootstrap is idempotent on existing config (exit 0)
|
||||
OK bootstrap did not rewrite existing config
|
||||
OK validate missing config exits 3 (exit 3)
|
||||
OK malformed JSON exits 2 (exit 2)
|
||||
OK unsupported configVersion exits 2 (exit 2)
|
||||
OK unknown top-level key exits 2 (exit 2)
|
||||
OK unknown execution key exits 2 (exit 2)
|
||||
OK unsupported backend exits 2 (exit 2)
|
||||
OK unsupported environment exits 2 (exit 2)
|
||||
OK relative dataRoot exits 2 (exit 2)
|
||||
OK non-canonical dataRoot exits 2 (exit 2)
|
||||
OK filesystem root dataRoot exits 2 (exit 2)
|
||||
OK home directory dataRoot exits 2 (exit 2)
|
||||
OK dataRoot containing config dir exits 2 (exit 2)
|
||||
OK control character in provider exits 2 (exit 2)
|
||||
OK symlinked config file exits 2 (exit 2)
|
||||
OK env exports resolve correctly
|
||||
OK failed validation modified nothing
|
||||
|
||||
selftest: 24 passed, 0 failed
|
||||
@@ -0,0 +1,82 @@
|
||||
toolchain: node v26.8.1
|
||||
|
||||
OK syntax: packages/discord/src/approvals.mjs
|
||||
OK syntax: packages/discord/src/authorize.mjs
|
||||
OK syntax: packages/discord/src/binding.mjs
|
||||
OK syntax: packages/discord/src/cli.mjs
|
||||
OK syntax: packages/discord/src/connector.mjs
|
||||
OK syntax: packages/discord/src/context.mjs
|
||||
OK syntax: packages/discord/src/engine-pi.mjs
|
||||
OK syntax: packages/discord/src/errors.mjs
|
||||
OK syntax: packages/discord/src/gateway.mjs
|
||||
OK syntax: packages/discord/src/git.mjs
|
||||
OK syntax: packages/discord/src/journal.mjs
|
||||
OK syntax: packages/discord/src/notify.mjs
|
||||
OK syntax: packages/discord/src/rest.mjs
|
||||
OK syntax: packages/discord/src/setspark.mjs
|
||||
OK syntax: packages/discord/src/tools.mjs
|
||||
OK syntax: packages/discord/src/web.mjs
|
||||
OK syntax: packages/discord/bin/git-credential.mjs
|
||||
OK syntax: packages/discord/extension/tools.mjs
|
||||
OK syntax: packages/discord/tests/approvals.test.mjs
|
||||
OK syntax: packages/discord/tests/authorize.test.mjs
|
||||
OK syntax: packages/discord/tests/binding.test.mjs
|
||||
OK syntax: packages/discord/tests/connector.test.mjs
|
||||
OK syntax: packages/discord/tests/context.test.mjs
|
||||
OK syntax: packages/discord/tests/copy-service.test.mjs
|
||||
OK syntax: packages/discord/tests/engine.test.mjs
|
||||
OK syntax: packages/discord/tests/fake-pi.mjs
|
||||
OK syntax: packages/discord/tests/gateway.test.mjs
|
||||
OK syntax: packages/discord/tests/git.test.mjs
|
||||
OK syntax: packages/discord/tests/helpers.mjs
|
||||
OK syntax: packages/discord/tests/journal.test.mjs
|
||||
OK syntax: packages/discord/tests/notify.test.mjs
|
||||
OK syntax: packages/discord/tests/offline-check.test.mjs
|
||||
OK syntax: packages/discord/tests/recover.test.mjs
|
||||
OK syntax: packages/discord/tests/rest.test.mjs
|
||||
OK syntax: packages/discord/tests/setspark.test.mjs
|
||||
OK syntax: packages/discord/tests/tools.test.mjs
|
||||
OK syntax: packages/discord/tests/web.test.mjs
|
||||
OK syntax: packages/discord/fixtures/claim-worker.mjs
|
||||
OK syntax: packages/discord/fixtures/legacy-owner-worker.mjs
|
||||
OK syntax: scripts/discord.sh
|
||||
OK syntax: scripts/discord-service.sh
|
||||
OK packages/discord declares no dependencies
|
||||
OK no bot-token-shaped string in packages/discord
|
||||
OK fixture binding uses placeholder ids only
|
||||
OK fixture binding validates
|
||||
OK real pi with the extension exposes exactly list_dir, read_file, search and no built-in tool
|
||||
OK real pi with a writable root exposes exactly the three reads plus write_file and edit_file, and writes nothing at start
|
||||
OK real pi with a web key exposes the three reads plus web_fetch and web_search, and no write tool without a writable root
|
||||
OK real pi with a git root exposes the reads, writes and the four git verbs, commits nothing at start, and never shows the token
|
||||
OK real pi with protocol vault adds reserve_id to the git verbs
|
||||
OK real pi with a setspark key exposes the reads and the eight record verbs, no counters, and never shows the key
|
||||
OK real pi refuses a git key on a read-only root (fail closed)
|
||||
OK real pi with the pilot flags (--no-tools) exposes no tool at all
|
||||
OK real pi exits non-zero without MOSAIC_DISCORD_TOOLS: no session, no tools (fail closed)
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test packages/discord/tests/ (ℹ pass 183)
|
||||
OK scripts/discord.sh --help exits 0
|
||||
OK scripts/discord.sh check without a binding exits 4
|
||||
OK scripts/discord.sh recover without a binding exits 4
|
||||
OK scripts/discord.sh reload without a binding exits 4
|
||||
OK scripts/discord-service.sh without a command exits 4
|
||||
OK service unit renders with the repository path, a supervised run as the main process, exit 3 never retried, and reload as SIGHUP
|
||||
OK service install writes the rendered unit (0644) and leaves no temp file
|
||||
OK service install a second time reports unchanged
|
||||
OK systemd-analyze verify accepts the rendered unit
|
||||
OK service uninstall removes the unit file
|
||||
OK service install with an unknown flag exits 4
|
||||
OK service install with USER unset finishes and names the account for lingering
|
||||
OK pinned render runs copy CLI with copy cwd/repo and no checkout executable
|
||||
OK pinned install writes the rendered unit in a temporary unit directory
|
||||
OK pinned install refuses short prerequisite and writes no unit
|
||||
OK pinned install refuses missing prerequisite and writes no unit
|
||||
OK pinned install refuses cli prerequisite and writes no unit
|
||||
OK pinned install refuses pi prerequisite and writes no unit
|
||||
OK status names the copy from fake systemctl effective cwd
|
||||
OK checkout install explicitly recommends --copy
|
||||
OK wrapper check --offline passes local fixture and makes no network call
|
||||
OK wrapper run --offline refuses usage
|
||||
|
||||
discord suite: 78 passed, 0 failed
|
||||
@@ -0,0 +1,21 @@
|
||||
OK initial ordinary-file install
|
||||
OK installed tree matches canonical source
|
||||
OK installed tree has no symlinks
|
||||
OK check detects installation drift
|
||||
OK sync refuses to overwrite installation drift
|
||||
OK check detects an extra destination file
|
||||
OK check detects an extra destination directory
|
||||
OK check rejects a destination symlink
|
||||
OK sync accepts a canonical source update
|
||||
OK updated installation matches canonical source
|
||||
scripts/test-extension-package.sh: line 14: 919376 Killed "$@" > /dev/null 2>&1
|
||||
OK forced interruption kills the replacing process
|
||||
OK next invocation recovers old consistent installation
|
||||
OK interrupted replacement rolled back
|
||||
OK sync succeeds after interruption recovery
|
||||
OK unlocked stale lock file does not block
|
||||
OK active lock refuses a concurrent sync
|
||||
OK source symlink fails closed
|
||||
OK nested second entrypoint fails closed
|
||||
|
||||
extension package selftest: 18 passed, 0 failed
|
||||
@@ -0,0 +1,53 @@
|
||||
toolchain: node v26.8.1, python 3.12.8, jsonschema 4.26.0
|
||||
|
||||
OK syntax: scripts/foundation-inspect.mjs
|
||||
OK syntax: scripts/foundation/strict-json.mjs
|
||||
OK syntax: scripts/foundation/canonical.mjs
|
||||
OK syntax: scripts/foundation/resolve.mjs
|
||||
OK syntax: scripts/foundation/validate-record.mjs
|
||||
OK syntax: scripts/foundation/fixtures/build-fixtures.mjs
|
||||
OK syntax: scripts/foundation/canonical.test.mjs
|
||||
OK syntax: scripts/foundation/cli.test.mjs
|
||||
OK syntax: scripts/foundation/fixtures.test.mjs
|
||||
OK syntax: scripts/foundation/resolve.test.mjs
|
||||
OK syntax: scripts/foundation/strict-json.test.mjs
|
||||
OK syntax: scripts/foundation/verify-schema.py (ast only; no bytecode written)
|
||||
OK fixture generator runs
|
||||
OK checked-in fixtures/bundles equal a fresh generation
|
||||
OK checked-in fixtures/raw equal a fresh generation
|
||||
OK checked-in fixtures/index.json equal a fresh generation
|
||||
OK checked-in demo bundles equal a fresh generation
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test scripts/foundation/ (ℹ pass 80)
|
||||
OK differential schema oracle: PASS: differential schema oracle (finite corpus; compatibility evidence, not equivalence proof)
|
||||
platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999)
|
||||
node v26.8.1; corpus 1568 records (38 pinned fixtures, 478 unique bundle records, 1052 typeCase/mutation/lexical cases)
|
||||
schema column: agree-valid 540, agree-invalid 991, DISAGREEMENTS 0; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10
|
||||
profile column (schema-valid records only): profile-valid 510, profile-invalid 30
|
||||
profile refusals asserted: 30 schema-agreed-valid records refused only by the strict typed-string profile (rule profile-pattern-mismatch), 12 declared by name; 73 named probes verified against declared schema/profile columns
|
||||
OK oracle: zero schema-column disagreements with the pinned checker
|
||||
OK oracle: strict-only profile refusals are counted and asserted
|
||||
OK demo: permitted read preview exits 0 (exit 0)
|
||||
OK demo: permitted file.change preview exits 0 (exit 0)
|
||||
OK demo: assignment.change proposal is unresolved (exit 3) (exit 3)
|
||||
OK demo: revoked registration is refused (exit 3) (exit 3)
|
||||
OK demo: message is not authority (exit 3) (exit 3)
|
||||
OK usage: no arguments exits 2 (exit 2)
|
||||
OK io: missing file exits 4 (exit 4)
|
||||
OK io: directory exits 4 (exit 4)
|
||||
OK io: symlink exits 4 (O_NOFOLLOW) (exit 4)
|
||||
OK bound: oversize fixture exits 2 (exit 2)
|
||||
OK profile: one final LF in a typed selection id is refused before admission (exit 2) (exit 2)
|
||||
OK profile: two final LFs fail the schema pattern itself (exit 2) (exit 2)
|
||||
OK profile: escaped newlines in free-form text stay allowed (exit 0) (exit 0)
|
||||
OK profile refusal is invalid-request/profile-pattern-mismatch with selection and operation withheld, value not echoed
|
||||
OK text output starts with the disclaimer
|
||||
OK json output is valid JSON with result allowed and exactly the charter §7 fields
|
||||
OK json golden matches byte-for-byte
|
||||
OK sandboxed bundle run (env -i, PATH=/nonexistent) produced the unresolved proposal
|
||||
OK sandbox inventory (path/type/size/mode/uid/gid/inode/mtime/sha256) unchanged by runs
|
||||
OK canary never printed (bundle run and credential-file run)
|
||||
OK a non-bundle JSON file is refused at the shape gate, not read into output
|
||||
OK no field of the non-bundle file is echoed
|
||||
|
||||
selftest: 44 passed, 0 failed
|
||||
@@ -0,0 +1,86 @@
|
||||
OK args: exit 2, target-branch
|
||||
OK args: exit 2, target-branch
|
||||
OK args: exit 4
|
||||
OK args: exit 4
|
||||
OK args: exit 4
|
||||
OK --base next refuses before the config is read (got 2)
|
||||
OK a missing system config exits 3 (got 3)
|
||||
OK nobus: exit 3
|
||||
OK schema-table: exit 2, bus-schema
|
||||
OK schema-meta: exit 2, bus-schema
|
||||
OK openBus opens the database read-only
|
||||
OK other-business: exit 2, decision-not-found
|
||||
OK no-raise: exit 2, decision-not-found
|
||||
OK not-a-merge: exit 2, not-a-merge
|
||||
OK open: exit 2, not-resolved
|
||||
OK withdrawn: exit 2, not-resolved
|
||||
OK by-agent: exit 2, not-human
|
||||
OK via-webui: exit 2, not-human
|
||||
OK no-answer: exit 2, not-human
|
||||
OK answer-role: exit 2, not-human
|
||||
OK answer-run: exit 2, not-human
|
||||
OK answer-choice: exit 2, not-human
|
||||
OK two-answers: exit 2, not-human
|
||||
OK chose-no: exit 2, not-merge-option
|
||||
OK two-refs: exit 2, work-ref
|
||||
OK bad-ref: exit 2, work-ref
|
||||
OK task-ref-disagrees: exit 2, work-ref
|
||||
OK raise-task-disagrees: exit 2, work-ref
|
||||
OK target-main: exit 2, target-branch
|
||||
OK superseded-question: exit 2, superseded
|
||||
OK superseded-task: exit 2, superseded
|
||||
OK superseded-by: exit 2, superseded
|
||||
OK no-verdict: exit 2, no-verdict
|
||||
OK changes-later: exit 2, not-approved
|
||||
OK short-commit: exit 2, not-approved
|
||||
OK wrong-task-body: exit 2, not-approved
|
||||
OK args: exit 2, decision-not-found
|
||||
OK earlier-merge: exit 0
|
||||
OK ref-moved: exit 2, ref-moved
|
||||
OK root-top: exit 2, root-file
|
||||
OK root-newdir: exit 2, root-file
|
||||
OK root-src: exit 2, root-file
|
||||
OK unrelated: exit 2, base-conflict
|
||||
OK empty: exit 2, base-conflict
|
||||
OK an empty reviewed diff says so
|
||||
OK dirty-changed: exit 2, checkout-dirty
|
||||
OK dirty-staged: exit 2, checkout-dirty
|
||||
OK dirty-untracked: exit 2, checkout-dirty
|
||||
OK conflict: exit 2, base-conflict
|
||||
OK a refusal after the worktree is added leaves no worktree or scratch
|
||||
OK cleanup looks for the worktree's Docker network
|
||||
OK dirty-during: exit 2, checkout-dirty
|
||||
OK a reviewed path dirtied during the gate moves no ref
|
||||
OK drift: exit 2, patch-drift
|
||||
OK patch-drift leaves no worktree or scratch
|
||||
OK gate-pkg: exit 2, gate-failed
|
||||
OK gate-failed names the failing step's log, and it exists
|
||||
OK gate-failed leaves no worktree or scratch
|
||||
OK gate-script: exit 2, gate-failed
|
||||
OK a failing scripts/test-*.sh fails the gate
|
||||
OK a failed gate moves no ref
|
||||
OK nomods: exit 4
|
||||
OK a target without node_modules leaves no worktree or scratch
|
||||
OK moved: exit 2, base-moved
|
||||
OK base-moved keeps the base where it moved to
|
||||
OK dry: exit 0
|
||||
OK --dry-run writes no ref
|
||||
OK --dry-run prints the commit with --subject and --attribution
|
||||
OK --dry-run runs the gate
|
||||
OK --dry-run leaves no worktree or scratch
|
||||
OK land: exit 0
|
||||
OK the landing is one commit on the old base
|
||||
OK its diff is the reviewed diff by patch-id
|
||||
OK its tree is the dry run's
|
||||
OK the message has the option's subject, the citations and the attribution last
|
||||
OK it prints the line for the PM
|
||||
OK the checked-out base has the reviewed paths and keeps the unrelated edit
|
||||
OK only refs/heads/refactor exists in the target
|
||||
OK the work ref is unchanged
|
||||
OK the bus database is unchanged
|
||||
OK the gate ran each package suite but queue, and each scripts/test-*.sh
|
||||
OK the landing leaves no worktree or scratch
|
||||
OK the target's node_modules is still there, with its contents
|
||||
OK the worktree's Docker network is removed
|
||||
---
|
||||
land-work selftests: 84 passed, 0 failed
|
||||
@@ -0,0 +1,36 @@
|
||||
toolchain: node v26.8.1, git version 2.55.0
|
||||
|
||||
OK syntax: packages/queue/src/cli.mjs
|
||||
OK syntax: packages/queue/src/errors.mjs
|
||||
OK syntax: packages/queue/src/io.mjs
|
||||
OK syntax: packages/queue/src/lock.mjs
|
||||
OK syntax: packages/queue/src/queue.mjs
|
||||
OK syntax: packages/queue/src/review.mjs
|
||||
OK syntax: packages/queue/src/store.mjs
|
||||
OK syntax: packages/queue/tests/commit.test.mjs
|
||||
OK syntax: packages/queue/tests/data.test.mjs
|
||||
OK syntax: packages/queue/tests/dispatch.test.mjs
|
||||
OK syntax: packages/queue/tests/gate-owner.test.mjs
|
||||
OK syntax: packages/queue/tests/helpers.mjs
|
||||
OK syntax: packages/queue/tests/lock.test.mjs
|
||||
OK syntax: packages/queue/tests/migration.test.mjs
|
||||
OK syntax: packages/queue/tests/review.test.mjs
|
||||
OK syntax: packages/queue/tests/store.test.mjs
|
||||
OK syntax: packages/queue/tests/write.test.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/fake-gitea.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/kill-at.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/lock-child.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/mosaic-pre-a2.sh
|
||||
OK syntax: scripts/queue-commit.sh
|
||||
OK syntax: scripts/git-hooks/pre-commit
|
||||
OK syntax: scripts/mosaic
|
||||
OK queue-commit.sh, the guard and scripts/mosaic are executable
|
||||
OK packages/queue declares no dependencies
|
||||
ℹ tests 156
|
||||
ℹ pass 156
|
||||
ℹ fail 0
|
||||
OK node --test packages/queue/tests/
|
||||
OK scripts/mosaic queue help
|
||||
skip queue verify and render --check: this checkout (/mnt/storage/src/mosaic-stack-rocko-122-r2) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
|
||||
|
||||
queue suite: 28 passed, 0 failed
|
||||
@@ -0,0 +1,16 @@
|
||||
OK valid RELEASE resolves (exit 0)
|
||||
OK invalid RELEASE exits 1 (exit 1)
|
||||
OK missing RELEASE exits 1 (exit 1)
|
||||
OK valid RELEASE leaves image tag consistent with version
|
||||
OK status safe on empty state (exit 0)
|
||||
OK status created no pointer
|
||||
OK fault-injected activation refuses (exit 1)
|
||||
OK refused activation wrote no pointer
|
||||
OK refusal logged exactly once with valid fields
|
||||
OK healthy activation succeeds (exit 0)
|
||||
OK pointer written with valid fields
|
||||
OK repeat activation succeeds (log grows) (exit 0)
|
||||
OK log is append-only across activations
|
||||
OK rollback without previous refuses (exit 1)
|
||||
|
||||
selftest: 14 passed, 0 failed
|
||||
@@ -0,0 +1,101 @@
|
||||
OK valid task validates (exit 0)
|
||||
OK unknown task key exits 2 (exit 2)
|
||||
OK unsupported taskVersion exits 2 (exit 2)
|
||||
OK invalid task id exits 2 (exit 2)
|
||||
OK empty prompt exits 2 (exit 2)
|
||||
OK NUL in expectExact exits 2 (exit 2)
|
||||
OK out-of-range timeout exits 2 (exit 2)
|
||||
OK missing mission file exits 4 (exit 4)
|
||||
OK task with valid mission validates (exit 0)
|
||||
OK invalid mission exits 2 (exit 2)
|
||||
OK validate missing task exits 4 (exit 4)
|
||||
OK validation does not modify the task file
|
||||
OK prune dry-run exits 0 (exit 0)
|
||||
OK dry-run deleted nothing
|
||||
OK prune --keep=2 --yes removes oldest (exit 0)
|
||||
OK kept exactly 2 newest runs
|
||||
OK newest run kept, oldest pruned
|
||||
OK append-only receipt written (3 entries)
|
||||
OK sessions/workspaces untouched by prune
|
||||
OK prune with invalid keep exits 4 (exit 4)
|
||||
OK mock adapter: gate passes on matching mock response (exit 0)
|
||||
OK mock adapter: expect-mismatch recorded (exit 1)
|
||||
OK mismatch reason recorded
|
||||
OK unknown adapter fails closed (exit 1)
|
||||
OK mission task runs via mock adapter (exit 0)
|
||||
OK mission section injected into generated prompt
|
||||
OK retry of mission run succeeds (exit 0)
|
||||
OK retriedFrom lineage recorded
|
||||
OK mission section present after retry (relative path resolved)
|
||||
OK retry of missing run exits 4 (exit 4)
|
||||
OK skill install bundled ms-tools (exit 0)
|
||||
OK installed to skills-available
|
||||
OK double install refuses (exit 1)
|
||||
OK activate enables skill (exit 0)
|
||||
OK enabled dir populated
|
||||
OK uninstall while enabled refuses (exit 1)
|
||||
OK deactivate moves back to available (exit 0)
|
||||
OK uninstall removes from available (exit 0)
|
||||
OK seat with enabled skill launches
|
||||
OK skill path delivered to adapter
|
||||
OK shipped researcher contract resolves (ceiling + network)
|
||||
OK resolve-role refuses a non-role document (conductor policy) (exit 2)
|
||||
OK resolve-role refuses name/filename mismatch (exit 2)
|
||||
OK resolve-role refuses unknown network declaration (exit 2)
|
||||
OK resolve-role refuses duplicate role tool (exit 2)
|
||||
OK resolve-role refuses unsupported tool (exit 2)
|
||||
OK resolve-role refuses missing contract file (exit 4)
|
||||
OK version 1 role prints no contract line
|
||||
OK shipped version 2 roles resolve with their contracts (pm, cto, coder, reviewer)
|
||||
OK resolve-role accepts a minimal version 2 role (exit 0)
|
||||
OK resolve-role refuses an action outside the vocabulary (exit 2)
|
||||
OK resolve-role refuses a gated-only action in a role file (exit 2)
|
||||
OK resolve-role refuses a Vikunja verb no role may hold (exit 2)
|
||||
OK resolve-role refuses a version 2 role whose contract is missing (exit 2)
|
||||
OK resolve-role refuses a contract that is a symbolic link (exit 2)
|
||||
OK seat launches under role ceiling
|
||||
OK role ceiling narrows seat tools (read,write,bash -> read,bash)
|
||||
OK narrowing recorded loudly
|
||||
OK missing role contract refuses launch (exit 2)
|
||||
OK missing-contract refusal names the role
|
||||
OK empty ceiling intersection -> tool-free seat
|
||||
OK tool-free outcome recorded loudly
|
||||
OK overridden agents dir without seat definition refuses (exit 4)
|
||||
OK seat-resolution refusal names the seat
|
||||
OK policy: mission only -> mission tools
|
||||
OK policy: task only -> task tools
|
||||
OK policy: both -> intersection (task narrowed)
|
||||
OK policy: empty intersection -> tool-free
|
||||
OK invalid mission capabilities rejected (exit 2)
|
||||
mosaic-task: unsupported mission tool: "sudo" (supported: read, write, edit, bash, grep, find, ls)
|
||||
OK task run with user layer present (exit 0)
|
||||
OK user context dispatched into generated prompt
|
||||
OK workspace+tools task runs via mock (exit 0)
|
||||
OK workspace path + tools delivered to adapter
|
||||
OK persistent workspace created on host
|
||||
OK plain task still runs (no workspace/tools) (exit 0)
|
||||
OK workspace var present but empty when absent
|
||||
OK tools empty when absent
|
||||
OK unknown tool exits 2 (exit 2)
|
||||
OK workspace traversal exits 2 (exit 2)
|
||||
OK live hello task succeeds with exact marker
|
||||
OK result.json written in run dir
|
||||
OK result.json contents are correct
|
||||
OK wrong expectExact fails with exit 1 (reason: expect-mismatch)
|
||||
OK each run gets a distinct run dir (no clobber)
|
||||
OK list shows both runs
|
||||
OK fork base: teach succeeds (exit 0)
|
||||
OK fork child recalls ancestor context (exit 0)
|
||||
OK forked child recalled ancestor code word
|
||||
OK ancestor session untouched by fork
|
||||
OK child session dir has its own branch file
|
||||
OK onboard without name exits 4 (non-interactive) (exit 4)
|
||||
OK onboard --name renders profile (exit 0)
|
||||
OK profile written
|
||||
OK canon structure: required filled, optional placeholdered
|
||||
OK canon sections present
|
||||
OK user recall run succeeds
|
||||
OK recalled user name (response: Jason)
|
||||
OK no agent identity on headless run
|
||||
|
||||
selftest: 98 passed, 0 failed
|
||||
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/launch/max"
|
||||
},
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/launch/models",
|
||||
"value": {
|
||||
"opus": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-5-5"
|
||||
},
|
||||
"sonnet": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-5-5"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/launch/limits",
|
||||
"value": {
|
||||
"models": {
|
||||
"anthropic": {
|
||||
"claude-opus-5-5": 4,
|
||||
"claude-sonnet-5-5": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/pm/vars/model",
|
||||
"value": "opus"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/cto/vars/model",
|
||||
"value": "opus"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/coder/vars/model",
|
||||
"value": "sonnet"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/reviewer/vars/model",
|
||||
"value": "opus"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/chief/vars/model",
|
||||
"value": "opus"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/roles/assistant/vars/model",
|
||||
"value": "opus"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,44 @@
|
||||
docs/TOOLS.md: OK
|
||||
packages/bus/src/broker.mjs: OK
|
||||
packages/bus/src/runtime.mjs: OK
|
||||
packages/bus/tests/limits.test.mjs: OK
|
||||
packages/business/README.md: OK
|
||||
packages/business/examples/mosaic-stack.example.json: OK
|
||||
packages/business/src/business.mjs: OK
|
||||
packages/business/src/index.mjs: OK
|
||||
packages/business/src/launch-settings.mjs: OK
|
||||
packages/business/src/launch.mjs: OK
|
||||
packages/business/src/migrate-launch.mjs: OK
|
||||
packages/business/src/organization.mjs: OK
|
||||
packages/business/src/vocabulary.mjs: OK
|
||||
packages/business/tests/assistant.test.mjs: OK
|
||||
packages/business/tests/business.test.mjs: OK
|
||||
packages/business/tests/chief-of-staff.test.mjs: OK
|
||||
packages/business/tests/helpers.mjs: OK
|
||||
packages/business/tests/launch-settings.test.mjs: OK
|
||||
packages/business/tests/resolve.test.mjs: OK
|
||||
packages/cli/README.md: OK
|
||||
packages/cli/src/cli.mjs: OK
|
||||
packages/cli/src/config.mjs: OK
|
||||
packages/cli/src/launcher.mjs: OK
|
||||
packages/cli/src/limits.mjs: OK
|
||||
packages/cli/tests/launch-limits.test.mjs: OK
|
||||
packages/cli/tests/launcher.test.mjs: OK
|
||||
packages/cli/tests/limits.test.mjs: OK
|
||||
packages/harness/src/bundle.mjs: OK
|
||||
packages/harness/tests/pi-session.test.mjs: OK
|
||||
packages/harness/tests/runner.test.mjs: OK
|
||||
packages/seat/src/session.mjs: OK
|
||||
packages/seat/tests/session.test.mjs: OK
|
||||
packages/webui/src/bus.mjs: OK
|
||||
packages/webui/src/cli.mjs: OK
|
||||
packages/webui/src/public/bus.js: OK
|
||||
packages/webui/src/reads.mjs: OK
|
||||
packages/webui/src/serve.mjs: OK
|
||||
packages/webui/tests/reads-fixture.mjs: OK
|
||||
packages/webui/tests/reads.test.mjs: OK
|
||||
packages/webui/tests/settings-form.test.mjs: OK
|
||||
packages/webui/tests/settings-write.test.mjs: OK
|
||||
packages/webui/tests/shell.test.mjs: OK
|
||||
packages/webui/tests/views.test.mjs: OK
|
||||
scripts/mosaic: OK
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"models": {
|
||||
"opus": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-5-5"
|
||||
},
|
||||
"sonnet": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-5-5"
|
||||
}
|
||||
},
|
||||
"families": {
|
||||
"opus": "opus",
|
||||
"sonnet": "sonnet"
|
||||
},
|
||||
"instances": {
|
||||
"pm": "opus",
|
||||
"cto": "opus",
|
||||
"coder": "sonnet",
|
||||
"reviewer": "opus",
|
||||
"chief": "opus",
|
||||
"assistant": "opus"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
01-whole-document-validation KILLED 1
|
||||
02-atomic-publication KILLED 1
|
||||
03-previous-version KILLED 1
|
||||
04-authenticated-actor KILLED 1
|
||||
05-old-new-receipt KILLED 1
|
||||
06-stale-revision KILLED 1
|
||||
07-uncertain-recovery KILLED 1
|
||||
08-total-limit KILLED 1
|
||||
09-provider-limit KILLED 1
|
||||
10-model-limit KILLED 1
|
||||
11-at-limit KILLED 1
|
||||
12-unset-unlimited KILLED 1
|
||||
13-nonnegative-counts KILLED 1
|
||||
14-no-policy-ceiling KILLED 1
|
||||
15-exact-provider-count KILLED 1
|
||||
16-provider-routing KILLED 1
|
||||
17-reread-every-launch KILLED 1
|
||||
18-refusal-hit-logged KILLED 1
|
||||
19-migration-preserve-counts KILLED 1
|
||||
20-migration-ambiguity KILLED 1
|
||||
21-print-only-migration KILLED 1
|
||||
22-human-only-settings KILLED 1
|
||||
23-settings-origin KILLED 1
|
||||
24-settings-fetch-metadata KILLED 1
|
||||
25-settings-send-mode KILLED 1
|
||||
26-settings-strict-keys KILLED 1
|
||||
27-form-instances KILLED 1
|
||||
28-form-limit-payload KILLED 1
|
||||
29-migration-idempotent KILLED 1
|
||||
30-zero-stops-new KILLED 1
|
||||
31-instance-model-edit KILLED 1
|
||||
32-model-table-edit KILLED 1
|
||||
33-runtime-writer-wiring KILLED 1
|
||||
34-inherited-exact-model KILLED 1
|
||||
35-inherited-provider KILLED 1
|
||||
36-config-required KILLED 1
|
||||
37-recovery-not-at-start KILLED 1
|
||||
38-uncertain-writes-refuse KILLED 1
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
"""One fault per acceptance check. Sequential process groups; whole-group timeout cleanup."""
|
||||
import json,os,pathlib,signal,subprocess,sys,time
|
||||
ROOT=pathlib.Path(sys.argv[1] if len(sys.argv)>1 else '/mnt/storage/src/mosaic-stack-rocko-122-r2')
|
||||
OUT=pathlib.Path(__file__).resolve().parent/'mutants';OUT.mkdir(exist_ok=True)
|
||||
B='packages/business/tests/launch-settings.test.mjs';C='packages/cli/tests/limits.test.mjs';L='packages/cli/tests/launch-limits.test.mjs';H='packages/bus/tests/limits.test.mjs';W='packages/webui/tests/settings-write.test.mjs';F='packages/webui/tests/settings-form.test.mjs'
|
||||
cases=[]
|
||||
def add(id,path,old,new,test):cases.append(dict(id=id,path=path,old=old,new=new,test=test))
|
||||
p='packages/business/src/organization.mjs'
|
||||
add('01-whole-document-validation',p,'validateBusinessDocument(document, file, { rolesDir });\n const old','/* validation omitted */\n const old',B)
|
||||
add('02-atomic-publication',p,'renameSync(candidate, file);','/* publication omitted */',B)
|
||||
add('03-previous-version',p,'durable(previous, oldBytes);',"durable(previous, '{}');",B)
|
||||
add('04-authenticated-actor',p,'transaction, actor, business: id, before, after,','transaction, actor: "anonymous", business: id, before, after,',B)
|
||||
add('05-old-new-receipt',p,'changes: changes(old, document)','changes: []',B)
|
||||
add('06-stale-revision',p,'if (revision !== before)','if (false)',B)
|
||||
add('07-uncertain-recovery',p,'if (hash !== e.before && hash !== e.after)','if (false)',B)
|
||||
p='packages/business/src/launch.mjs'
|
||||
add('08-total-limit',p,'["total", limits.total, usage.total]','["total", undefined, usage.total]',B)
|
||||
add('09-provider-limit',p,'own(limits.providers, provider)','undefined',B)
|
||||
add('10-model-limit',p,'own(own(limits.models, provider), model)','undefined',B)
|
||||
add('11-at-limit',p,'running >= limit','running > limit',B)
|
||||
add('12-unset-unlimited',p,'["total", limits.total, usage.total]','["total", limits.total ?? 0, usage.total]',B)
|
||||
add('13-nonnegative-counts',p,'!Number.isSafeInteger(value) || value < 0','!Number.isSafeInteger(value)',B)
|
||||
add('14-no-policy-ceiling',p,'!Number.isSafeInteger(value) || value < 0','!Number.isSafeInteger(value) || value < 0 || value > 4',B)
|
||||
add('15-exact-provider-count',p,'providerCounts.set(provider, (providerCounts.get(provider) ?? 0) + 1);','providerCounts.set("anthropic", (providerCounts.get("anthropic") ?? 0) + 1);',B)
|
||||
add('16-provider-routing','packages/harness/src/bundle.mjs','provider:entry.provider',"provider:'anthropic'",B)
|
||||
p='packages/cli/src/launcher.mjs'
|
||||
add('17-reread-every-launch',p,'b=loadBusiness(host.business,{dir:configDir(env),rolesDir:rolesDir(env)});','/* cached policy */',L)
|
||||
add('18-refusal-hit-logged',p,'...(e.limit?{limit:e.limit}:{})','/* omitted hit */',L)
|
||||
p='packages/business/src/migrate-launch.mjs'
|
||||
add('19-migration-preserve-counts',p,'limits.models[entry.provider][entry.model] = count;','limits.models[entry.provider][entry.model] = 0;',C)
|
||||
add('20-migration-ambiguity',p,'if (used.has(tuple))','if (false)',B)
|
||||
add('21-print-only-migration','packages/cli/src/limits.mjs','const converted = migrateLaunch(raw, mapping, file, { rolesDir, system });','(await import("node:fs")).writeFileSync(file, JSON.stringify(raw));\n const converted = migrateLaunch(raw, mapping, file, { rolesDir, system });',C)
|
||||
add('22-human-only-settings','packages/bus/src/broker.mjs','if (!s.human) fail("human-required");','/* human check omitted */',H)
|
||||
p='packages/webui/src/serve.mjs'
|
||||
add('23-settings-origin',p,"if (one(req, 'origin') !== `https://${preview.host}`)",'if (false)',W)
|
||||
add('24-settings-fetch-metadata',p,"if (one(req, 'sec-fetch-site') !== 'same-origin')",'if (false)',W)
|
||||
add('25-settings-send-mode',p,'if(!send||!settingsWrite||!named)','if(!settingsWrite||!named)',W)
|
||||
add('26-settings-strict-keys',p,"Object.keys(value).some(key => !['revision', ...writable].includes(key))",'false',W)
|
||||
p='packages/webui/src/public/bus.js'
|
||||
add('27-form-instances',p,'Object.entries(v.instances||{})','Object.entries({})',F)
|
||||
add('28-form-limit-payload',p,"if(kind==='total')limits.total=n;","if(kind==='total')limits.total=1;",F)
|
||||
add('29-migration-idempotent','packages/business/src/migrate-launch.mjs','if (!out.launch?.max)','if (false)',C)
|
||||
add('30-zero-stops-new','packages/business/src/launch.mjs','limit !== undefined && running >= limit','limit !== undefined && limit > 0 && running >= limit',B)
|
||||
add('31-instance-model-edit','packages/business/src/launch-settings.mjs','if (Object.hasOwn(args, "instances"))','if (false)',B)
|
||||
add('32-model-table-edit','packages/business/src/launch-settings.mjs','if (Object.hasOwn(args, "models")) next.launch.models = args.models;','/* model table ignored */',B)
|
||||
add('33-runtime-writer-wiring','packages/bus/src/runtime.mjs',"organization:settings?(id,verb,args,actor)=>verb==='limits'?settings.read(id):settings.set(id,args,actor):null,",'organization:null,',H)
|
||||
p='packages/business/src/migrate-launch.mjs'
|
||||
add('34-inherited-exact-model',p,'old = system?.["execution.model"];','old = models[mapping.instances[instance]].model;',C)
|
||||
add('35-inherited-provider',p,'provider = system?.["execution.provider"];','provider = models[mapping.instances[instance]].provider;',C)
|
||||
add('36-config-required','packages/cli/src/limits.mjs','const system = inherits ? systemVars(loadSystem({ env: io.env })) : null;','const system = inherits ? {"execution.provider":"anthropic","execution.model":"claude-opus-5-5"} : null;',C)
|
||||
p='packages/bus/src/runtime.mjs'
|
||||
add('37-recovery-not-at-start',p,'const settings=organization?launchSettings({...organization,sessions:()=>readSessions(dataRoot)}):null;','const settings=organization?launchSettings({...organization,sessions:()=>readSessions(dataRoot)}):null;\n if(settings)for(const id of Object.keys(businesses))settings.writer.recover(id);',H)
|
||||
add('38-uncertain-writes-refuse','packages/business/src/organization.mjs',' recover(id);',' /* reconciliation omitted */',H)
|
||||
# Apply all matching copies for repeated logging sites. Every fault must change source.
|
||||
results=[]
|
||||
for c in cases:
|
||||
file=ROOT/c['path'];before=file.read_text();matches=before.count(c['old'])
|
||||
if not matches:raise RuntimeError('missing mutation site '+c['id'])
|
||||
file.write_text(before.replace(c['old'],c['new']))
|
||||
try:
|
||||
env={**os.environ,'DOCKER_HOST':'unix:///nonexistent.sock'}
|
||||
with (OUT/(c['id']+'.log')).open('w') as log:
|
||||
p=subprocess.Popen(['node','--test',c['test']],cwd=ROOT,env=env,stdout=log,stderr=subprocess.STDOUT,start_new_session=True)
|
||||
try:rc=p.wait(timeout=120)
|
||||
except subprocess.TimeoutExpired:os.killpg(p.pid,signal.SIGKILL);p.wait();rc='timeout'
|
||||
verdict='KILLED' if isinstance(rc,int) and rc!=0 else 'SURVIVED' if rc==0 else 'TIMEOUT'
|
||||
row={k:c[k] for k in ['id','path','test']};row.update(result=verdict,exit=rc,sites=matches);results.append(row);print(c['id'],verdict,rc,flush=True)
|
||||
finally:file.write_text(before)
|
||||
(OUT/'results.json').write_text(json.dumps(results,indent=2)+'\n')
|
||||
sys.exit(0 if all(r['result']=='KILLED' for r in results) else 1)
|
||||
@@ -0,0 +1,32 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (9.186122ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.578154ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.076218ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.004302ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.691905ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (16.053185ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.697007ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.1352ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 115.266093
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.076218ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:29:167)
|
||||
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: undefined,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.511204ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.52458ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (10.390992ms)
|
||||
✖ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.273538ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.69982ms)
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (12.310118ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.419486ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.903146ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 106.398241
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (10.390992ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
undefined !== 99
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:27:9)
|
||||
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: undefined,
|
||||
expected: 99,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:31:1
|
||||
✖ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.273538ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
undefined !== 7
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:35:244)
|
||||
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: undefined,
|
||||
expected: 7,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:43:1
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (12.310118ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
undefined !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:45:118)
|
||||
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: undefined,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.730527ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.515237ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (9.488106ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (14.709004ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.837764ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (16.068732ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.525655ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.257774ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 110.941631
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (9.488106ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ '{}'
|
||||
- '{\n' +
|
||||
- ' "businessVersion": 1,\n' +
|
||||
- ' "id": "acme",\n' +
|
||||
- ' "human": "jason",\n' +
|
||||
- ' "arbiters": {\n' +
|
||||
- ' "delivery": "pm",\n' +
|
||||
- ' "technical": "cto"\n' +
|
||||
- ' },\n' +
|
||||
- ' "projects": {\n' +
|
||||
- ' "stack": {\n' +
|
||||
- ' "root": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/project"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "tracker.baseUrl": "http://127.0.0.1:3456",\n' +
|
||||
- ' "gitea.baseUrl": "https://git.example",\n' +
|
||||
- ' "tracker.pollSeconds": 60\n' +
|
||||
- ' },\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "sync": {\n' +
|
||||
- ' "bot": "bot-acme-sync",\n' +
|
||||
- ' "botId": 9,\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/sync-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "labels": {}\n' +
|
||||
- ' },\n' +
|
||||
- ' "roles": {\n' +
|
||||
- ' "pm": {\n' +
|
||||
- ' "definition": "pm",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-pm",\n' +
|
||||
- ' "botId": 3\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/pm-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/pm-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "holder": "sage",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "pi",\n' +
|
||||
- ' "model": "opus"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "cto": {\n' +
|
||||
- ' "definition": "cto",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-cto",\n' +
|
||||
- ' "botId": 4\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/cto-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/cto-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "holder": "darkwing",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "claude-code",\n' +
|
||||
- ' "model": "sonnet"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "coder": {\n' +
|
||||
- ' "definition": "coder",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-coder",\n' +
|
||||
- ' "botId": 5\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/coder-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/coder-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "pi",\n' +
|
||||
- ' "limits.network": "none",\n' +
|
||||
- ' "model": "sonnet"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "reviewer": {\n' +
|
||||
- ' "definition": "reviewer",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-reviewer",\n' +
|
||||
- ' "botId": 6\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/reviewer-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/reviewer-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "model": "sonnet"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "chief": {\n' +
|
||||
- ' "definition": "chief-of-staff",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "model": "sonnet"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "launch": {\n' +
|
||||
- ' "by": "chief",\n' +
|
||||
- ' "instances": [\n' +
|
||||
- ' "coder",\n' +
|
||||
- ' "reviewer"\n' +
|
||||
- ' ],\n' +
|
||||
- ' "models": {\n' +
|
||||
- ' "opus": {\n' +
|
||||
- ' "provider": "anthropic",\n' +
|
||||
- ' "model": "claude-opus-5-5"\n' +
|
||||
- ' },\n' +
|
||||
- ' "sonnet": {\n' +
|
||||
- ' "provider": "anthropic",\n' +
|
||||
- ' "model": "claude-sonnet-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "limits": {\n' +
|
||||
- ' "models": {\n' +
|
||||
- ' "anthropic": {\n' +
|
||||
- ' "claude-opus-5-5": 4,\n' +
|
||||
- ' "claude-sonnet-5-5": 4\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- '}\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:27:131)
|
||||
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: '{}',
|
||||
expected: '{\n "businessVersion": 1,\n "id": "acme",\n "human": "jason",\n "arbiters": {\n "delivery": "pm",\n "technical": "cto"\n },\n "projects": {\n "stack": {\n "root": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/project"\n }\n },\n "vars": {\n "tracker.baseUrl": "http://127.0.0.1:3456",\n "gitea.baseUrl": "https://git.example",\n "tracker.pollSeconds": 60\n },\n "tracker": {\n "sync": {\n "bot": "bot-acme-sync",\n "botId": 9,\n "credentials": {\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/sync-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "labels": {}\n },\n "roles": {\n "pm": {\n "definition": "pm",\n "tracker": {\n "bot": "bot-acme-pm",\n "botId": 3\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/pm-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/pm-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "holder": "sage",\n "vars": {\n "harness": "pi",\n "model": "opus"\n }\n },\n "cto": {\n "definition": "cto",\n "tracker": {\n "bot": "bot-acme-cto",\n "botId": 4\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/cto-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/cto-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "holder": "darkwing",\n "vars": {\n "harness": "claude-code",\n "model": "sonnet"\n }\n },\n "coder": {\n "definition": "coder",\n "tracker": {\n "bot": "bot-acme-coder",\n "botId": 5\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/coder-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/coder-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "vars": {\n "harness": "pi",\n "limits.network": "none",\n "model": "sonnet"\n }\n },\n "reviewer": {\n "definition": "reviewer",\n "tracker": {\n "bot": "bot-acme-reviewer",\n "botId": 6\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/reviewer-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-business-KfyCsI/secrets/reviewer-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "vars": {\n "model": "sonnet"\n }\n },\n "chief": {\n "definition": "chief-of-staff",\n "vars": {\n "model": "sonnet"\n }\n }\n },\n "launch": {\n "by": "chief",\n "instances": [\n "coder",\n "reviewer"\n ],\n "models": {\n "opus": {\n "provider": "anthropic",\n "model": "claude-opus-5-5"\n },\n "sonnet": {\n "provider": "anthropic",\n "model": "claude-sonnet-5-5"\n }\n },\n "limits": {\n "models": {\n "anthropic": {\n "claude-opus-5-5": 4,\n "claude-sonnet-5-5": 4\n }\n }\n }\n }\n}\n',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.877743ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.549242ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (10.535701ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.977217ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.718855ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.495197ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.729416ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.083757ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 115.837814
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (10.535701ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'anonymous'
|
||||
- 'jason'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:28:118)
|
||||
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: 'anonymous',
|
||||
expected: 'jason',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.907175ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.537022ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (12.1917ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.307837ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.839784ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.329823ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.506333ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.795165ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 110.519554
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (12.1917ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(e.changes.some(c=>c.path==='launch.limits.total'&&c.new===99))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:28:182)
|
||||
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: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.670086ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.525348ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.884313ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.041586ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.004241ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.776249ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.442853ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.702986ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 113.599461
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.884313ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:29:49)
|
||||
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: /revision/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.576461ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.562103ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.74923ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.337629ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.012533ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.043675ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.700778ms)
|
||||
✖ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.030105ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 119.78724
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:53:1
|
||||
✖ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.030105ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:55:331)
|
||||
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: /match prepared/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.95932ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (2.899547ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.612262ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.587287ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.754921ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (16.247693ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.713059ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.255621ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 122.410657
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (2.899547ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(limitHit(sessions,'acme',limits,{provider:'anthropic',model:'opus-exact'}))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:106)
|
||||
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: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.950861ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.024696ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.6882ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (11.773444ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.649335ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.603107ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.565745ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.928534ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 118.845726
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.024696ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(limitHit(sessions,'acme',limits,{provider:'anthropic',model:'opus-exact'}))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:106)
|
||||
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: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.565745ms)
|
||||
TypeError: Cannot read properties of null (reading 'scope')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:50:357)
|
||||
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,42 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.873349ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.044543ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (15.62589ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.565561ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.780671ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.197901ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.503139ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.43741ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 121.757418
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.044543ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(limitHit(sessions,'acme',limits,{provider:'anthropic',model:'opus-exact'}))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:106)
|
||||
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: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.503139ms)
|
||||
TypeError: Cannot read properties of null (reading 'scope')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:50:468)
|
||||
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,42 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (9.085695ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (2.975655ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (17.506024ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.647154ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.928657ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.094091ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.601888ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.551356ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 117.568764
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (2.975655ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(limitHit(sessions,'acme',limits,{provider:'anthropic',model:'opus-exact'}))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:106)
|
||||
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: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.601888ms)
|
||||
TypeError: Cannot read properties of null (reading 'scope')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:50:357)
|
||||
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,64 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.696143ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.160262ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (15.59507ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (11.857626ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.881194ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.78099ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.62378ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.658206ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 117.117963
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.160262ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ {
|
||||
+ limit: 0,
|
||||
+ running: 1,
|
||||
+ scope: 'total'
|
||||
+ }
|
||||
- null
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:192)
|
||||
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: { scope: 'total', limit: 0, running: 1 },
|
||||
expected: null,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.62378ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ {
|
||||
+ limit: 0,
|
||||
+ running: 1,
|
||||
+ scope: 'total'
|
||||
+ }
|
||||
- null
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:50:86)
|
||||
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: { scope: 'total', limit: 0, running: 1 },
|
||||
expected: null,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
✖ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (7.285996ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.6686ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.635826ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.25356ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.915124ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.998172ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.568857ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.368288ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 118.11527
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:10:1
|
||||
✖ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (7.285996ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:13:104)
|
||||
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: undefined,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (13.635826ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:29:167)
|
||||
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: undefined,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
✖ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (6.382947ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.617716ms)
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (5.367264ms)
|
||||
✖ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (9.603291ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.041805ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (17.157403ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.483634ms)
|
||||
✖ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (3.942983ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 4
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 98.610689
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:10:1
|
||||
✖ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (6.382947ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-56OueL/businesses/acme.json launch.limits.total must be a whole number of 0 or more
|
||||
at refuse (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/errors.mjs:12:9)
|
||||
at count (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/launch.mjs:7:63)
|
||||
at checkLimits (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/launch.mjs:30:50)
|
||||
at checkLaunch (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/business.mjs:130:16)
|
||||
at validateBusinessDocument (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/business.mjs:180:57)
|
||||
at check (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:11:29)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:12:257)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:24:1
|
||||
✖ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (5.367264ms)
|
||||
Error [BusinessError]: /mnt/storage/scratch/tmp/mosaic-business-5bKON1/businesses/acme.json launch.limits.total must be a whole number of 0 or more
|
||||
at refuse (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/errors.mjs:12:9)
|
||||
at count (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/launch.mjs:7:63)
|
||||
at checkLimits (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/launch.mjs:30:50)
|
||||
at checkLaunch (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/business.mjs:130:16)
|
||||
at validateBusinessDocument (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/business.mjs:180:57)
|
||||
at file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:186:7
|
||||
at withLock (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:128:14)
|
||||
at Object.write (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:180:12)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:26:77)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:31:1
|
||||
✖ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (9.603291ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
undefined !== 7
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:35:244)
|
||||
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: undefined,
|
||||
expected: 7,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:53:1
|
||||
✖ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (3.942983ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:55:331)
|
||||
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: /match prepared/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.55136ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.525161ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.151978ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.430806ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.885607ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.139925ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.587774ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.992096ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 116.971275
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.587774ms)
|
||||
TypeError: Cannot read properties of null (reading 'scope')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:50:357)
|
||||
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,37 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (9.201694ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.601564ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (15.191996ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (11.933913ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.924855ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.817036ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (2.13097ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.723778ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 116.399523
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (2.13097ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'anthropic'
|
||||
- 'proxy-next'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:49:153)
|
||||
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: 'anthropic',
|
||||
expected: 'proxy-next',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
✖ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (9.833616ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 64.913401
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/launch-limits.test.mjs:10:1
|
||||
✖ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (9.833616ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ error: 'fixture-policy',
|
||||
- error: 'capacity-full',
|
||||
ok: false
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/launch-limits.test.mjs:16:157)
|
||||
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: { ok: false, error: 'fixture-policy' },
|
||||
expected: { ok: false, error: 'capacity-full' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
✖ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (10.352116ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 70.023134
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/launch-limits.test.mjs:10:1
|
||||
✖ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (10.352116ms)
|
||||
TypeError: Cannot read properties of undefined (reading 'scope')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/launch-limits.test.mjs:16:380)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
@@ -0,0 +1,40 @@
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (6.428562ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (1.162907ms)
|
||||
✔ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (155.080638ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 250.781914
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:11:1
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (6.428562ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
models: {
|
||||
anthropic: {
|
||||
+ 'claude-opus-5-5': 0,
|
||||
+ 'claude-sonnet-5-5': 0
|
||||
- 'claude-opus-5-5': 4,
|
||||
- 'claude-sonnet-5-5': 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:17:60)
|
||||
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: { models: { anthropic: [Object] } },
|
||||
expected: { models: { anthropic: [Object] } },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.490496ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.524785ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.125952ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (11.954228ms)
|
||||
✖ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.527138ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (14.785549ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.672131ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.645669ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 119.333516
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:38:1
|
||||
✖ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (3.527138ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:41:729)
|
||||
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: /ambiguous/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (7.802001ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (1.242031ms)
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (31.172331ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 128.142871
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:11:1
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (7.802001ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ '{"businessVersion":1,"id":"acme","human":"jason","arbiters":{"delivery":"pm","technical":"cto"},"projects":{"stack":{"root":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/project"}},"vars":{"tracker.baseUrl":"http://127.0.0.1:3456","gitea.baseUrl":"https://git.example","tracker.pollSeconds":60},"tracker":{"sync":{"bot":"bot-acme-sync","botId":9,"credentials":{"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/sync-vikunja.token","expires":"2099-01-01"}}},"labels":{}},"roles":{"pm":{"definition":"pm","tracker":{"bot":"bot-acme-pm","botId":3},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-vikunja.token","expires":"2099-01-01"}},"holder":"sage","vars":{"harness":"pi","model":"claude-opus-5-5"}},"cto":{"definition":"cto","tracker":{"bot":"bot-acme-cto","botId":4},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-vikunja.token","expires":"2099-01-01"}},"holder":"darkwing","vars":{"harness":"claude-code","model":"claude-opus-5-5"}},"coder":{"definition":"coder","tracker":{"bot":"bot-acme-coder","botId":5},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-vikunja.token","expires":"2099-01-01"}},"vars":{"harness":"pi","limits.network":"none","model":"claude-sonnet-5-5"}},"reviewer":{"definition":"reviewer","tracker":{"bot":"bot-acme-reviewer","botId":6},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-vikunja.token","expires":"2099-01-01"}},"vars":{"model":"claude-opus-5-5"}},"chief":{"definition":"chief-of-staff","vars":{"model":"claude-opus-5-5"}}},"launch":{"by":"chief","instances":["coder","reviewer"],"max":{"opus":4,"sonnet":4}}}'
|
||||
- '{\n' +
|
||||
- ' "businessVersion": 1,\n' +
|
||||
- ' "id": "acme",\n' +
|
||||
- ' "human": "jason",\n' +
|
||||
- ' "arbiters": {\n' +
|
||||
- ' "delivery": "pm",\n' +
|
||||
- ' "technical": "cto"\n' +
|
||||
- ' },\n' +
|
||||
- ' "projects": {\n' +
|
||||
- ' "stack": {\n' +
|
||||
- ' "root": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/project"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "tracker.baseUrl": "http://127.0.0.1:3456",\n' +
|
||||
- ' "gitea.baseUrl": "https://git.example",\n' +
|
||||
- ' "tracker.pollSeconds": 60\n' +
|
||||
- ' },\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "sync": {\n' +
|
||||
- ' "bot": "bot-acme-sync",\n' +
|
||||
- ' "botId": 9,\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/sync-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "labels": {}\n' +
|
||||
- ' },\n' +
|
||||
- ' "roles": {\n' +
|
||||
- ' "pm": {\n' +
|
||||
- ' "definition": "pm",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-pm",\n' +
|
||||
- ' "botId": 3\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "holder": "sage",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "pi",\n' +
|
||||
- ' "model": "claude-opus-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "cto": {\n' +
|
||||
- ' "definition": "cto",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-cto",\n' +
|
||||
- ' "botId": 4\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "holder": "darkwing",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "claude-code",\n' +
|
||||
- ' "model": "claude-opus-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "coder": {\n' +
|
||||
- ' "definition": "coder",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-coder",\n' +
|
||||
- ' "botId": 5\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "harness": "pi",\n' +
|
||||
- ' "limits.network": "none",\n' +
|
||||
- ' "model": "claude-sonnet-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "reviewer": {\n' +
|
||||
- ' "definition": "reviewer",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-acme-reviewer",\n' +
|
||||
- ' "botId": 6\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "model": "claude-opus-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "chief": {\n' +
|
||||
- ' "definition": "chief-of-staff",\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "model": "claude-opus-5-5"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "launch": {\n' +
|
||||
- ' "by": "chief",\n' +
|
||||
- ' "instances": [\n' +
|
||||
- ' "coder",\n' +
|
||||
- ' "reviewer"\n' +
|
||||
- ' ],\n' +
|
||||
- ' "max": {\n' +
|
||||
- ' "opus": 4,\n' +
|
||||
- ' "sonnet": 4\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- '}\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:17:216)
|
||||
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: '{"businessVersion":1,"id":"acme","human":"jason","arbiters":{"delivery":"pm","technical":"cto"},"projects":{"stack":{"root":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/project"}},"vars":{"tracker.baseUrl":"http://127.0.0.1:3456","gitea.baseUrl":"https://git.example","tracker.pollSeconds":60},"tracker":{"sync":{"bot":"bot-acme-sync","botId":9,"credentials":{"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/sync-vikunja.token","expires":"2099-01-01"}}},"labels":{}},"roles":{"pm":{"definition":"pm","tracker":{"bot":"bot-acme-pm","botId":3},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-vikunja.token","expires":"2099-01-01"}},"holder":"sage","vars":{"harness":"pi","model":"claude-opus-5-5"}},"cto":{"definition":"cto","tracker":{"bot":"bot-acme-cto","botId":4},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-vikunja.token","expires":"2099-01-01"}},"holder":"darkwing","vars":{"harness":"claude-code","model":"claude-opus-5-5"}},"coder":{"definition":"coder","tracker":{"bot":"bot-acme-coder","botId":5},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-vikunja.token","expires":"2099-01-01"}},"vars":{"harness":"pi","limits.network":"none","model":"claude-sonnet-5-5"}},"reviewer":{"definition":"reviewer","tracker":{"bot":"bot-acme-reviewer","botId":6},"credentials":{"gitea":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-vikunja.token","expires":"2099-01-01"}},"vars":{"model":"claude-opus-5-5"}},"chief":{"definition":"chief-of-staff","vars":{"model":"claude-opus-5-5"}}},"launch":{"by":"chief","instances":["coder","reviewer"],"max":{"opus":4,"sonnet":4}}}',
|
||||
expected: '{\n "businessVersion": 1,\n "id": "acme",\n "human": "jason",\n "arbiters": {\n "delivery": "pm",\n "technical": "cto"\n },\n "projects": {\n "stack": {\n "root": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/project"\n }\n },\n "vars": {\n "tracker.baseUrl": "http://127.0.0.1:3456",\n "gitea.baseUrl": "https://git.example",\n "tracker.pollSeconds": 60\n },\n "tracker": {\n "sync": {\n "bot": "bot-acme-sync",\n "botId": 9,\n "credentials": {\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/sync-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "labels": {}\n },\n "roles": {\n "pm": {\n "definition": "pm",\n "tracker": {\n "bot": "bot-acme-pm",\n "botId": 3\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/pm-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "holder": "sage",\n "vars": {\n "harness": "pi",\n "model": "claude-opus-5-5"\n }\n },\n "cto": {\n "definition": "cto",\n "tracker": {\n "bot": "bot-acme-cto",\n "botId": 4\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/cto-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "holder": "darkwing",\n "vars": {\n "harness": "claude-code",\n "model": "claude-opus-5-5"\n }\n },\n "coder": {\n "definition": "coder",\n "tracker": {\n "bot": "bot-acme-coder",\n "botId": 5\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/coder-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "vars": {\n "harness": "pi",\n "limits.network": "none",\n "model": "claude-sonnet-5-5"\n }\n },\n "reviewer": {\n "definition": "reviewer",\n "tracker": {\n "bot": "bot-acme-reviewer",\n "botId": 6\n },\n "credentials": {\n "gitea": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/mnt/storage/scratch/tmp/mosaic-cli-C12Oef/secrets/reviewer-vikunja.token",\n "expires": "2099-01-01"\n }\n },\n "vars": {\n "model": "claude-opus-5-5"\n }\n },\n "chief": {\n "definition": "chief-of-staff",\n "vars": {\n "model": "claude-opus-5-5"\n }\n }\n },\n "launch": {\n "by": "chief",\n "instances": [\n "coder",\n "reviewer"\n ],\n "max": {\n "opus": 4,\n "sonnet": 4\n }\n }\n}\n',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:30:1
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (31.172331ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ '{"businessVersion":1,"id":"acme","human":"jason","arbiters":{"delivery":"pm","technical":"cto"},"projects":{"stack":{"root":"/mnt/storage/src/mosaic-stack"}},"vars":{"tracker.baseUrl":"http://127.0.0.1:3456","gitea.baseUrl":"https://git.mosaicstack.dev"},"tracker":{"sync":{"bot":"bot-mosaic-stack-sync","botId":14,"credentials":{"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/sync-vikunja.token","expires":"2099-01-01"}}},"labels":{}},"roles":{"pm":{"definition":"pm","holder":"sage","tracker":{"bot":"bot-mosaic-stack-pm","botId":10},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-vikunja.token","expires":"2099-01-01"}}},"cto":{"definition":"cto","holder":"darkwing","tracker":{"bot":"bot-mosaic-stack-cto","botId":11},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-vikunja.token","expires":"2099-01-01"}}},"coder":{"definition":"coder","tracker":{"bot":"bot-mosaic-stack-coder","botId":12},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-vikunja.token","expires":"2099-01-01"}}},"reviewer":{"definition":"reviewer","tracker":{"bot":"bot-mosaic-stack-reviewer","botId":13},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-vikunja.token","expires":"2099-01-01"}}},"chief":{"definition":"chief-of-staff"},"assistant":{"definition":"assistant","holder":"mos"}},"launch":{"by":"chief","instances":["coder","reviewer"],"max":{"opus":4,"sonnet":4}}}'
|
||||
- '{\n' +
|
||||
- ' "businessVersion": 1,\n' +
|
||||
- ' "id": "acme",\n' +
|
||||
- ' "human": "jason",\n' +
|
||||
- ' "arbiters": {\n' +
|
||||
- ' "delivery": "pm",\n' +
|
||||
- ' "technical": "cto"\n' +
|
||||
- ' },\n' +
|
||||
- ' "projects": {\n' +
|
||||
- ' "stack": {\n' +
|
||||
- ' "root": "/mnt/storage/src/mosaic-stack"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "vars": {\n' +
|
||||
- ' "tracker.baseUrl": "http://127.0.0.1:3456",\n' +
|
||||
- ' "gitea.baseUrl": "https://git.mosaicstack.dev"\n' +
|
||||
- ' },\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "sync": {\n' +
|
||||
- ' "bot": "bot-mosaic-stack-sync",\n' +
|
||||
- ' "botId": 14,\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/sync-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "labels": {}\n' +
|
||||
- ' },\n' +
|
||||
- ' "roles": {\n' +
|
||||
- ' "pm": {\n' +
|
||||
- ' "definition": "pm",\n' +
|
||||
- ' "holder": "sage",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-mosaic-stack-pm",\n' +
|
||||
- ' "botId": 10\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "cto": {\n' +
|
||||
- ' "definition": "cto",\n' +
|
||||
- ' "holder": "darkwing",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-mosaic-stack-cto",\n' +
|
||||
- ' "botId": 11\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "coder": {\n' +
|
||||
- ' "definition": "coder",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-mosaic-stack-coder",\n' +
|
||||
- ' "botId": 12\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "reviewer": {\n' +
|
||||
- ' "definition": "reviewer",\n' +
|
||||
- ' "tracker": {\n' +
|
||||
- ' "bot": "bot-mosaic-stack-reviewer",\n' +
|
||||
- ' "botId": 13\n' +
|
||||
- ' },\n' +
|
||||
- ' "credentials": {\n' +
|
||||
- ' "gitea": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-gitea.token",\n' +
|
||||
- ' "rotateBy": "2099-01-01"\n' +
|
||||
- ' },\n' +
|
||||
- ' "vikunja": {\n' +
|
||||
- ' "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-vikunja.token",\n' +
|
||||
- ' "expires": "2099-01-01"\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "chief": {\n' +
|
||||
- ' "definition": "chief-of-staff"\n' +
|
||||
- ' },\n' +
|
||||
- ' "assistant": {\n' +
|
||||
- ' "definition": "assistant",\n' +
|
||||
- ' "holder": "mos"\n' +
|
||||
- ' }\n' +
|
||||
- ' },\n' +
|
||||
- ' "launch": {\n' +
|
||||
- ' "by": "chief",\n' +
|
||||
- ' "instances": [\n' +
|
||||
- ' "coder",\n' +
|
||||
- ' "reviewer"\n' +
|
||||
- ' ],\n' +
|
||||
- ' "max": {\n' +
|
||||
- ' "opus": 4,\n' +
|
||||
- ' "sonnet": 4\n' +
|
||||
- ' }\n' +
|
||||
- ' }\n' +
|
||||
- '}\n'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:40:302)
|
||||
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: '{"businessVersion":1,"id":"acme","human":"jason","arbiters":{"delivery":"pm","technical":"cto"},"projects":{"stack":{"root":"/mnt/storage/src/mosaic-stack"}},"vars":{"tracker.baseUrl":"http://127.0.0.1:3456","gitea.baseUrl":"https://git.mosaicstack.dev"},"tracker":{"sync":{"bot":"bot-mosaic-stack-sync","botId":14,"credentials":{"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/sync-vikunja.token","expires":"2099-01-01"}}},"labels":{}},"roles":{"pm":{"definition":"pm","holder":"sage","tracker":{"bot":"bot-mosaic-stack-pm","botId":10},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-vikunja.token","expires":"2099-01-01"}}},"cto":{"definition":"cto","holder":"darkwing","tracker":{"bot":"bot-mosaic-stack-cto","botId":11},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-vikunja.token","expires":"2099-01-01"}}},"coder":{"definition":"coder","tracker":{"bot":"bot-mosaic-stack-coder","botId":12},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-vikunja.token","expires":"2099-01-01"}}},"reviewer":{"definition":"reviewer","tracker":{"bot":"bot-mosaic-stack-reviewer","botId":13},"credentials":{"gitea":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-gitea.token","rotateBy":"2099-01-01"},"vikunja":{"file":"/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-vikunja.token","expires":"2099-01-01"}}},"chief":{"definition":"chief-of-staff"},"assistant":{"definition":"assistant","holder":"mos"}},"launch":{"by":"chief","instances":["coder","reviewer"],"max":{"opus":4,"sonnet":4}}}',
|
||||
expected: '{\n "businessVersion": 1,\n "id": "acme",\n "human": "jason",\n "arbiters": {\n "delivery": "pm",\n "technical": "cto"\n },\n "projects": {\n "stack": {\n "root": "/mnt/storage/src/mosaic-stack"\n }\n },\n "vars": {\n "tracker.baseUrl": "http://127.0.0.1:3456",\n "gitea.baseUrl": "https://git.mosaicstack.dev"\n },\n "tracker": {\n "sync": {\n "bot": "bot-mosaic-stack-sync",\n "botId": 14,\n "credentials": {\n "vikunja": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/sync-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "labels": {}\n },\n "roles": {\n "pm": {\n "definition": "pm",\n "holder": "sage",\n "tracker": {\n "bot": "bot-mosaic-stack-pm",\n "botId": 10\n },\n "credentials": {\n "gitea": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/pm-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "cto": {\n "definition": "cto",\n "holder": "darkwing",\n "tracker": {\n "bot": "bot-mosaic-stack-cto",\n "botId": 11\n },\n "credentials": {\n "gitea": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/cto-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "coder": {\n "definition": "coder",\n "tracker": {\n "bot": "bot-mosaic-stack-coder",\n "botId": 12\n },\n "credentials": {\n "gitea": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/coder-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "reviewer": {\n "definition": "reviewer",\n "tracker": {\n "bot": "bot-mosaic-stack-reviewer",\n "botId": 13\n },\n "credentials": {\n "gitea": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-gitea.token",\n "rotateBy": "2099-01-01"\n },\n "vikunja": {\n "file": "/home/you/.config/mosaic-dev/secrets/mosaic-stack/reviewer-vikunja.token",\n "expires": "2099-01-01"\n }\n }\n },\n "chief": {\n "definition": "chief-of-staff"\n },\n "assistant": {\n "definition": "assistant",\n "holder": "mos"\n }\n },\n "launch": {\n "by": "chief",\n "instances": [\n "coder",\n "reviewer"\n ],\n "max": {\n "opus": 4,\n "sonnet": 4\n }\n }\n}\n',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
✖ limits binds actor from human proof and rejects role, reader, tester and forged actor (10.345813ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (28.453453ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (23.005856ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 114.091052
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limits.test.mjs:9:1
|
||||
✖ limits binds actor from human proof and rejects role, reader, tester and forged actor (10.345813ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/tests/limits.test.mjs:13:89)
|
||||
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: /human-required/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
2026-10-15T01:33:35.581Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (13.387284ms)
|
||||
2026-10-15T01:33:35.588Z settings user="jason" changed
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (5.236792ms)
|
||||
✔ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (4.811456ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 106.397024
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-write.test.mjs:12:1
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (5.236792ms)
|
||||
AssertionError [ERR_ASSERTION]: origin
|
||||
|
||||
200 !== 403
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-write.test.mjs:14:361)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 200,
|
||||
expected: 403,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
2026-10-15T01:33:35.742Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (13.367927ms)
|
||||
2026-10-15T01:33:35.748Z settings user="jason" changed
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (4.922937ms)
|
||||
✔ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (4.7993ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 101.859665
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-write.test.mjs:12:1
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (4.922937ms)
|
||||
AssertionError [ERR_ASSERTION]: sec-fetch-site
|
||||
|
||||
200 !== 403
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-write.test.mjs:14:361)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 200,
|
||||
expected: 403,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
2026-10-15T01:33:35.914Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (14.10557ms)
|
||||
2026-10-15T01:33:35.919Z settings user="jason" changed
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (2.524127ms)
|
||||
✔ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (5.601441ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 107.365457
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-write.test.mjs:12:1
|
||||
✖ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (2.524127ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
200 !== 403
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-write.test.mjs:13:40)
|
||||
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: 200,
|
||||
expected: 403,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
2026-10-15T01:33:36.072Z settings user="jason" changed
|
||||
✔ REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation (13.746947ms)
|
||||
✔ REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata (5.546219ms)
|
||||
2026-10-15T01:33:36.082Z settings user="jason" changed
|
||||
✖ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (2.191147ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 101.220115
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-write.test.mjs:16:1
|
||||
✖ REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call (2.191147ms)
|
||||
AssertionError [ERR_ASSERTION]: [object Object]
|
||||
|
||||
200 !== 400
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-write.test.mjs:17:124)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 200,
|
||||
expected: 400,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
✖ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (431.255971ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 516.288563
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-form.test.mjs:8:1
|
||||
✖ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (431.255971ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
0 !== 4
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-form.test.mjs:15: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: 0,
|
||||
expected: 4,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
✖ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (577.488619ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 665.142006
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/webui/tests/settings-form.test.mjs:8:1
|
||||
✖ Settings form shows every scope and held role; gated save, exact payload, retained draft and no automatic retry (577.488619ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
1 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/webui/tests/settings-form.test.mjs:19:279)
|
||||
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: 1,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (7.408132ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (1.100148ms)
|
||||
✔ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (153.602274ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 248.342209
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:11:1
|
||||
✖ migration needs no bus/config, prints whole converted document, is idempotent and never writes (7.408132ms)
|
||||
Error [CliError]: old launch.max must be a JSON object
|
||||
at limitsCommand (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/src/limits.mjs:57:11)
|
||||
at main (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/src/cli.mjs:384:33)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:19:175)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
exitCode: 2
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.766636ms)
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.095582ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.359917ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (13.013003ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.707886ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.550436ms)
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.616908ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (7.633415ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 120.00651
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:17:1
|
||||
✖ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (3.095582ms)
|
||||
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
|
||||
|
||||
assert.ok(limitHit(sessions,'acme',JSON.parse(JSON.stringify(limits).replaceAll(':1',':0')),{provider:'anthropic',model:'opus-exact'}))
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:19:336)
|
||||
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: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:47:1
|
||||
✖ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.616908ms)
|
||||
TypeError: Cannot read properties of null (reading 'running')
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:51:104)
|
||||
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,35 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.667563ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.548458ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (16.900711ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.707934ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.924117ms)
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (10.117938ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.400194ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.324857ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 112.785985
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:43:1
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (10.117938ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
'sonnet' !== 'opus'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:45:154)
|
||||
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: 'sonnet',
|
||||
expected: 'opus',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (8.978541ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (0.528313ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (15.346126ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (12.118657ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.968131ms)
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.876823ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.55368ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (8.296513ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 7
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 119.523215
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/launch-settings.test.mjs:43:1
|
||||
✖ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (15.876823ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'anthropic'
|
||||
- 'proxy'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/tests/launch-settings.test.mjs:45:357)
|
||||
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: 'anthropic',
|
||||
expected: 'proxy',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (15.104107ms)
|
||||
✖ runtime wires verified human settings to the actual shared file writer and actor receipt (16.788074ms)
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (15.495672ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 94.057311
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limits.test.mjs:17:1
|
||||
✖ runtime wires verified human settings to the actual shared file writer and actor receipt (16.788074ms)
|
||||
Error: not-configured
|
||||
at fail (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/src/broker.mjs:76:9)
|
||||
at Broker.request (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/src/broker.mjs:673:34)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/tests/limits.test.mjs:22:24)
|
||||
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) {
|
||||
code: 'not-configured'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/limits.test.mjs:24:1
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (15.495672ms)
|
||||
Error: not-configured
|
||||
at fail (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/src/broker.mjs:76:9)
|
||||
at Broker.request (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/src/broker.mjs:673:34)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/tests/limits.test.mjs:30:118)
|
||||
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) {
|
||||
code: 'not-configured'
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
✔ migration needs no bus/config, prints whole converted document, is idempotent and never writes (8.239232ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (0.95278ms)
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (76.758389ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 171.602302
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:30:1
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (76.758389ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected rejection.
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:44:186)
|
||||
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: /inherited provider\/model/,
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
✔ migration needs no bus/config, prints whole converted document, is idempotent and never writes (8.335756ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (0.956578ms)
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (100.570388ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 196.448552
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:30:1
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (100.570388ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected rejection.
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:44:186)
|
||||
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: /inherited provider\/model/,
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
✔ migration needs no bus/config, prints whole converted document, is idempotent and never writes (8.302574ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (0.957108ms)
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (8.760014ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 102.031685
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/limits.test.mjs:30:1
|
||||
✖ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (8.760014ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected rejection.
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/cli/tests/limits.test.mjs:45:25)
|
||||
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: /system config/,
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (15.046648ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (28.511746ms)
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (10.653404ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 101.148839
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limits.test.mjs:24:1
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (10.653404ms)
|
||||
Error: organization bytes do not match prepared receipt
|
||||
at fail (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:20:9)
|
||||
at recover (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:168:9)
|
||||
at file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:218:68
|
||||
at withLock (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:128:14)
|
||||
at Object.recover (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/business/src/organization.mjs:218:49)
|
||||
at startBroker (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/src/runtime.mjs:39:73)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/tests/limits.test.mjs:29:18)
|
||||
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) {
|
||||
code: 'organization-uncertain'
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (13.59679ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (27.368037ms)
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (16.912643ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 105.568949
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limits.test.mjs:24:1
|
||||
✖ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (16.912643ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///mnt/storage/src/mosaic-stack-rocko-122-r2/packages/bus/tests/limits.test.mjs:30:191)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /organization-uncertain/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
[
|
||||
{
|
||||
"id": "01-whole-document-validation",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "02-atomic-publication",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "03-previous-version",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "04-authenticated-actor",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "05-old-new-receipt",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "06-stale-revision",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "07-uncertain-recovery",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "08-total-limit",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "09-provider-limit",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "10-model-limit",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "11-at-limit",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "12-unset-unlimited",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "13-nonnegative-counts",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "14-no-policy-ceiling",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "15-exact-provider-count",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "16-provider-routing",
|
||||
"path": "packages/harness/src/bundle.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "17-reread-every-launch",
|
||||
"path": "packages/cli/src/launcher.mjs",
|
||||
"test": "packages/cli/tests/launch-limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "18-refusal-hit-logged",
|
||||
"path": "packages/cli/src/launcher.mjs",
|
||||
"test": "packages/cli/tests/launch-limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 3
|
||||
},
|
||||
{
|
||||
"id": "19-migration-preserve-counts",
|
||||
"path": "packages/business/src/migrate-launch.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "20-migration-ambiguity",
|
||||
"path": "packages/business/src/migrate-launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "21-print-only-migration",
|
||||
"path": "packages/cli/src/limits.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "22-human-only-settings",
|
||||
"path": "packages/bus/src/broker.mjs",
|
||||
"test": "packages/bus/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "23-settings-origin",
|
||||
"path": "packages/webui/src/serve.mjs",
|
||||
"test": "packages/webui/tests/settings-write.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 2
|
||||
},
|
||||
{
|
||||
"id": "24-settings-fetch-metadata",
|
||||
"path": "packages/webui/src/serve.mjs",
|
||||
"test": "packages/webui/tests/settings-write.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 2
|
||||
},
|
||||
{
|
||||
"id": "25-settings-send-mode",
|
||||
"path": "packages/webui/src/serve.mjs",
|
||||
"test": "packages/webui/tests/settings-write.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "26-settings-strict-keys",
|
||||
"path": "packages/webui/src/serve.mjs",
|
||||
"test": "packages/webui/tests/settings-write.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "27-form-instances",
|
||||
"path": "packages/webui/src/public/bus.js",
|
||||
"test": "packages/webui/tests/settings-form.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "28-form-limit-payload",
|
||||
"path": "packages/webui/src/public/bus.js",
|
||||
"test": "packages/webui/tests/settings-form.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "29-migration-idempotent",
|
||||
"path": "packages/business/src/migrate-launch.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "30-zero-stops-new",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "31-instance-model-edit",
|
||||
"path": "packages/business/src/launch-settings.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "32-model-table-edit",
|
||||
"path": "packages/business/src/launch-settings.mjs",
|
||||
"test": "packages/business/tests/launch-settings.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "33-runtime-writer-wiring",
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"test": "packages/bus/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "34-inherited-exact-model",
|
||||
"path": "packages/business/src/migrate-launch.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "35-inherited-provider",
|
||||
"path": "packages/business/src/migrate-launch.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "36-config-required",
|
||||
"path": "packages/cli/src/limits.mjs",
|
||||
"test": "packages/cli/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "37-recovery-not-at-start",
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"test": "packages/bus/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
},
|
||||
{
|
||||
"id": "38-uncertain-writes-refuse",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"test": "packages/bus/tests/limits.test.mjs",
|
||||
"result": "KILLED",
|
||||
"exit": 1,
|
||||
"sites": 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"network": "mosaic-stack-rocko-122-r2_default",
|
||||
"present": true,
|
||||
"removeExit": 0
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
bb0f710521162dd7ebfe5cd33a7a5047bf209d702f311c1510ff7c2f88de8056 agents/rocko/work/queue-122/r2/BUILD.md
|
||||
531b41b691bd5def2bdeb44d191a4c7bcc1c3dd5549b3a4168a4c88ff9e3c23a agents/rocko/work/queue-122/r2/MIGRATION.md
|
||||
45bf4f5063ad9b6657fc5aea65ceeaac9d2226468995004bf23ba32524be9be6 agents/rocko/work/queue-122/r2/MUTANTS.md
|
||||
db592d3e2ed154ba9d166b9566912275b441fe18fe4b322ad97d36d790b535a8 agents/rocko/work/queue-122/r2/base-drift.json
|
||||
b9cfe84dc9028b56d554e8f5992ff2f48ea2befad131b9ec8d3e844d2f490c69 agents/rocko/work/queue-122/r2/base.txt
|
||||
5dbb99237f427b5e090e06ebd341c0dda0f7bb7932bfe9cfae421a6ede931ffb agents/rocko/work/queue-122/r2/build.patch
|
||||
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/rocko/work/queue-122/r2/busy-check.log
|
||||
f96467d1db869496c274d0ac92284130f38f60af074af0580eb423eff30355d6 agents/rocko/work/queue-122/r2/busy.py
|
||||
00b84e311475f97ced0d9a9599fba23a28442971ed15d8d489d9422d84a8812e agents/rocko/work/queue-122/r2/candidate-manifest.sha256
|
||||
3536a3ceb0a37b8288c0c90b542421e0299c27773faaad41ad4ccc64a3e37d80 agents/rocko/work/queue-122/r2/gate/pkg-bus.log
|
||||
fedc0e4b5df809f7299ec4e88fad639e3d6a2520a2769a9e5320d984664c66b8 agents/rocko/work/queue-122/r2/gate/pkg-business-before-merge-assertion.log
|
||||
b81c3be328f98efa679c3cb0575dee81f38b11ab23b00b7a4c8ae79129ca677e agents/rocko/work/queue-122/r2/gate/pkg-business.log
|
||||
c37ecd1a95dfabf89d28b746a5fd5b35aa9b5c8c668593dfec491b1744c338d7 agents/rocko/work/queue-122/r2/gate/pkg-cli.log
|
||||
659432d573a93538b0cf0929940b4d65a527aa7d46a5442415c0b25f6b81a523 agents/rocko/work/queue-122/r2/gate/pkg-control-board.log
|
||||
f99012456bb806f20322044f4e1d7470355120fb4f9a432f1a18ec78fcf5fa4b agents/rocko/work/queue-122/r2/gate/pkg-conversation.log
|
||||
4607dde1c0604f42090ccbdd57d1a4f5ee8b78d915f699494a5f2b4ca485060c agents/rocko/work/queue-122/r2/gate/pkg-discord.log
|
||||
d013306ea3db595c430a09054b51b2924bba59dbf83d192511c654207a926902 agents/rocko/work/queue-122/r2/gate/pkg-harness.log
|
||||
5de1782a2ea1410bc232d48fdb20119bc368b372bff9eb0af952a5dc27f9e1f9 agents/rocko/work/queue-122/r2/gate/pkg-ledger.log
|
||||
75c43c62331783379bc2a00d9b233ee7bec4a59a93065de36866834cb7f50855 agents/rocko/work/queue-122/r2/gate/pkg-mosaic.log
|
||||
f3676fd6c682eaa0e31b9253919c6c22d1153ae06130cb7afa90f6fbbbf1d9cb agents/rocko/work/queue-122/r2/gate/pkg-runs.log
|
||||
fce58b9d33b0229a4bc81dc83d1e309c67b0238837955f4720bc8f5931d60980 agents/rocko/work/queue-122/r2/gate/pkg-seat.log
|
||||
6f75cf1401c77a3767d3a8ce6d433db77ab54e1fb2a85756d9c4eb51cc6ddc75 agents/rocko/work/queue-122/r2/gate/pkg-tasks.log
|
||||
8a6ee124a4079b21d777966f497ed8b36acb885b6001090240ac7956caf5215b agents/rocko/work/queue-122/r2/gate/pkg-webui.log
|
||||
c1812c975889f1923fbeefb9f2a0d42b97ffc4f9ed1c0a8279ad1c8567dc3b52 agents/rocko/work/queue-122/r2/gate/results.json
|
||||
f91fc95a173339137f981e24fbf630acfde957e32c3cd71e28304532083c6a77 agents/rocko/work/queue-122/r2/gate/script-auth.log
|
||||
7eae4e340c5c7d1904a5795c65535d2fdae965010448ffb5324338850a89b6ad agents/rocko/work/queue-122/r2/gate/script-conductor.log
|
||||
52d211444489ea729dafc3c9745d4474d9dfd50f41055cbad792424197f04073 agents/rocko/work/queue-122/r2/gate/script-config.log
|
||||
87d2e24ce0be7586e31ea1f2c9ce5618b3127515b3c3cd3893f2a0ed899d5822 agents/rocko/work/queue-122/r2/gate/script-discord.log
|
||||
516597949775cb7e5107d400205ab0a7ce71dc5cb39d54666cd4f0c5a4e0824d agents/rocko/work/queue-122/r2/gate/script-extension-package.log
|
||||
83dfaa21c4e4ad941088efab3f69e87ebd2f6bd3cc72ede938e21dc06da8a34f agents/rocko/work/queue-122/r2/gate/script-foundation.log
|
||||
8e2254aa3e1bb9b205ab72c68273d447c0328c9f156ccba2a46f3a0476468b58 agents/rocko/work/queue-122/r2/gate/script-land-work.log
|
||||
9437ee6c418564a64060fb7a17cc859fbb3d14b2d869fd1eba66535a9ca38686 agents/rocko/work/queue-122/r2/gate/script-queue.log
|
||||
fa832794ee35025fb4559d58d01a270f6bff2eb65e863e9075b797f47fa68545 agents/rocko/work/queue-122/r2/gate/script-release.log
|
||||
ccea37f4ffde1f160dcd1a1864988083a645d974e892065c956b338d0f8c853a agents/rocko/work/queue-122/r2/gate/script-task.log
|
||||
388126342c880d87b330843aedc0cee1b854a006061ab3b7edf5380eb9bfd03f agents/rocko/work/queue-122/r2/gate-run-final.log
|
||||
107efdf0317263fbc0f3672b881624a95871891e72a7e8ec853758184323ac29 agents/rocko/work/queue-122/r2/gate-run.log
|
||||
4be363832d9b8ac0ffca024d51fd4f3764d8a5dee6815063c679c2456bdba45f agents/rocko/work/queue-122/r2/gate.py
|
||||
2a4f540a4139687c22a3e92c61c719a78f39ce94c50ab726c09eddb4beba6ed5 agents/rocko/work/queue-122/r2/jason-migration.patch.json
|
||||
fb0d40fe5820173d6b757dd7a4c0dff58cc0416ad1d9a20f1968fa4570e967a3 agents/rocko/work/queue-122/r2/manifest-check.txt
|
||||
a2b6d6fc1c6e96e01e5711d5f1a6f82845ef645ae7074f58f068c9616acac71e agents/rocko/work/queue-122/r2/migration-map.json
|
||||
473e2afbbd8fa064c07fe1f52bea9c5e8d3e65790636a8f2aaef855c6cd2686b agents/rocko/work/queue-122/r2/mutants/01-whole-document-validation.log
|
||||
2f3275b01c6346d334eef3275ef48f759254ab0169b72906e54e8513278b719a agents/rocko/work/queue-122/r2/mutants/02-atomic-publication.log
|
||||
825ae01a0cdb4008bef27fa05eb2f467b20e78ccd1cbbb7a2cae5a55c21737f8 agents/rocko/work/queue-122/r2/mutants/03-previous-version.log
|
||||
879c3bd2f168b09a1ae6a8305ef79446f0f429d2493f42e8b06b5e483ba8628c agents/rocko/work/queue-122/r2/mutants/04-authenticated-actor.log
|
||||
40b2776addca38cc35c9c45d2ae8e8dc14c9578fb0c690187492818c59e09a3c agents/rocko/work/queue-122/r2/mutants/05-old-new-receipt.log
|
||||
bf0a2e96f4fc05b496d20379afaa05c412f6dcc89300e240a7966d52b26909ce agents/rocko/work/queue-122/r2/mutants/06-stale-revision.log
|
||||
69640677a2581318c78930563936d5be2d008bd5d2f98134bf1aedf38c4115ee agents/rocko/work/queue-122/r2/mutants/07-uncertain-recovery.log
|
||||
72477ef4407e4c95942541f137f2912ca1bf6c76697ddbb1e61a25ada3302407 agents/rocko/work/queue-122/r2/mutants/08-total-limit.log
|
||||
9260ab6d630e4bfabaa31527e3c8d9db0bb770645f5f2242fa9811db5c5524be agents/rocko/work/queue-122/r2/mutants/09-provider-limit.log
|
||||
447c0a5866da54485ed6cf3c558dba3ad21b2627c8ff7261b573caa0f619fcfb agents/rocko/work/queue-122/r2/mutants/10-model-limit.log
|
||||
0600ee028dee241aa65bcfe49833c61d1558b5c11a96c9543b9e689ebd40d0b1 agents/rocko/work/queue-122/r2/mutants/11-at-limit.log
|
||||
b533e199461e71ece289b6458778555cdc82375066b58119a9054e982c9fda6e agents/rocko/work/queue-122/r2/mutants/12-unset-unlimited.log
|
||||
af06e8434fe4ef2f0ab3b196eded904d7662e032d1e055f4cf7d0b9ec38013af agents/rocko/work/queue-122/r2/mutants/13-nonnegative-counts.log
|
||||
09904e73c10bcd52351cb19525d91ffb8f76ef0bba2648d1090ad7351d6cf4cc agents/rocko/work/queue-122/r2/mutants/14-no-policy-ceiling.log
|
||||
19b5d580293372b157d44dafacf5d4596522eb3b514c9de3796877446f0a8857 agents/rocko/work/queue-122/r2/mutants/15-exact-provider-count.log
|
||||
7465aa899a499e6a1cc9766687579ed16c38aafe5168f48d0f07bd910daf5ee0 agents/rocko/work/queue-122/r2/mutants/16-provider-routing.log
|
||||
507a9af140a869bf15b2c5f20a791c3ecb20504f98ebe321a41e2bd0fe999c67 agents/rocko/work/queue-122/r2/mutants/17-reread-every-launch.log
|
||||
ab982e44226bd82ebe979eef55da58d7c5d97f929c1b1a2f845b4fa93de98049 agents/rocko/work/queue-122/r2/mutants/18-refusal-hit-logged.log
|
||||
bf1ea41a779995aebfb2fa7dae581476e647e9659c569a36850de277c175af70 agents/rocko/work/queue-122/r2/mutants/19-migration-preserve-counts.log
|
||||
98d30da778f840fc8507a642ac9c77955ad8ae51fa33b31cc29c7519d2bf0f37 agents/rocko/work/queue-122/r2/mutants/20-migration-ambiguity.log
|
||||
791b1e580e0a787c99526ef0d2b5be0acf7b4649dfa93f1fcd069cda254f607f agents/rocko/work/queue-122/r2/mutants/21-print-only-migration.log
|
||||
a6b0c09284a4d2d0ea7f3e7eeab4bc6622a2606753bf4ddbba4f2b5426084255 agents/rocko/work/queue-122/r2/mutants/22-human-only-settings.log
|
||||
1e14c38ddb3cb8c0a37f825434d9775c5771295c454131a98d67fd3444d19988 agents/rocko/work/queue-122/r2/mutants/23-settings-origin.log
|
||||
9aa378035513913c5903320e95fcc4fc316865d79122c8c7823460541de02624 agents/rocko/work/queue-122/r2/mutants/24-settings-fetch-metadata.log
|
||||
bc9c4de9c0eb6feff417d9f685ac29a52634f333998d4a76c0b4f91285ee5def agents/rocko/work/queue-122/r2/mutants/25-settings-send-mode.log
|
||||
e4664df33033b6ef4ca3b5798d7c05f596f0c8a5998da9fe2606681c851c8e5a agents/rocko/work/queue-122/r2/mutants/26-settings-strict-keys.log
|
||||
295f1ed6289c5d45882903e0cc6fcd494a0d8e99820dbdd2ffad79d1743d33f2 agents/rocko/work/queue-122/r2/mutants/27-form-instances.log
|
||||
10f92f13695bf62e3327810c9cc1a0d54052c3d7bf6b7573e79c67b2b3f7d111 agents/rocko/work/queue-122/r2/mutants/28-form-limit-payload.log
|
||||
77a5972d87caa18a34cd26779165bd76b071315b6bde37c4d05028e456af9ec3 agents/rocko/work/queue-122/r2/mutants/29-migration-idempotent.log
|
||||
de9fb9ff8673fd1e5861d1ad30505b1d0bd691783ec5b6951a5e55044b44a80d agents/rocko/work/queue-122/r2/mutants/30-zero-stops-new.log
|
||||
cce68c449eecd302841569c4e4f1183967fc0567fa477206acc3657d2e13cac7 agents/rocko/work/queue-122/r2/mutants/31-instance-model-edit.log
|
||||
54ccf57b19e69d208ee0baf0aec5e3c186a165cae6af376279643b58024f8d5f agents/rocko/work/queue-122/r2/mutants/32-model-table-edit.log
|
||||
7eb4096dc30619fb9a260d34b511113578733b718dadc9360aa901b4f181825e agents/rocko/work/queue-122/r2/mutants/33-runtime-writer-wiring.log
|
||||
f2753dd534bf34f6d0b76ba6b534f06d3031c5b906711858630753a53db3cbf9 agents/rocko/work/queue-122/r2/mutants/34-inherited-exact-model.log
|
||||
617357df0e008a65a32c2509f30caaa7801e03cafab5d88427383586799d8788 agents/rocko/work/queue-122/r2/mutants/35-inherited-provider.log
|
||||
be178d6e31e0942850ac45ac57654c954cd26eba424db1fc6eed9e4cf821ab6f agents/rocko/work/queue-122/r2/mutants/36-config-required.log
|
||||
edb209f343e530f03f4f82ead6fb63b6492873a85396260cf84519b5eb63961b agents/rocko/work/queue-122/r2/mutants/37-recovery-not-at-start.log
|
||||
0210200910539533a3b4168ef37ef71d144f42b621fa857420afde34c2dc5d8f agents/rocko/work/queue-122/r2/mutants/38-uncertain-writes-refuse.log
|
||||
538c172ce44e776c8b21764f568041aa41eaf702b66f8cd251cc5b75491b3b37 agents/rocko/work/queue-122/r2/mutants/results.json
|
||||
2f03170aa9fadc27f5524fd580485f853034afb02ce76968a6cd4a9a539dd1e9 agents/rocko/work/queue-122/r2/mutants-run.log
|
||||
9f3f6d993f51c7d434aed12b7e0ac2593cc812045b4d88c8e1b35fcc4a26a69c agents/rocko/work/queue-122/r2/mutants.py
|
||||
28d53ac5b3030bf5ad5f40c8a9ef2b8645a4bba7ee9abf579ea299dd0433e945 agents/rocko/work/queue-122/r2/network-cleanup.json
|
||||
3afe4044e547267b64eff28e00cd8f9885718430940007ec8a54ac021f2144b9 agents/rocko/work/queue-122/r2/style-check.json
|
||||
a32bd57c705e63ae1f55596a67bc8a62431addb75f347dc0f1995bad4bce0318 agents/rocko/work/queue-122/r2/sweep.log
|
||||
f31495a2e0fa8a35b57485a142aac17116ed220f7efcb684ad6f26cf143ac484 agents/rocko/work/queue-122/r2/sweep.py
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"organization": {
|
||||
"lines": 219,
|
||||
"over120": []
|
||||
},
|
||||
"launch": {
|
||||
"lines": 89,
|
||||
"over120": []
|
||||
},
|
||||
"migrate-launch": {
|
||||
"lines": 94,
|
||||
"over120": []
|
||||
},
|
||||
"launch-settings": {
|
||||
"lines": 68,
|
||||
"over120": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
{"before": []}
|
||||
{"after": []}
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Sweep only Rocko122 node/chromium processes. Never match another seat/live copy."""
|
||||
import os,pathlib,signal,time,json,sys
|
||||
root='/mnt/storage/src/mosaic-stack-rocko-122-r2'
|
||||
def owned():
|
||||
found=[]
|
||||
for p in pathlib.Path('/proc').glob('[0-9]*'):
|
||||
try:
|
||||
argv=(p/'cmdline').read_bytes().split(b'\0');exe=pathlib.Path(argv[0].decode()).name;cwd=os.readlink(p/'cwd')
|
||||
if exe not in ['node','chromium','chrome','chrome_crashpad_handler']:continue
|
||||
if cwd==root or cwd.startswith(root+'/') or any(root.encode() in a for a in argv):found.append({'pid':int(p.name),'exe':exe,'cwd':cwd})
|
||||
except (OSError,UnicodeError):continue
|
||||
return found
|
||||
before=owned();print(json.dumps({'before':before}))
|
||||
for row in before:
|
||||
try:os.kill(row['pid'],signal.SIGTERM)
|
||||
except ProcessLookupError:pass
|
||||
if before:time.sleep(1)
|
||||
for row in owned():
|
||||
try:os.kill(row['pid'],signal.SIGKILL)
|
||||
except ProcessLookupError:pass
|
||||
if before:time.sleep(.2)
|
||||
after=owned();print(json.dumps({'after':after}));sys.exit(bool(after))
|
||||
Reference in New Issue
Block a user