test: match Claude memory slug normalization under mos-1442
This commit is contained in:
1 parent
e551cd8466
commit
a863015a51
18 files changed
+654
-1
No files matched your search
@@ -0,0 +1,49 @@
|
||||
# Row 304 / Vikunja 590 / Gitea #1811
|
||||
|
||||
Owner Rocko; reviewer Dewey; gate owner Sage. Base c16e943b90ef71ac96cfa5314bbea6040634d14d.
|
||||
Brief docs/plans/2026-10-23_gate-env-rows.md first section, approved exact
|
||||
one-line old-test change under mos-1442 point 1 / sage-3362.
|
||||
|
||||
265 is queued and has no active build, so 304 goes first. Slot requested;
|
||||
no Node, test, queue claim or push before Sage CLEAR.
|
||||
|
||||
Before the edit, run the unchanged whole claude-session.test.mjs with
|
||||
fixture-only HOME, CLAUDE_CONFIG_DIR and scripted API under an underscore
|
||||
TMPDIR and a hyphen TMPDIR. Expected: underscore 9/1 only at the unrestricted
|
||||
memory control (:298), hyphen 10/0. Record both raw results here. Stop for
|
||||
Sage if the installed CLI's mapping differs from [^A-Za-z0-9] -> '-'.
|
||||
|
||||
Only then replace /[/.]/g with /[^A-Za-z0-9]/g on the slug line. Every
|
||||
assertion and every other test line stays byte-identical. No product change.
|
||||
Acceptance is whole file green under mktemp, underscore, and space TMPDIR
|
||||
(if the CLI accepts space); old-regex mutant must fail the :298 assertion
|
||||
under underscore. Run scope and claim wait for Sage's slot grant.
|
||||
|
||||
Use short fixture TMPDIRs under /mnt/storage/scratch/tmp, process groups,
|
||||
explicit TAP and bounded runs. No Docker, browser, suites or live state.
|
||||
Keep token/config paths and real provider access out of every fixture.
|
||||
|
||||
## Evidence, sage-3366 (mos-1442 point 1)
|
||||
|
||||
queue next selected304; claim rev3521, rc0. Base test unchanged until both
|
||||
mapping probes finished. Correct restricted-check citation: :293, not :291.
|
||||
|
||||
| Run | TMPDIR | Exit | Pass/fail/skip |
|
||||
|---|---|---|---|
|
||||
| baseline-underscore | /mnt/storage/scratch/tmp/rk304_OV81Op | 1 | 9/1/0 |
|
||||
| baseline-hyphen | /mnt/storage/scratch/tmp/rk304-UnWJbm | 0 | 10/0/0 |
|
||||
| fixed-mktemp | /mnt/storage/scratch/tmp/rk304yw6LWT | 0 | 10/0/0 |
|
||||
| fixed-underscore | /mnt/storage/scratch/tmp/rk304_MyhpSs | 0 | 10/0/0 |
|
||||
| fixed-space | /mnt/storage/scratch/tmp/rk304 i5d7HA | 0 | 10/0/0 |
|
||||
| M1-old-regex | /mnt/storage/scratch/tmp/rk304_595gfj | 1 | 9/1/0 |
|
||||
|
||||
Baseline underscore and M1 both fail only the named unrestricted positive
|
||||
control at claude-session.test.mjs:298:10, ERR_ASSERTION, missing MARKER-MEMORY.
|
||||
Hyphen baseline is green. This confirms the expected installed-CLI mapping.
|
||||
Space is accepted and passes after the fix. All3 fixed whole-file runs30/0/0;
|
||||
baseline hyphen10/0/0; M1 one assertion kill (whole file9/1/0).0cancellations,
|
||||
0skips throughout. Tests11:05:01Z-11:05:36Z, no unexpected red or retry.
|
||||
Every other source byte, including all assertions, is unchanged, recorded in
|
||||
assertion-preservation.json. Fixed test sha2567690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9.
|
||||
Cwd node/chromium/claude sweep empty; no Docker/browser/suite/live activity.
|
||||
Sage's separate gate and Dewey's review still required; no gate claimed here.
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"allOtherBytesUnchanged": true,
|
||||
"assertionLinesUnchanged": true,
|
||||
"baseSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0",
|
||||
"candidateSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
c16e943b90ef71ac96cfa5314bbea6040634d14d
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/packages/harness/tests/claude-session.test.mjs b/packages/harness/tests/claude-session.test.mjs
|
||||
index bf5cb2d29..d9c45e446 100644
|
||||
--- a/packages/harness/tests/claude-session.test.mjs
|
||||
+++ b/packages/harness/tests/claude-session.test.mjs
|
||||
@@ -269,7 +269,7 @@ test("claude adapter: a directory pin exits 2 before it runs; a pin with a space
|
||||
|
||||
test("claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do", { skip }, async (t) => {
|
||||
const { dir, workspace, env } = await session(t, []);
|
||||
- const slug = realpathSync(workspace).replace(/[/.]/g, "-");
|
||||
+ const slug = realpathSync(workspace).replace(/[^A-Za-z0-9]/g, "-");
|
||||
const plant = {
|
||||
"MARKER-USER": [join(env.HOME, ".claude", "CLAUDE.md"), join(env.CLAUDE_CONFIG_DIR, "CLAUDE.md")],
|
||||
"MARKER-PARENT": [join(dir, "CLAUDE.md")],
|
||||
@@ -0,0 +1 @@
|
||||
7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9 packages/harness/tests/claude-session.test.mjs
|
||||
@@ -0,0 +1 @@
|
||||
packages/harness/tests/claude-session.test.mjs
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,14 @@
|
||||
START baseline-underscore 2026-10-23T11:05:01.371651+00:00 /mnt/storage/scratch/tmp/rk304_OV81Op
|
||||
END {"label": "baseline-underscore", "start": "2026-10-23T11:05:01.371651+00:00", "end": "2026-10-23T11:05:06.998843+00:00", "seconds": 5.627, "exit": 1, "counts": {"tests": 10, "pass": 9, "fail": 1, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_OV81Op", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/baseline-underscore.tap"}
|
||||
START baseline-hyphen 2026-10-23T11:05:07.003823+00:00 /mnt/storage/scratch/tmp/rk304-UnWJbm
|
||||
END {"label": "baseline-hyphen", "start": "2026-10-23T11:05:07.003823+00:00", "end": "2026-10-23T11:05:12.829873+00:00", "seconds": 5.826, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304-UnWJbm", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/baseline-hyphen.tap"}
|
||||
START fixed-mktemp 2026-10-23T11:05:12.834143+00:00 /mnt/storage/scratch/tmp/rk304yw6LWT
|
||||
END {"label": "fixed-mktemp", "start": "2026-10-23T11:05:12.834143+00:00", "end": "2026-10-23T11:05:18.560124+00:00", "seconds": 5.726, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304yw6LWT", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-mktemp.tap"}
|
||||
START fixed-underscore 2026-10-23T11:05:18.564553+00:00 /mnt/storage/scratch/tmp/rk304_MyhpSs
|
||||
END {"label": "fixed-underscore", "start": "2026-10-23T11:05:18.564553+00:00", "end": "2026-10-23T11:05:24.340312+00:00", "seconds": 5.776, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_MyhpSs", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-underscore.tap"}
|
||||
START fixed-space 2026-10-23T11:05:24.344312+00:00 /mnt/storage/scratch/tmp/rk304 i5d7HA
|
||||
END {"label": "fixed-space", "start": "2026-10-23T11:05:24.344312+00:00", "end": "2026-10-23T11:05:30.170101+00:00", "seconds": 5.826, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304 i5d7HA", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-space.tap"}
|
||||
START M1-old-regex 2026-10-23T11:05:30.173937+00:00 /mnt/storage/scratch/tmp/rk304_595gfj
|
||||
END {"label": "M1-old-regex", "start": "2026-10-23T11:05:30.173937+00:00", "end": "2026-10-23T11:05:36.100361+00:00", "seconds": 5.926, "exit": 1, "counts": {"tests": 10, "pass": 9, "fail": 1, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_595gfj", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/M1-old-regex.tap"}
|
||||
BUILD_GREEN 2026-10-23T11:05:36.103508+00:00
|
||||
CWD_SWEEP []
|
||||
@@ -0,0 +1,99 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 810.176546
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 503.543336
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 915.865915
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.807726
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 15.271577
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.309932
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
not ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 888.601244
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r304/packages/harness/tests/claude-session.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
'MARKER-USER',
|
||||
'MARKER-PARENT',
|
||||
'MARKER-WS',
|
||||
- 'MARKER-MEMORY'
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
3: 'MARKER-MEMORY'
|
||||
actual:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r304/packages/harness/tests/claude-session.test.mjs:298:10)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 9.250346
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1764.786892
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 871.328606
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 9
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5870.59342
|
||||
@@ -0,0 +1,70 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 780.047981
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 503.370776
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 848.822885
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.629499
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 15.371187
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.545444
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 947.229815
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.467575
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1738.629452
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 857.865121
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 10
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5790.544695
|
||||
@@ -0,0 +1,100 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 748.693342
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 499.864544
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 829.415272
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.710643
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 14.085981
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 4.998474
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
not ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 863.150735
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r304/packages/harness/tests/claude-session.test.mjs:270:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
'MARKER-USER',
|
||||
'MARKER-PARENT',
|
||||
'MARKER-WS',
|
||||
- 'MARKER-MEMORY'
|
||||
]
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
3: 'MARKER-MEMORY'
|
||||
actual:
|
||||
0: 'MARKER-USER'
|
||||
1: 'MARKER-PARENT'
|
||||
2: 'MARKER-WS'
|
||||
operator: 'deepStrictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r304/packages/harness/tests/claude-session.test.mjs:298:10)
|
||||
process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.695573
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1671.315421
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 823.801717
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 9
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5552.702962
|
||||
@@ -0,0 +1,70 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 822.315273
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 473.785584
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 834.093184
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.587717
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 15.598032
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.369426
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 831.362199
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.237071
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1687.124498
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 884.665674
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 10
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5663.888591
|
||||
@@ -0,0 +1,70 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 740.530837
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 484.250736
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 857.991709
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 5.19059
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 16.380045
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.47195
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 869.204192
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.011154
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1760.816087
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 951.447392
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 10
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5778.476849
|
||||
@@ -0,0 +1,70 @@
|
||||
TAP version 13
|
||||
# Subtest: claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
ok 1 - claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist
|
||||
---
|
||||
duration_ms: 766.913918
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: the hook alone blocks a path outside the workspace
|
||||
ok 2 - claude: the hook alone blocks a path outside the workspace
|
||||
---
|
||||
duration_ms: 496.038436
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a second turn resumes the first turn's session
|
||||
ok 3 - claude: a second turn resumes the first turn's session
|
||||
---
|
||||
duration_ms: 839.816577
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: --restricted is always passed
|
||||
ok 4 - claude adapter: --restricted is always passed
|
||||
---
|
||||
duration_ms: 4.571987
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
ok 5 - claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable
|
||||
---
|
||||
duration_ms: 17.17544
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
ok 6 - claude adapter: a directory pin exits 2 before it runs; a pin with a space runs
|
||||
---
|
||||
duration_ms: 5.448032
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
ok 7 - claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do
|
||||
---
|
||||
duration_ms: 873.897762
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: a missing hook or MCP file refuses before claude starts
|
||||
ok 8 - claude: a missing hook or MCP file refuses before claude starts
|
||||
---
|
||||
duration_ms: 8.282957
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
ok 9 - claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after
|
||||
---
|
||||
duration_ms: 1738.792709
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
ok 10 - claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers
|
||||
---
|
||||
duration_ms: 863.908172
|
||||
type: 'test'
|
||||
...
|
||||
1..10
|
||||
# tests 10
|
||||
# suites 0
|
||||
# pass 10
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 5704.886282
|
||||
@@ -0,0 +1,16 @@
|
||||
0b487adf165fb6b83e9cba38fc49167c6ec54b66261d955052f7ee5a877fde07 BUILD.md
|
||||
a75846e9e3217b524ad09bb423033975da6c44074d8d74dc14193550ec1666b9 assertion-preservation.json
|
||||
5ddf1af4e2d23bc579e6a4005c2b355794dcc33fbd29c0421a6d1e9ca60f70ec base.txt
|
||||
85dc6f969a11d933b04cc7b2fe49199d745029779c66bf1815f549c51ec91568 build.patch
|
||||
a09b498872aaf4f3b3af9b297d839d4ddb6fdc57d7a01f05cc1a48200c30cfd4 candidate-manifest.sha256
|
||||
8588e890cdfadd6911fd3b473aad3ff826f6dd91a52e8d10aeb4a28f7929d995 changed-paths.txt
|
||||
37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570 cwd-sweep.json
|
||||
767c5c04bc6442bb6efc8de3bf86e5ef8d2bbdd90d20d72fd604d18e69290f91 driver.log
|
||||
f6f8a66ccc0c025782cc6932de9745720ca7574a0376d6122074275332abaf43 logs/M1-old-regex.tap
|
||||
dc290774a454c85033fdc8c71226f7cd56a07e52106b2868ca91ca5ea652ddca logs/baseline-hyphen.tap
|
||||
960114150fbf0a3069762d356b6cffe0068208a69e805bb0422de0da8825af35 logs/baseline-underscore.tap
|
||||
1d0836115cdf344e7cdcbe1ef9de7a3f2e57ca06a4cca42a07adb14ba82bd29a logs/fixed-mktemp.tap
|
||||
a69191da6fd3eb20ec99b92521df9418e9815b7879a159cc7b2abbd5b790261c logs/fixed-space.tap
|
||||
9776e07a392bc567609573a66a2a17619ded0863b8ee35cbc53482e42c58220b logs/fixed-underscore.tap
|
||||
3adeed328506abdeff0bb108ac16d306736e2caba1c8188d48173e5ea75b5c81 results.jsonl
|
||||
084a848241bf874a5873a881d2c47efd29deff7b6682947fc7738053556845d0 run-build.py
|
||||
@@ -0,0 +1,6 @@
|
||||
{"label": "baseline-underscore", "start": "2026-10-23T11:05:01.371651+00:00", "end": "2026-10-23T11:05:06.998843+00:00", "seconds": 5.627, "exit": 1, "counts": {"tests": 10, "pass": 9, "fail": 1, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_OV81Op", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/baseline-underscore.tap"}
|
||||
{"label": "baseline-hyphen", "start": "2026-10-23T11:05:07.003823+00:00", "end": "2026-10-23T11:05:12.829873+00:00", "seconds": 5.826, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304-UnWJbm", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/baseline-hyphen.tap"}
|
||||
{"label": "fixed-mktemp", "start": "2026-10-23T11:05:12.834143+00:00", "end": "2026-10-23T11:05:18.560124+00:00", "seconds": 5.726, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304yw6LWT", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-mktemp.tap"}
|
||||
{"label": "fixed-underscore", "start": "2026-10-23T11:05:18.564553+00:00", "end": "2026-10-23T11:05:24.340312+00:00", "seconds": 5.776, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_MyhpSs", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-underscore.tap"}
|
||||
{"label": "fixed-space", "start": "2026-10-23T11:05:24.344312+00:00", "end": "2026-10-23T11:05:30.170101+00:00", "seconds": 5.826, "exit": 0, "counts": {"tests": 10, "pass": 10, "fail": 0, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304 i5d7HA", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "7690a4a945e45f5606633d36a3db9a160892be9d125d40351cd848f5bf3ea9c9", "skips": [], "log": "agents/rocko/work/queue-304/logs/fixed-space.tap"}
|
||||
{"label": "M1-old-regex", "start": "2026-10-23T11:05:30.173937+00:00", "end": "2026-10-23T11:05:36.100361+00:00", "seconds": 5.926, "exit": 1, "counts": {"tests": 10, "pass": 9, "fail": 1, "cancelled": 0, "skipped": 0}, "tmpdir": "/mnt/storage/scratch/tmp/rk304_595gfj", "head": "c16e943b90ef71ac96cfa5314bbea6040634d14d", "testSha256": "3a43f134d334e985e6dd50f641a7c1788de29beb86e2f9e2ac7f0ceaf924a8e0", "skips": [], "log": "agents/rocko/work/queue-304/logs/M1-old-regex.tap"}
|
||||
@@ -0,0 +1,66 @@
|
||||
from pathlib import Path
|
||||
import subprocess,os,signal,re,json,hashlib,time
|
||||
from datetime import datetime,timezone
|
||||
ROOT=Path(__file__).resolve().parents[4];P=Path(__file__).resolve().parent;O=P/'logs';O.mkdir(exist_ok=True)
|
||||
FILE='packages/harness/tests/claude-session.test.mjs';source=ROOT/FILE
|
||||
BASE='c16e943b90ef71ac96cfa5314bbea6040634d14d'
|
||||
old='realpathSync(workspace).replace(/[/.]/g, "-")';new='realpathSync(workspace).replace(/[^A-Za-z0-9]/g, "-")'
|
||||
original=source.read_bytes();assert original.decode().count(old)==1
|
||||
fixed=original.decode().replace(old,new,1).encode()
|
||||
rows=[];temps=[]
|
||||
def stamp():return datetime.now(timezone.utc).isoformat()
|
||||
def verify(data):
|
||||
assert subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip()==BASE
|
||||
assert source.read_bytes()==data
|
||||
|
||||
def run(label,template,data):
|
||||
verify(data);tmp=subprocess.check_output(['mktemp','-d',template],text=True).strip();temps.append(tmp)
|
||||
env=os.environ.copy();env.update(TMPDIR=tmp,DOCKER_HOST='unix:///mnt/storage/scratch/rocko-r304-dead.sock',NO_COLOR='1');env.pop('MOSAIC_GITEA_CREDENTIAL_FILE',None);env.pop('MOSAIC_LIVE_PROVIDER',None)
|
||||
args=['timeout','-k','10','180','node','--test','--test-reporter=tap',FILE];log=O/(label+'.tap');start=stamp();begin=time.monotonic()
|
||||
print('START',label,start,tmp,flush=True)
|
||||
with log.open('wb') as f:
|
||||
child=subprocess.Popen(args,cwd=ROOT,env=env,stdout=f,stderr=subprocess.STDOUT,start_new_session=True)
|
||||
try:rc=child.wait(timeout=195)
|
||||
except subprocess.TimeoutExpired:
|
||||
os.killpg(child.pid,signal.SIGKILL);child.wait();rc=124
|
||||
finally:
|
||||
try:os.killpg(child.pid,signal.SIGTERM)
|
||||
except ProcessLookupError:pass
|
||||
text=log.read_text(errors='replace');counts={k:int(m[-1]) if (m:=re.findall(r'^# '+k+r' (\d+)\s*$',text,re.M)) else None for k in ['tests','pass','fail','cancelled','skipped']}
|
||||
row=dict(label=label,start=start,end=stamp(),seconds=round(time.monotonic()-begin,3),exit=rc,counts=counts,tmpdir=tmp,head=BASE,testSha256=hashlib.sha256(data).hexdigest(),skips=[x for x in text.splitlines() if re.search(r'^skip\b|# SKIP\b',x,re.I)],log=str(log.relative_to(ROOT)))
|
||||
rows.append(row)
|
||||
with (P/'results.jsonl').open('a') as f:f.write(json.dumps(row)+'\n')
|
||||
print('END',json.dumps(row),flush=True)
|
||||
assert rc not in [124,137,-9] and 'SyntaxError:' not in text,'invalid run '+label
|
||||
verify(data);return row,text
|
||||
|
||||
def red(label,template,data):
|
||||
r,t=run(label,template,data)
|
||||
assert r['exit']!=0 and r['counts']['tests']==10 and r['counts']['pass']==9 and r['counts']['fail']==1 and r['counts']['cancelled']==0 and r['counts']['skipped']==0,'unexpected red counts '+label
|
||||
names=re.findall(r'^not ok \d+ - (.*)$',t,re.M)
|
||||
assert len(names)==1 and "CLAUDE.md files and auto-memory" in names[0] and ':298:10' in t and 'ERR_ASSERTION' in t and 'MARKER-MEMORY' in t,'unexpected red '+label
|
||||
|
||||
def green(label,template,data):
|
||||
r,t=run(label,template,data)
|
||||
assert r['exit']==0 and r['counts']['tests']==10 and r['counts']['pass']==10 and r['counts']['fail']==0 and r['counts']['cancelled']==0 and r['counts']['skipped']==0,'unexpected mapping/refusal '+label
|
||||
|
||||
try:
|
||||
red('baseline-underscore','/mnt/storage/scratch/tmp/rk304_XXXXXX',original)
|
||||
green('baseline-hyphen','/mnt/storage/scratch/tmp/rk304-XXXXXX',original)
|
||||
# Both installed-CLI probes now confirm the approved mapping before editing.
|
||||
source.write_bytes(fixed)
|
||||
green('fixed-mktemp','/mnt/storage/scratch/tmp/rk304XXXXXX',fixed)
|
||||
green('fixed-underscore','/mnt/storage/scratch/tmp/rk304_XXXXXX',fixed)
|
||||
green('fixed-space','/mnt/storage/scratch/tmp/rk304 XXXXXX',fixed)
|
||||
source.write_bytes(original)
|
||||
try:red('M1-old-regex','/mnt/storage/scratch/tmp/rk304_XXXXXX',original)
|
||||
finally:source.write_bytes(fixed)
|
||||
verify(fixed);print('BUILD_GREEN',stamp(),flush=True)
|
||||
finally:
|
||||
found=[]
|
||||
for proc in Path('/proc').glob('[0-9]*'):
|
||||
try:
|
||||
name=(proc/'comm').read_text().strip();cwd=str((proc/'cwd').resolve())
|
||||
if any(x in name for x in ['node','chrom','claude']) and any(cwd==r or cwd.startswith(r+'/') for r in [str(ROOT),*temps]):found.append(dict(pid=int(proc.name),name=name,cwd=cwd))
|
||||
except (FileNotFoundError,PermissionError,ProcessLookupError):pass
|
||||
(P/'cwd-sweep.json').write_text(json.dumps(found,indent=2)+'\n');print('CWD_SWEEP',found,flush=True)
|
||||
@@ -269,7 +269,7 @@ test("claude adapter: a directory pin exits 2 before it runs; a pin with a space
|
||||
|
||||
test("claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do", { skip }, async (t) => {
|
||||
const { dir, workspace, env } = await session(t, []);
|
||||
const slug = realpathSync(workspace).replace(/[/.]/g, "-");
|
||||
const slug = realpathSync(workspace).replace(/[^A-Za-z0-9]/g, "-");
|
||||
const plant = {
|
||||
"MARKER-USER": [join(env.HOME, ".claude", "CLAUDE.md"), join(env.CLAUDE_CONFIG_DIR, "CLAUDE.md")],
|
||||
"MARKER-PARENT": [join(dir, "CLAUDE.md")],
|
||||
|
||||
Reference in new issue
Block a user