Compare commits

...
10 changed files with 416 additions and 6 deletions

No files matched your search

@@ -0,0 +1,47 @@
{
"authority": "mos-1409 via sage-3181",
"base": "4a9c536e8",
"path": "packages/cli/tests/case1-accept.test.mjs",
"old_line_replacements": [
{
"old": " if(fault==='inner')assert.ok(probeSeconds>=1.25&&probeSeconds<2.75,`${mode}: probe ${probeSeconds}s after baseline ${baselineSeconds}s`);",
"new": " if(fault==='inner')assert.ok(probeSeconds>=1.25&&probeSeconds<2.75,`${mode}: direct probe ${probeSeconds}s; baseline ${baselineSeconds}s is diagnostic only`);",
"change": "diagnostic message only; numeric comparisons and strictness unchanged"
},
{
"old": " assert.ok(probeSeconds>=3.25&&probeSeconds<4.75,`${mode}: probe ${probeSeconds}s after baseline ${baselineSeconds}s`);",
"new": " assert.ok(probeSeconds>=3.25&&probeSeconds<4.75,`${mode}: direct probe ${probeSeconds}s; baseline ${baselineSeconds}s is diagnostic only`);",
"change": "diagnostic message only; numeric comparisons and strictness unchanged"
},
{
"old": " const probeSeconds=seconds-baselineSeconds;",
"new": " let probeSeconds=seconds;\n if(timingFile)assert.doesNotThrow(()=>{probeSeconds=readProbeSeconds(read(timingFile));},'P10 observer pair is required');",
"change": "approved observer plumbing or probeSeconds source"
},
{
"old": "function run(h, extra = {}, argv = [\"--business\", \"mosaic-stack\", \"--args\", \"/etc/mosaic-stack/dev.args\", \"--claude-pin\", CLAUDE_PIN, \"--node-pin\", NODE_PIN, \"--root\", h.root]) {",
"new": "function run(h, extra = {}, argv = [\"--business\", \"mosaic-stack\", \"--args\", \"/etc/mosaic-stack/dev.args\", \"--claude-pin\", CLAUDE_PIN, \"--node-pin\", NODE_PIN, \"--root\", h.root], script = SCRIPT) {",
"change": "approved observer plumbing or probeSeconds source"
},
{
"old": " const r = spawnSync(SCRIPT, argv, {",
"new": " const r = spawnSync(script, argv, {",
"change": "approved observer plumbing or probeSeconds source"
},
{
"old": " const start=performance.now(),r=run(h),seconds=(performance.now()-start)/1000;capture();",
"new": " const start=performance.now(),r=run(h,timingFile?{ROW299_TIMING_FILE:timingFile}:{},undefined,observedScript),seconds=(performance.now()-start)/1000;capture();",
"change": "fault run selects private copy only for inner/outer; default SCRIPT and overflow remain"
}
],
"only_removed_assertion_lines_are_two_diagnostic_messages": true,
"numeric_bands_unchanged": {
"inner": "[1.25,2.75)",
"outer": "[3.25,4.75)"
},
"baseline_status_and_clean_session_lines_byte_identical": true,
"all_other_original_assertion_lines_preserved": true,
"guard_7000_unchanged": true,
"new_assertions": "copy reversal, observer variable isolation, stream/status/EXIT preservation, strict records, required pair",
"runtime_status": "NOT RUN; no Node or test until CLEAR"
}
+28
View File
@@ -0,0 +1,28 @@
{
"row": 299,
"issue": 1806,
"vikunja": 573,
"base": "4a9c536e861f1d9f9a018019b3ac4519d65eccf0",
"branch": "gander/row299-p10",
"status": "IMPLEMENTED STATIC; source 1ec2b9765; no Node/test/push",
"authority": "mos-1409, sage-3181; Filbert implementation review pending",
"files": [
{
"path": "packages/cli/tests/case1-accept.test.mjs",
"git_blob": "c196b40981056963ed924a09f649cfe8e99b34c6",
"sha256": "1e8af0656707d93dedade923bf60556022dc7121c43761876a5d7e02731c14aa"
},
{
"path": "packages/cli/tests/case-sudo-fixture.mjs",
"git_blob": "866c6c0d229a1fc1e9401ee8bb5522ac8cb01ebc",
"sha256": "eac5c83f43056bdeb5781101307e17d4bc01f03e97e02f4f5e930436d7e43535"
},
{
"path": "scripts/case1-accept.sh",
"git_blob": "05cb249ea2217d1a542438b597d382669acf8a9b",
"sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2"
}
],
"source": "1ec2b97650849b90f41a8e1d1190f609de312d49",
"execution": "HELD for Sage CLEAR; no stress process; ambient load >=4 is target only"
}
+92
View File
@@ -0,0 +1,92 @@
# Row 299 / Vikunja 573: direct P10 timing
> Execution method: Gander implements inline after Mos's old-test ruling and Filbert's static read. No delegation. Static implementation authorized by mos-1409 / sage-3181. Every runtime step remains held for CLEAR.
**Goal:** Measure whether P10 takes its two-second inner path or four-second outer path under load, without subtracting unrelated work from another run.
**Architecture:** Add a test helper that makes a private, instrumented copy of the current acceptance script. Two root-side observer statements bracket only the P10 capture's actual bounded wait. Read a complete monotonic begin/end pair from a separate fixture file, while all existing refusal, residual and cleanup assertions still examine the real acceptance output.
**Tech stack:** Existing Node test runner, Bash builtins, Linux /proc/uptime. No new package, interpreter, product hook or live host action.
**Spec:** docs/plans/2026-10-23_mvp-readiness-rows.md, "Brief: 573, the P10 hop band"; sage-3175. Base 4a9c536e8, branch gander/row299-p10. Reviewer Filbert; gate owner Sage. Row 293 is done. Queue claim is held because it executes Node, forbidden in the present slot.
## Constraints and current status
- Static implementation only, authorized by mos-1409. No Node, tests, HTTPS Git, queue call or push has run for 299. No production edit.
- Mos approved the measurement semantics in mos-1409 via sage-3181 under mos-1272. The numeric bands stay unchanged.
- All script/supervisor bytes, 2/4-second budgets, 128-byte cap, exact reason assertions, no-observed assertion, hop residual assertion and cleanup assertions remain authoritative.
- Keep the same healthy baseline status and `baseline leaves no session` assertions. It may remain as an independent healthy control and diagnostic; it no longer supplies the clock value being asserted.
- No extra retry, smoothing, percentile selection, ignored red, clock fallback, or widened band. Missing clock evidence fails.
- Tests use a short TMPDIR directly under /mnt/storage/scratch/tmp/gXXXXXX, never /tmp. No live units, ports, credentials or instance state.
## Source of the band and evidence
1. The original row 253 test timed the full acceptance run. Row 276 exposed it after adding stdout spooling: the old inner `<4 s` whole-run bound already failed 2/5 before that delta and 5/5 after it. Mos's mos-1350 ruled that tests 9 and 10 must measure the probe's cost, offering probe stamps or a same-mode no-fault baseline. See agents/gander/work/queue-276/BUILD.md:120-145 and ASSERTION-PRESERVATION.json.
2. We chose baseline subtraction in 135bb8fae (original source 6f8c5653a). e06130fc0 added the required clean baseline check. Current test lines 371-388 measure two separate full runs and compute `probeSeconds=seconds-baselineSeconds`.
3. The adopted windows are inner [1.25,2.75) and outer [3.25,4.75): 0.75 s around the configured 2/4 s budgets, with 0.5 s between windows. Duckworth-0218 accepted them; the isolated proof in queue-276/BUILD.md reported inner exec 2.033..2.171, inner hop 2.055..2.135, outer exec 3.758..3.961, outer hop 3.736..3.911. Those are historical evidence, not a new run or carried result.
4. The recorded failure is agents/gizmoduck/work/queue-270/BUILD.md:629-636: run 3 on 53406f3e4 had CLI 904/905, inner hop estimate 1.08 below 1.25. The file was unchanged. Its isolated whole rerun passed 50/50 at load 3.19 (mos-1367). No other seat's scratch has been read for this packet.
5. Production is scripts/case1-accept.sh:744, `tester_capture 2 4 128`. Its inner timer is after the uid drop; its outer timeout is started at :238 and waited at :244. The capture validates tools and creates its private files at :233-235, before the timer is armed. Exact refusal mapping is :224-229. The stalled-supervisor case remains an explicit same-uid residual.
Static mechanism: let H be the healthy probe cost, I the true faulty wait and U the rest of the full run, including scheduling delays. The current estimate is `(I + U_fault) - (H + U_baseline)`. It contains `U_fault-U_baseline-H`, so it can underestimate I when the baseline gets more delay. The 1.08 report is consistent with that mechanism; we do not invent the separate component timings absent from the committed record. A direct bracket removes the unrelated subtraction; execution must still establish its margins under the agreed load.
## Approaches considered
- Repeat baselines or use a median: reduces some noise but still subtracts two unrelated schedules and adds work to every whole-file gate. Reject as the fix.
- Stamp in the peer Python or sudo fake: the inner/outer timer is already armed before a delayed child reaches the stamp, so it can measure only the remaining budget and undercount again. Reject.
- **Recommend a direct root-side bracket in a private script copy.** Begin immediately before the actual outer timeout launch, after validation; end immediately after its wait, before unrelated post-checks. Includes sudo dispatch, the inner wait and its cleanup, or the outer timeout. Excludes preceding functional checks, the healthy run, metadata work before capture, and tool-validation cost. It measures the same timing distinction, using both existing fake sudo modes.
Mos approved this approach in mos-1409. Timing still includes kernel scheduling and inner cleanup. Arbitrary starvation cannot be given a hard wall-time guarantee; an overshoot remains a red for placement, not permission to retune.
## Proposed files and interfaces
- New packages/cli/tests/case-p10-timing-fixture.mjs: `instrumentP10Probe(source)` returns a copy of the current script with exactly two observer blocks; `readProbeSeconds(text)` returns `(end-begin)` in seconds from two validated centisecond readings.
- Existing packages/cli/tests/case1-accept.test.mjs: an optional script-path argument to run(), defaulting to SCRIPT for every current caller. Only inner/outer P10 fault runs execute the private copy. The baseline still uses SCRIPT. Overflow stays on SCRIPT and unchanged.
- agents/gander/work/queue-299/: plan, assertion-preservation record, manifest, raw logs, load/timing receipts and mutant records after authorization. No production path in the candidate manifest.
Observer details:
1. Locate exactly one `tester_capture() (` function, scoped before the unique row276-legacy marker. Each insertion anchor must occur once within that slice. Never apply an unscoped global replace.
2. Just before :238 and just after :244, use shell `read` on /proc/uptime plus `printf` to append `begin <uptime>` / `end <uptime>` to ROW299_TIMING_FILE, only when `maximum` is 128. Selecting the existing probe cap, rather than the 2/4 budgets, keeps the observer active when a timer mutant changes a budget. Config query uses 4096 and emits no probe pair.
3. Read and printf are Bash builtins: no new process or Python/Node startup inside the timed span. Preserve `$rc` and every original command, redirection and heredoc byte. Do not emit observer bytes on stdout/stderr. The file is private fixture evidence, not a product authority channel.
4. The copy retains the original absolute /proc reads and the --root fixture seam. The script has no relative self-path imports. Write the copy under h.dir with executable mode and pass the private timing path only to that run. No product script is rewritten.
5. Reverse the two recorded insertions and assert byte equality with freshly read SCRIPT. This applies to the current script, including a deliberately mutated source, rather than a stale frozen healthy copy. The same source/copy comparison and unique anchors fail closed on drift.
6. Parser requires exactly one newline-terminated begin and end pair, in that order, each `<integer>.<two digits>`, and end strictly above begin. No extra pair, missing value, NaN or negative interval is accepted. Use integer centiseconds before converting to seconds. A 10 ms clock resolution is much smaller than the existing 0.5 s window gap.
7. Keep inner [1.25,2.75) and outer [3.25,4.75) exactly. Change only the source of probeSeconds and its diagnostic description. Preserve every existing status/reason/no-observed/residual/cleanup assertion, including the healthy baseline checks. The existing 7 s fixture safety guard stays unchanged and remains cleanup only, never proof of an outer timeout. If it intervenes or masks a measurement, stop for Sage/Mos; do not silently extend it.
## Review focus
- A delayed healthy baseline cannot change the measured interval: it is diagnostic only. No baseline value enters readProbeSeconds or a timing assertion.
- A child delayed after timer arming is not used as the start observer. The begin read precedes timer launch in the root-side capture copy.
- Missing/duplicated/reversed records fail before a band assertion. Add named observer-record tests; no fallback to the old arithmetic.
- A timer mutant reaches the actual observer copy. Source reconstruction and cap-based selection prevent budgets changed to 1/3 seconds from disabling observation.
- Observer code must not change stdout, refusal status, cleanup or trust. Preserve original source bytes by inverse comparison and all original non-timing assertion lines by an assertion-preservation receipt.
## Implementation and evidence sequence (held)
- [x] Proposal sent in gander-0183; mos-1409 / sage-3181 approve the measurement change. Filbert accepts the observation points and supplies implementation checks I1-I5.
- [x] Source 1ec2b9765 adds the helper and observer wiring, plus source/variable, streams/status/trap, and record-validation tests. ASSERTION-PRESERVATION.json lists all six old line replacements; only two original assertion messages change. No runtime or syntax claim.
- [ ] Static review on the committed candidate and manifest. Prove scripts/case1-accept.sh and scripts/case2-unit.sh are byte-identical to the approved base, and no unrelated assertion moved. Finalize all mutant anchors with exactly-one checks.
- [ ] On Sage CLEAR, first record a passing named base for each killer and then M1-M6 from MUTANT-PLAN.json. Report the actual assertion killed. Every restore is byte-identical and git status is checked. A timeout or survivor stops for placement, not a kill.
- [ ] Run case1-accept.test.mjs whole at least three times under load, then CLI whole, as the brief requires. Record ambient load at each of the three starts and throughout each file; >=4 is a target, never a wait condition (mos-1409). No stress process. The whole CLI suite is the required loaded proof; record its load and all exec/hop direct intervals, plus min/max. Do not hold the slot for load.
- [ ] Record all timeout limits before launch: per-node-file timeout -k 10; use at least ceil(3x longest receipt)+120, with 900 s for an unknown file. Whole case1 gets 1200 s from the row293 receipt; stack-release 2400 s from its 683.647 s historical receipt; recheck measured maxima before the current gate. Print the full CLI file list and run the package whole with its normal test-file concurrency, so the suite itself supplies the required loaded proof. Use timeout -k 10 5400 around that whole invocation: 3x the row293 1367.764 s CLI receipt plus 120 is 4224 s, below 5400. TMPDIR is fresh short scratch. No runs are authorized now.
- [ ] Any old-test red, reason mismatch, fixture-guard intervention, timeout, or survivor goes to Sage/Mos before edits or retry. No carried result from row293. Commit and publish records only in Sage's gap, claimant review move only in a queue gap. Filbert reviews; Sage gates and lands.
## Static self-review
The proposal meets the brief's source/fix/mutant items and preserves the 2/4 s distinction and separated numeric windows. No runtime or load-stability claim is made. Timing-copy instrumentation is the main review risk: Filbert must approve the two exact observation points and source-byte reconstruction before execution. Mos approved the changed old-test measurement semantics in mos-1409. The 7 s whole-run fixture guard and scheduling overshoot remain explicit risks to measure, not hidden assertions to relax. No other test or supervisor repair is bundled.
## Implemented static: mos-1409 / sage-3181 and Filbert I1-I5
Source 1ec2b9765 on base 4a9c536e8. The two observers use `read -r row299_up row299_spare < /proc/uptime`, never the fixture root. Both guard cap 128 and a nonempty `${ROW299_TIMING_FILE-}`. printf is redirected to that absolute private fixture file; grouped stderr goes to /dev/null; errors leave absent evidence which the parser refuses. No observer assigns a production capture variable, changes rc, or touches a trap. New tests assert row299-only read targets and no other assignment; preserve explicit stdout/stderr bytes, exit 87 and the EXIT trap; and reject missing begin/end, duplicate pair, reversed order, nonnumeric/equal/backward readings, and a missing/extra final newline.
Only inner/outer fault runs receive the absolute timing path and executable 0700 private copy. Every such run reverses its two insertions and compares to a fresh read of SCRIPT, including any timer mutant. Baseline and overflow use SCRIPT; baseline status and clean-session assertions remain unchanged. The clock pair is required by assert.doesNotThrow before applying the unchanged bands. baselineSeconds stays diagnostic only. Capture launch insertion keys on its unique LC_ALL=C prefix rather than the timeout command itself, so M4 (outer removal) reaches execution instead of an anchor refusal.
M1-M6 have one target each in their defined scope. M5 now suppresses only the begin printf, preserving the constant block and reversal check so the named inner test must reject an end-only record. M6 admits equal readings so the record-validation test must catch it. M1 retains the known startup-overhead risk: save its interval and stop on a survivor, without changing the ruled bands. All production/shared fixture bytes are unchanged. Manifest is the two test/helper paths only. No Node, syntax preflight, test, mutant, queue call, or HTTPS operation has run. The implementation is unverified until Filbert's static read and Sage CLEAR.
## sage-3255 integration, static only
Rebased all three commits from 4a9c536e8 onto 80793d824 under new branch gander/row299-8079, preserving gander/row299-p10. No conflict. The range-diff has three equal pairs and all per-commit stable patch-ids match. Source is e6751ecab; both manifest blobs equal the approved 1ec2b9765 blobs, so digest 277ace0b is unchanged. Direct test/helper, product case1 script, shared CLI helper and sudo-fixture paths have zero drift over 4a9c536e8..80793d824. Row294's CLI config/access and stack-release-test changes are in the new base and covered by the required full CLI suite. No package/source/test implementation changed in this integration. Full records in integration-8079/.
Gate remains held for CLEAR. Ambient load >=4 remains a target, not a wait condition under mos-1409; no stress process. Record each of three whole case1 starts and the whole CLI suite's load and per-mode direct timings. Numeric windows and the 7 s guard remain fixed. Any red, guard intervention, timeout, survivor or overshoot stops to Sage for Mos before edits or retry.
@@ -0,0 +1,2 @@
7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a packages/cli/tests/case-p10-timing-fixture.mjs
685cf69c741540240c5b414e1907e624cbc59656541316f178d377472fad34a2 packages/cli/tests/case1-accept.test.mjs
@@ -0,0 +1,73 @@
{
"status": "Static definitions finalized; no mutant executed",
"mutants": [
{
"id": "M1",
"path": "scripts/case1-accept.sh",
"old": "tester_capture 2 4 128",
"new": "tester_capture 1 4 128",
"killer": "row253 C4 P10 inner reason holds under both sudo models",
"expected": "exact inner-timeout reason remains valid, but direct probe interval is below 1.25 s; ERR_ASSERTION on the existing lower-band check",
"static_anchor_count": 1,
"source_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"receipt_requirement": "Record direct interval even if it survives; startup overhead can erase the 0.25 s kill margin. Survivor stops to Sage/Mos; bands unchanged."
},
{
"id": "M2",
"path": "scripts/case1-accept.sh",
"old": "tester_capture 2 4 128",
"new": "tester_capture 3 4 128",
"killer": "row253 C4 P10 inner reason holds under both sudo models",
"expected": "exact inner-timeout reason remains valid, but direct interval exceeds the unchanged 2.75 s top; ERR_ASSERTION on upper-band check",
"static_anchor_count": 1,
"source_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2"
},
{
"id": "M3",
"path": "scripts/case1-accept.sh",
"old": "tester_capture 2 4 128",
"new": "tester_capture 2 3 128",
"killer": "row253 C4 P10 outer reason holds under both sudo models",
"expected": "stalled supervisor still gives exact outer-timeout, but direct interval falls below 3.25 s; ERR_ASSERTION on outer lower-band check",
"static_anchor_count": 1,
"source_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2"
},
{
"id": "M4",
"path": "scripts/case1-accept.sh",
"scope": "tester_capture function only",
"description": "Remove the trusted outer GNU timeout from the capture invocation, keeping the fixture guard",
"killer": "row253 C4 P10 outer reason holds under both sudo models",
"expected": "the fixture safety guard permits return but the exact probe-outer-timeout assertion fails; never count external command timeout or cleanup alone as a kill",
"scope_begin": "tester_capture() (\n",
"scope_end": "# row276-legacy-begin",
"old": "LC_ALL=C \"$TS_TIMEOUT\" --verbose --signal=KILL \"${outer}s\" \"$TS_BASH\" -c ",
"new": "LC_ALL=C \"$TS_BASH\" -c ",
"static_anchor_count": 1,
"source_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2"
},
{
"id": "M5",
"path": "packages/cli/tests/case-p10-timing-fixture.mjs",
"description": "Suppress the begin printf while retaining the inserted begin block and reversal check",
"killer": "row253 C4 P10 inner reason holds under both sudo models",
"expected": "the existing inner test requires a valid pair with assert.doesNotThrow; end-only evidence fails ERR_ASSERTION",
"old": "printf 'begin %s\\\\n' \"$row299_up\" >> \"$ROW299_TIMING_FILE\";",
"new": ":;",
"static_anchor_count": 1,
"source_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a"
},
{
"id": "M6",
"path": "packages/cli/tests/case-p10-timing-fixture.mjs",
"description": "Accept an equal begin/end clock pair",
"killer": "row299 P10 observer records are complete and ordered",
"expected": "the equal-readings case in the named record test expects refusal and fails ERR_ASSERTION",
"old": "end <= begin",
"new": "end < begin",
"static_anchor_count": 1,
"source_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a"
}
],
"restore": "Restore byte-identical source/test/helper files and require clean git status between cases. Timeout is a stop, never a kill."
}
@@ -0,0 +1,7 @@
b0ca08db7968e92d417960e58112d767d54902e4d1121f97d4eef2152a2340eb agents/gander/work/queue-299/ASSERTION-PRESERVATION.json
3cc775b0c0e78d0aca5396aba4380a0bdd38d421b144dceea4124323ddfd1bc4 agents/gander/work/queue-299/BASE.json
132cd793d5f9daa93c879d073dd1fa1d1568b07851b707a3c0b519ed64e9a63a agents/gander/work/queue-299/BUILD.md
277ace0b4274970d5bd4c05cf8fe99aa1e7ebc469a719e4cefcb334a75d3865d agents/gander/work/queue-299/MANIFEST.sha256
ff72c99b4b73cfe2acbaf79eb9aed442c855f011fe662722acba7f8a388d3f9b agents/gander/work/queue-299/MUTANT-PLAN.json
7657e629dab262aaeb46004526ede586a167675558a72b6177abf7e646ce6885 agents/gander/work/queue-299/integration-8079/CHECKS.json
b6632cb58ccfc79262f98322682cfd2887e102436cdd1af9e8ac37d2a482b9d8 agents/gander/work/queue-299/integration-8079/range-diff.txt
@@ -0,0 +1,35 @@
{
"base": "80793d824e05baaef4820f4be7790aba55971b6f",
"rebased_source": "e6751ecab",
"rebased_tip_before_records": "bc7da6814",
"conflicts": [],
"range_diff": "all three pairs equal",
"patch_ids": [
{
"old": "31c847580",
"new": "482adc255",
"patch_id": "224e6ce7677320cf362189ad2746c481176c3429"
},
{
"old": "1ec2b9765",
"new": "e6751ecab",
"patch_id": "dec31bc01820a54fa4001fda4886905576a6b692"
},
{
"old": "9872b5ab5",
"new": "bc7da6814",
"patch_id": "f335941005f9c113aa09a800a3569d2447be3464"
}
],
"checked_paths": [
"packages/cli/tests/case1-accept.test.mjs",
"packages/cli/tests/case-p10-timing-fixture.mjs",
"scripts/case1-accept.sh",
"packages/cli/tests/helpers.mjs",
"packages/cli/tests/case-sudo-fixture.mjs"
],
"drift": "",
"manifest": "277ace0b4274970d5bd4c05cf8fe99aa1e7ebc469a719e4cefcb334a75d3865d",
"test_blobs_match_static_approved_1ec2b9765": true,
"runtime": "Not run; awaiting Sage CLEAR. No queue/Node/tests executed."
}
@@ -0,0 +1,3 @@
1: 31c847580 = 1: 482adc255 docs(row299): propose direct P10 wait timing for mos-1272 review
2: 1ec2b9765 = 2: e6751ecab test(case): observe P10 wait directly under mos-1409
3: 9872b5ab5 = 3: bc7da6814 docs(row299): record mos-1409 preservation and static candidate
@@ -0,0 +1,63 @@
// Row299 / mos-1409: observations exist only in a private test copy of the
// shipped script. Neither the timer arguments nor its control flow are changed.
const CAPTURE = 'tester_capture() (\n';
const LEGACY = '# row276-legacy-begin';
// Stable even when a mutant removes the outer timeout from this command.
const LAUNCH = ' LC_ALL=C ';
const WAIT = ' wait "$child" 2>/dev/null || rc=$?\n';
export const P10_OBSERVERS = Object.freeze({
begin: ` # row299-observer-begin-start
if [ "$maximum" = 128 ] && [ -n "\${ROW299_TIMING_FILE-}" ]; then
{ read -r row299_up row299_spare < /proc/uptime &&
printf 'begin %s\\n' "$row299_up" >> "$ROW299_TIMING_FILE"; } 2>/dev/null || :
fi
# row299-observer-begin-end
`,
end: ` # row299-observer-end-start
if [ "$maximum" = 128 ] && [ -n "\${ROW299_TIMING_FILE-}" ]; then
{ read -r row299_up row299_spare < /proc/uptime &&
printf 'end %s\\n' "$row299_up" >> "$ROW299_TIMING_FILE"; } 2>/dev/null || :
fi
# row299-observer-end-end
`,
});
function uniqueIndex(source, text) {
const first = source.indexOf(text);
if (first < 0 || source.indexOf(text, first + text.length) >= 0) {
throw new Error('P10 observer anchor must occur exactly once');
}
return first;
}
export function instrumentP10Probe(source) {
const start = uniqueIndex(source, CAPTURE);
const end = uniqueIndex(source, LEGACY);
if (end <= start) throw new Error('P10 observer capture scope is reversed');
let capture = source.slice(start, end);
uniqueIndex(capture, LAUNCH);
uniqueIndex(capture, WAIT);
capture = capture.replace(LAUNCH, P10_OBSERVERS.begin + LAUNCH);
capture = capture.replace(WAIT, WAIT + P10_OBSERVERS.end);
return source.slice(0, start) + capture + source.slice(end);
}
export function removeP10Observers(source) {
for (const block of Object.values(P10_OBSERVERS)) {
uniqueIndex(source, block);
source = source.replace(block, '');
}
return source;
}
export function readProbeSeconds(text) {
const match = /^begin ([0-9]+)\.([0-9]{2})\nend ([0-9]+)\.([0-9]{2})\n$/.exec(text);
if (!match || match[0] !== text) throw new Error('P10 observer needs exactly one complete ordered pair');
const begin = BigInt(match[1]) * 100n + BigInt(match[2]);
const end = BigInt(match[3]) * 100n + BigInt(match[4]);
if (end <= begin || end - begin > BigInt(Number.MAX_SAFE_INTEGER)) {
throw new Error('P10 observer interval must be positive and safely representable');
}
return Number(end - begin) / 100;
}
+66 -6
View File
@@ -12,6 +12,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, sym
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { tmp } from "./helpers.mjs";
import { instrumentP10Probe, removeP10Observers, readProbeSeconds, P10_OBSERVERS } from "./case-p10-timing-fixture.mjs";
import { CASE_SUDO_SESSION, recordedLivePids, killRecordedPids, fixtureGuard, cleanupFixture, pollFixtureGone, blockingQuerySource, LEGACY_CASES } from "./case-sudo-fixture.mjs";
const REPO = fileURLToPath(new URL("../../../", import.meta.url));
@@ -209,8 +210,8 @@ function host(t) {
return { dir, root, hc, bin, args };
}
function run(h, extra = {}, argv = ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--claude-pin", CLAUDE_PIN, "--node-pin", NODE_PIN, "--root", h.root]) {
const r = spawnSync(SCRIPT, argv, {
function run(h, extra = {}, argv = ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--claude-pin", CLAUDE_PIN, "--node-pin", NODE_PIN, "--root", h.root], script = SCRIPT) {
const r = spawnSync(script, argv, {
encoding: "utf8",
env: { ...process.env, PATH: `${h.bin}:${process.env.PATH}`, HC: h.hc, ROOT_DIR: h.root, REAL_NODE: process.execPath, TMPDIR: h.dir, ...extra },
});
@@ -365,6 +366,58 @@ test('row253 C4 acceptance query overflow is output-limit in both models',async
}
});
test('row299 P10 timing copy preserves shipped bytes and isolates observer variables',()=>{
const source=read(SCRIPT),copy=instrumentP10Probe(source);
assert.equal(removeP10Observers(copy),read(SCRIPT),'observer reversal equals a fresh shipped script read');
for(const block of Object.values(P10_OBSERVERS)){
const reads=[...block.matchAll(/\bread -r ([A-Za-z_][A-Za-z0-9_ ]*) < \/proc\/uptime/g)];
assert.equal(reads.length,1,'one direct host clock read per observer');
const assigned=reads[0][1].trim().split(/\s+/);
assert.deepEqual(assigned,['row299_up','row299_spare']);
assert.ok(assigned.every(name=>/^row299_/.test(name)),'read targets cannot clobber capture locals');
assert.deepEqual([...block.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)=/g)],[],'no other assignments in observer blocks');
assert.doesNotMatch(block,/\$ROOT|\$\{ROOT/,'fixture root cannot supply the clock');
}
const changedTimer=source.replace('tester_capture 2 4 128','tester_capture 1 4 128');
assert.equal(removeP10Observers(instrumentP10Probe(changedTimer)),changedTimer,'copy keeps current timer mutants');
});
test('row299 P10 observers preserve stdout stderr status and the EXIT trap',t=>{
const dir=tmp(t,'p10-clock-'),clock=join(dir,'clock'),trapFile=join(dir,'trap');
put(clock,'',0o600);
const program=`set -uo pipefail
capture() (
maximum=128; rc=87
trap 'printf trap > "$ROW299_TRAP_FILE"' EXIT
${P10_OBSERVERS.begin}printf stdout-without-newline
printf stderr-without-newline >&2
${P10_OBSERVERS.end}exit "$rc"
)
capture`;
const r=spawnSync('/bin/bash',['-c',program],{encoding:'utf8',env:{...process.env,ROW299_TIMING_FILE:clock,ROW299_TRAP_FILE:trapFile}});
assert.equal(r.status,87);
assert.equal(r.stdout,'stdout-without-newline');
assert.equal(r.stderr,'stderr-without-newline');
assert.equal(read(trapFile),'trap');
assert.match(read(clock),/^begin [0-9]+\.[0-9]{2}\nend [0-9]+\.[0-9]{2}\n$/);
});
test('row299 P10 observer records are complete and ordered',()=>{
assert.equal(readProbeSeconds('begin 100.01\nend 102.03\n'),2.02);
const invalid={
'missing begin':'end 102.00\n',
'missing end':'begin 100.00\n',
'duplicate pair':'begin 100.00\nend 102.00\nbegin 102.00\nend 104.00\n',
'reversed order':'end 102.00\nbegin 100.00\n',
'non-numeric':'begin nope\nend 102.00\n',
'equal readings':'begin 100.00\nend 100.00\n',
'backward readings':'begin 102.00\nend 100.00\n',
'missing final newline':'begin 100.00\nend 102.00',
'extra final newline':'begin 100.00\nend 102.00\n\n',
};
for(const [name,text] of Object.entries(invalid))assert.throws(()=>readProbeSeconds(text),/P10 observer/,name);
});
for(const fault of ['inner','outer','overflow'])test(`row253 C4 P10 ${fault} reason holds under both sudo models`,async t=>{
for(const mode of ['exec','hop']){
const h=host(t),files=[join(h.hc,'session-pids'),join(h.hc,'query-pids')];put(join(h.hc,'session-mode'),mode);
@@ -380,16 +433,23 @@ for(const fault of ['inner','outer','overflow'])test(`row253 C4 P10 ${fault} rea
if(fault==='inner')put(join(h.hc,'peer-hang'),'');
if(fault==='outer'){put(join(h.hc,'stall-probe'),'');put(join(h.hc,'stall-output'),'200 997 997\n');}
if(fault==='overflow'){put(join(h.hc,'peer-output'),'200 997 997\n'+'X'.repeat(256));put(join(h.hc,'peer-status'),'0');}
const start=performance.now(),r=run(h),seconds=(performance.now()-start)/1000;capture();
let observedScript=SCRIPT,timingFile;
if(fault==='inner'||fault==='outer'){
observedScript=join(h.dir,'case1-p10-observed.sh');timingFile=join(h.hc,'probe-uptime');
put(timingFile,'',0o600);put(observedScript,instrumentP10Probe(read(SCRIPT)),0o700);
assert.equal(removeP10Observers(read(observedScript)),read(SCRIPT),'observer reversal equals a fresh shipped script read');
}
const start=performance.now(),r=run(h,timingFile?{ROW299_TIMING_FILE:timingFile}:{},undefined,observedScript),seconds=(performance.now()-start)/1000;capture();
assert.equal(r.status,0,r.out+r.err);
const reason=fault==='inner'?'inner-timeout':fault==='outer'?'outer-timeout':'output-limit';
assert.match(r.out,new RegExp('P10 tester-socket-squat unnamed boundary=failed reason=probe-'+reason+' '));
assert.doesNotMatch(r.out,/boundary=observed/);
const probeSeconds=seconds-baselineSeconds;
let probeSeconds=seconds;
if(timingFile)assert.doesNotThrow(()=>{probeSeconds=readProbeSeconds(read(timingFile));},'P10 observer pair is required');
if(fault==='inner'||fault==='outer')t.diagnostic(JSON.stringify({fault,mode,baselineSeconds,faultSeconds:seconds,probeSeconds}));
if(fault==='inner')assert.ok(probeSeconds>=1.25&&probeSeconds<2.75,`${mode}: probe ${probeSeconds}s after baseline ${baselineSeconds}s`);
if(fault==='inner')assert.ok(probeSeconds>=1.25&&probeSeconds<2.75,`${mode}: direct probe ${probeSeconds}s; baseline ${baselineSeconds}s is diagnostic only`);
if(fault==='outer'){
assert.ok(probeSeconds>=3.25&&probeSeconds<4.75,`${mode}: probe ${probeSeconds}s after baseline ${baselineSeconds}s`);
assert.ok(probeSeconds>=3.25&&probeSeconds<4.75,`${mode}: direct probe ${probeSeconds}s; baseline ${baselineSeconds}s is diagnostic only`);
if(mode==='hop')assert.ok(recordedLivePids(files[0]).length>0,'stalled supervisor is R3 residual');
for(const file of files)killRecordedPids(file);
}