docs: record row 279 regression and mutant evidence
This commit is contained in:
1 parent
1016b85846
commit
cad9271377
21 files changed
+755
No files matched your search
@@ -0,0 +1,56 @@
|
||||
# Row279: stopRun deadline final observation
|
||||
|
||||
Scope: sage-2512, mos-1269; brief docs/plans/2026-10-22_stoprun-deadline.md.
|
||||
Base f40f2e770. Reviewer Dewey; gate owner Sage. V502 stays separate.
|
||||
|
||||
## Cause and smallest change
|
||||
|
||||
The loop's precondition now()<=deadline can skip the existing final status
|
||||
read when a sleep wakes beyond deadline. Use for(;;) so the existing
|
||||
now()>=deadline branch is the only time exit. Change that loop header only;
|
||||
all record/identity/ended exits and result mapping remain byte-identical.
|
||||
The old trailing fallback remains unreachable in the fixed loop. M1 restores
|
||||
only the old header and thereby restores the complete old fall-through path.
|
||||
|
||||
## Regression and evidence plan
|
||||
|
||||
Add one test to stop-run.test.mjs, preserving existing tests. Its fake sleep
|
||||
advances requested duration plus1ms, so the last sleep crosses the deadline.
|
||||
Its signal stub records TERM/KILL and returns success without killing the
|
||||
always-live fixture process. Expect both signals, time>7000ms and alive.
|
||||
The old loop should fail only the alive assertion with unknown.
|
||||
|
||||
Ask Sage CLEAR before any run, including the expected regression red. Then
|
||||
apply the one-line fix, run the touched whole file and processing-control
|
||||
package as granted, and kill M1 with that same named regression. Busy check,
|
||||
short scratch TMPDIR,deadDocker,owned process groups,timeouts,restore,sweep.
|
||||
No live state,units,store,provider,browser,Docker or V502 changes.
|
||||
|
||||
Packet includes base,patch,candidate hashes,regression/gate/mutant logs and
|
||||
exact source-diff check. Commit candidate and packet on the new branch only
|
||||
after authorized checks. No token is available; Sage publishes as jarvis.
|
||||
The business/CLI suites remain Sage's landing gate unless separately granted.
|
||||
|
||||
## Authorized run and result
|
||||
|
||||
Claim rev 3138, op rocko-279-start-r1. Sage granted this exact sequence in
|
||||
sage-2516 (2026-10-22T05:55:21Z). Runs: 05:56:03Z to 05:58:03Z.
|
||||
|
||||
| Step | Pass | Fail | Skip | Result |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| Regression on unfixed base | 0 | 1 | 0 | Expected assertion: unknown versus alive |
|
||||
| stop-run.test.mjs whole | 13 | 0 | 0 | Green |
|
||||
| processing-control package whole | 62 | 0 | 0 | Green |
|
||||
| M1 old loop | 0 | 1 | 0 | Killed by the named regression, unknown versus alive |
|
||||
|
||||
M1's killer is `a sleep past the stop deadline still observes an alive run
|
||||
after both signals`. It exits 1 with that assertion, never a syntax error or
|
||||
timeout. Logs and results.json retain the intentional failures separately.
|
||||
Green runs total 75 passes (the whole-file tests are also part of the package).
|
||||
No skips. All commands used a short scratch TMPDIR, a dead Docker socket and
|
||||
fixture-only configuration. Each node command ran in its own process group
|
||||
with a 120-second timeout. No timeout occurred. Final cwd sweep: empty.
|
||||
The source restoration and exact one-line product scope are checked in
|
||||
source-scope-check.json. The trailing unknown return stays unchanged and is
|
||||
unreachable after the fix. Business and CLI suites remain Sage's owner gate.
|
||||
Slot returned to Sage at 05:58:03Z. No live action or V502 change.
|
||||
@@ -0,0 +1 @@
|
||||
f40f2e770e0d8be394f1ef53b404045fd6a49c0e
|
||||
@@ -0,0 +1,35 @@
|
||||
diff --git a/packages/processing-control/src/runtimes.mjs b/packages/processing-control/src/runtimes.mjs
|
||||
index 05e439c1a..a11cb8e52 100644
|
||||
--- a/packages/processing-control/src/runtimes.mjs
|
||||
+++ b/packages/processing-control/src/runtimes.mjs
|
||||
@@ -330,7 +330,7 @@ async function ownStop(args, key, options) {
|
||||
};
|
||||
const termEnd = started + grace, deadline = termEnd + observe;
|
||||
let termTried = false, killTried = false;
|
||||
- while (now() <= deadline) {
|
||||
+ for (;;) {
|
||||
try { record = runtime(root, record.id); }
|
||||
catch {
|
||||
const present = readdirSync(directory(root, 'runtimes')).includes(record.id + '.json');
|
||||
diff --git a/packages/processing-control/tests/stop-run.test.mjs b/packages/processing-control/tests/stop-run.test.mjs
|
||||
index ed69bc111..5277ea7fe 100644
|
||||
--- a/packages/processing-control/tests/stop-run.test.mjs
|
||||
+++ b/packages/processing-control/tests/stop-run.test.mjs
|
||||
@@ -61,6 +61,17 @@ test('failed signal delivery observes alive, records no invented signals and nev
|
||||
assert.equal(f.sleeps.reduce((a,b)=>a+b,0), 7000);
|
||||
assert.deepEqual(await stopRun(f.args, f.options), result);
|
||||
});
|
||||
+test('a sleep past the stop deadline still observes an alive run after both signals', async t => {
|
||||
+ const f = setup(t); let time = 0;
|
||||
+ f.options.now = () => time;
|
||||
+ f.options.sleep = async ms => { time += ms + 1; };
|
||||
+ f.options.signal = (_r, sig) => { f.signals.push(sig); return true; };
|
||||
+ const result = await stopRun(f.args, f.options);
|
||||
+ assert.ok(time > 7000, 'the last sleep wakes past the complete stop deadline');
|
||||
+ assert.deepEqual(f.signals, ['SIGTERM', 'SIGKILL']);
|
||||
+ assert.equal(result.outcome, 'alive');
|
||||
+ assert.deepEqual(result.signals, ['SIGTERM', 'SIGKILL']);
|
||||
+});
|
||||
test('missing run and another business never borrow a pid or signal', async t => {
|
||||
const f = setup(t);
|
||||
for (const args of [{ ...f.args, run: 'missing' }, { ...f.args, business: 'other' }]) {
|
||||
@@ -0,0 +1,2 @@
|
||||
7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea packages/processing-control/src/runtimes.mjs
|
||||
7ce7a99363b987f8525f8992fd57940f4305597e870c6162fc158962f2101ff6 packages/processing-control/tests/stop-run.test.mjs
|
||||
@@ -0,0 +1 @@
|
||||
1016b85846c60dc159d49373f99ca36794a51fd9
|
||||
@@ -0,0 +1,2 @@
|
||||
packages/processing-control/src/runtimes.mjs
|
||||
packages/processing-control/tests/stop-run.test.mjs
|
||||
@@ -0,0 +1 @@
|
||||
1016b85846c60dc159d49373f99ca36794a51fd9
|
||||
@@ -0,0 +1,32 @@
|
||||
TAP version 13
|
||||
# Subtest: a sleep past the stop deadline still observes an alive run after both signals
|
||||
not ok 1 - a sleep past the stop deadline still observes an alive run after both signals
|
||||
---
|
||||
duration_ms: 40.278473
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r279/packages/processing-control/tests/stop-run.test.mjs:64:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
|
||||
'unknown' !== 'alive'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 'alive'
|
||||
actual: 'unknown'
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r279/packages/processing-control/tests/stop-run.test.mjs:72:10)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 89.021437
|
||||
@@ -0,0 +1,382 @@
|
||||
TAP version 13
|
||||
# Subtest: container admission publishes its generated name and root/runtime labels before dispatch
|
||||
ok 1 - container admission publishes its generated name and root/runtime labels before dispatch
|
||||
---
|
||||
duration_ms: 9.883733
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: container sweep sends TERM then KILL only after verifying exact id and both labels
|
||||
ok 2 - container sweep sends TERM then KILL only after verifying exact id and both labels
|
||||
---
|
||||
duration_ms: 66.167157
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: foreign labels and a replaced container id stay unknown and are never signalled
|
||||
ok 3 - foreign labels and a replaced container id stay unknown and are never signalled
|
||||
---
|
||||
duration_ms: 5.105671
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an unverified missing container remains unknown rather than claiming a pending start ended
|
||||
ok 4 - an unverified missing container remains unknown rather than claiming a pending start ended
|
||||
---
|
||||
duration_ms: 15.538468
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a removed --rm container is settled only by its trusted owner completion receipt
|
||||
ok 5 - a removed --rm container is settled only by its trusted owner completion receipt
|
||||
---
|
||||
duration_ms: 28.897791
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: after signalling a verified container, successful empty Docker listing proves --rm removed that id
|
||||
ok 6 - after signalling a verified container, successful empty Docker listing proves --rm removed that id
|
||||
---
|
||||
duration_ms: 24.215826
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt publishes before awaiting stops, resume refuses pending, and only clear permits new work
|
||||
ok 7 - halt publishes before awaiting stops, resume refuses pending, and only clear permits new work
|
||||
---
|
||||
duration_ms: 161.569582
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a new coordinator replays a persisted halt and an unresolved start keeps clear refused
|
||||
ok 8 - a new coordinator replays a persisted halt and an unresolved start keeps clear refused
|
||||
---
|
||||
duration_ms: 1102.680874
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a new halt generation never inherits a previous quiescent status before its sweep
|
||||
ok 9 - a new halt generation never inherits a previous quiescent status before its sweep
|
||||
---
|
||||
duration_ms: 4.450121
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt aborts an active local request and prevents a subsequent effect after halt/resume
|
||||
ok 10 - halt aborts an active local request and prevents a subsequent effect after halt/resume
|
||||
---
|
||||
duration_ms: 35.831508
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: processing scopes isolate roots and cancel only the registered child group
|
||||
ok 11 - processing scopes isolate roots and cancel only the registered child group
|
||||
---
|
||||
duration_ms: 59.946603
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halted scopes never invoke their body and unscoped human work has no processing context
|
||||
ok 12 - halted scopes never invoke their body and unscoped human work has no processing context
|
||||
---
|
||||
duration_ms: 3.067699
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: host git is stopped promptly by the active scope rather than waiting for its long deadline
|
||||
ok 13 - host git is stopped promptly by the active scope rather than waiting for its long deadline
|
||||
---
|
||||
duration_ms: 151.711241
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a child leader exiting does not erase an unverified surviving group receipt
|
||||
ok 14 - a child leader exiting does not erase an unverified surviving group receipt
|
||||
---
|
||||
duration_ms: 117.914283
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the actual nested read-only control mount refuses unlink, replacement and parent removal
|
||||
ok 15 - the actual nested read-only control mount refuses unlink, replacement and parent removal
|
||||
---
|
||||
duration_ms: 14.941666
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: the image entrypoint refuses halted and stale generations using the shared reader
|
||||
ok 16 - the image entrypoint refuses halted and stale generations using the shared reader
|
||||
---
|
||||
duration_ms: 89.020485
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt terminates a tracked stand-in and leaves honest write-once stop evidence
|
||||
ok 17 - halt terminates a tracked stand-in and leaves honest write-once stop evidence
|
||||
---
|
||||
duration_ms: 95.55672
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a TERM-resistant workload is killed after the bounded wait
|
||||
ok 18 - a TERM-resistant workload is killed after the bounded wait
|
||||
---
|
||||
duration_ms: 146.00258
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: wrong start ticks or boot identity cannot signal a live replacement
|
||||
ok 19 - wrong start ticks or boot identity cannot signal a live replacement
|
||||
---
|
||||
duration_ms: 65.844444
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a pending start cannot be reported quiescent and a second root is never signalled
|
||||
ok 20 - a pending start cannot be reported quiescent and a second root is never signalled
|
||||
---
|
||||
duration_ms: 93.749051
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: escalation still kills the tracked group after its leader exits
|
||||
ok 21 - escalation still kills the tracked group after its leader exits
|
||||
---
|
||||
duration_ms: 192.463864
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: session TERM targets its verified runner before forcing the outer namespace
|
||||
ok 22 - session TERM targets its verified runner before forcing the outer namespace
|
||||
---
|
||||
duration_ms: 100.923976
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: new runtime and stop directories sync their containing directories
|
||||
ok 23 - new runtime and stop directories sync their containing directories
|
||||
---
|
||||
duration_ms: 42.560646
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a vanished group leader with unverified surviving members stays unknown, never quiescent
|
||||
ok 24 - a vanished group leader with unverified surviving members stays unknown, never quiescent
|
||||
---
|
||||
duration_ms: 130.848284
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: persisted member identity anchors a group after the leader exited before the sweep
|
||||
ok 25 - persisted member identity anchors a group after the leader exited before the sweep
|
||||
---
|
||||
duration_ms: 124.574935
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: an unconfirmed secondary brake does not leave a verified workload running or claim success
|
||||
ok 26 - an unconfirmed secondary brake does not leave a verified workload running or claim success
|
||||
---
|
||||
duration_ms: 75.057063
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt persists across readers and resume needs the current generation
|
||||
ok 27 - halt persists across readers and resume needs the current generation
|
||||
---
|
||||
duration_ms: 9.437871
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: first initialization is explicit; missing state after control exists fails closed and halt repairs it
|
||||
ok 28 - first initialization is explicit; missing state after control exists fails closed and halt repairs it
|
||||
---
|
||||
duration_ms: 5.039685
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses invalid JSON instead of enabling work
|
||||
ok 29 - refuses invalid JSON instead of enabling work
|
||||
---
|
||||
duration_ms: 1.867281
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses unknown keys instead of enabling work
|
||||
ok 30 - refuses unknown keys instead of enabling work
|
||||
---
|
||||
duration_ms: 2.65956
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses bad timestamp instead of enabling work
|
||||
ok 31 - refuses bad timestamp instead of enabling work
|
||||
---
|
||||
duration_ms: 2.144084
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses nonboolean state instead of enabling work
|
||||
ok 32 - refuses nonboolean state instead of enabling work
|
||||
---
|
||||
duration_ms: 2.039112
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses bad generation instead of enabling work
|
||||
ok 33 - refuses bad generation instead of enabling work
|
||||
---
|
||||
duration_ms: 2.085806
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses loose mode instead of enabling work
|
||||
ok 34 - refuses loose mode instead of enabling work
|
||||
---
|
||||
duration_ms: 2.34307
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: refuses oversized file instead of enabling work
|
||||
ok 35 - refuses oversized file instead of enabling work
|
||||
---
|
||||
duration_ms: 2.916273
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a symlink leaf never follows its target; human halt replaces only the leaf
|
||||
ok 36 - a symlink leaf never follows its target; human halt replaces only the leaf
|
||||
---
|
||||
duration_ms: 4.530858
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: unsafe parent and interrupted initialization never get repaired as off
|
||||
ok 37 - unsafe parent and interrupted initialization never get repaired as off
|
||||
---
|
||||
duration_ms: 0.385291
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: repeated halt is a no-op and a different root keeps running
|
||||
ok 38 - repeated halt is a no-op and a different root keeps running
|
||||
---
|
||||
duration_ms: 7.00566
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: transition rejects nonstring identity before publishing state
|
||||
ok 39 - transition rejects nonstring identity before publishing state
|
||||
---
|
||||
duration_ms: 3.121939
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: bootstrap syncs the containing root as well as the state and control directory
|
||||
ok 40 - bootstrap syncs the containing root as well as the state and control directory
|
||||
---
|
||||
duration_ms: 36.144072
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: state ownership and bounded read guards refuse before trusting a document
|
||||
ok 41 - state ownership and bounded read guards refuse before trusting a document
|
||||
---
|
||||
duration_ms: 101.892703
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: canonical root aliases address one switch and never create independent control state
|
||||
ok 42 - canonical root aliases address one switch and never create independent control state
|
||||
---
|
||||
duration_ms: 4.179236
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: unbound run stops by verified registry identity, fixed 5s grace and 2s observe policy
|
||||
ok 43 - unbound run stops by verified registry identity, fixed 5s grace and 2s observe policy
|
||||
---
|
||||
duration_ms: 38.851257
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: same run joins the identical promise and completed repeats preserve owner and send no signals
|
||||
ok 44 - same run joins the identical promise and completed repeats preserve owner and send no signals
|
||||
---
|
||||
duration_ms: 27.976805
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: identity changed before TERM or between TERM and KILL refuses the changed signal
|
||||
ok 45 - identity changed before TERM or between TERM and KILL refuses the changed signal
|
||||
---
|
||||
duration_ms: 15.642865
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: failed signal delivery observes alive, records no invented signals and never restarts escalation
|
||||
ok 46 - failed signal delivery observes alive, records no invented signals and never restarts escalation
|
||||
---
|
||||
duration_ms: 32.602087
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a sleep past the stop deadline still observes an alive run after both signals
|
||||
ok 47 - a sleep past the stop deadline still observes an alive run after both signals
|
||||
---
|
||||
duration_ms: 31.045314
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: missing run and another business never borrow a pid or signal
|
||||
ok 48 - missing run and another business never borrow a pid or signal
|
||||
---
|
||||
duration_ms: 10.113655
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt joins an in-progress fire without another TERM or deadline and links its first receipt
|
||||
ok 49 - halt joins an in-progress fire without another TERM or deadline and links its first receipt
|
||||
---
|
||||
duration_ms: 30.224351
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a separate host joins durable first ownership without duplicate signals
|
||||
ok 50 - a separate host joins durable first ownership without duplicate signals
|
||||
---
|
||||
duration_ms: 99.128156
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: corrupt and symlinked final receipts refuse as unknown rather than signalling again
|
||||
ok 51 - corrupt and symlinked final receipts refuse as unknown rather than signalling again
|
||||
---
|
||||
duration_ms: 22.649789
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a later exit gets separate halt evidence while the original alive result stays immutable
|
||||
ok 52 - a later exit gets separate halt evidence while the original alive result stays immutable
|
||||
---
|
||||
duration_ms: 55.85559
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: root aliases join but a different root never shares the run stop
|
||||
ok 53 - root aliases join but a different root never shares the run stop
|
||||
---
|
||||
duration_ms: 45.6493
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a changed runtime record cannot replace the original stop identity after TERM
|
||||
ok 54 - a changed runtime record cannot replace the original stop identity after TERM
|
||||
---
|
||||
duration_ms: 8.507771
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: identity is rechecked at actual signal delivery, not just at the loop observation
|
||||
ok 55 - identity is rechecked at actual signal delivery, not just at the loop observation
|
||||
---
|
||||
duration_ms: 6.500324
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: task halt keeps the true Docker exit status, writes kill-switch once and leaves snapshots unchanged
|
||||
ok 56 - task halt keeps the true Docker exit status, writes kill-switch once and leaves snapshots unchanged
|
||||
---
|
||||
duration_ms: 201.141886
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt refuses direct task launch before Docker or a run record; clear allows a fresh normal result
|
||||
ok 57 - halt refuses direct task launch before Docker or a run record; clear allows a fresh normal result
|
||||
---
|
||||
duration_ms: 167.652567
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt refuses hello.sh before Docker, credentials or release alignment
|
||||
ok 58 - halt refuses hello.sh before Docker, credentials or release alignment
|
||||
---
|
||||
duration_ms: 122.654442
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt refuses verify.sh before Docker, credentials or release alignment
|
||||
ok 59 - halt refuses verify.sh before Docker, credentials or release alignment
|
||||
---
|
||||
duration_ms: 122.064969
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt refuses agent.sh before Docker, credentials or release alignment
|
||||
ok 60 - halt refuses agent.sh before Docker, credentials or release alignment
|
||||
---
|
||||
duration_ms: 120.632718
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a nonzero Docker client exit retains its unresolved runtime receipt (task)
|
||||
ok 61 - a nonzero Docker client exit retains its unresolved runtime receipt (task)
|
||||
---
|
||||
duration_ms: 93.3117
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a nonzero Docker client exit retains its unresolved runtime receipt (container-cli)
|
||||
ok 62 - a nonzero Docker client exit retains its unresolved runtime receipt (container-cli)
|
||||
---
|
||||
duration_ms: 97.234461
|
||||
type: 'test'
|
||||
...
|
||||
1..62
|
||||
# tests 62
|
||||
# suites 0
|
||||
# pass 62
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 1323.026518
|
||||
@@ -0,0 +1,32 @@
|
||||
TAP version 13
|
||||
# Subtest: a sleep past the stop deadline still observes an alive run after both signals
|
||||
not ok 1 - a sleep past the stop deadline still observes an alive run after both signals
|
||||
---
|
||||
duration_ms: 53.588908
|
||||
type: 'test'
|
||||
location: '/mnt/storage/scratch/rocko-r279/packages/processing-control/tests/stop-run.test.mjs:64:1'
|
||||
failureType: 'testCodeFailure'
|
||||
error: |-
|
||||
Expected values to be strictly equal:
|
||||
|
||||
'unknown' !== 'alive'
|
||||
|
||||
code: 'ERR_ASSERTION'
|
||||
name: 'AssertionError'
|
||||
expected: 'alive'
|
||||
actual: 'unknown'
|
||||
operator: 'strictEqual'
|
||||
stack: |-
|
||||
TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r279/packages/processing-control/tests/stop-run.test.mjs:72:10)
|
||||
async Test.run (node:internal/test_runner/test:1409:7)
|
||||
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
...
|
||||
1..1
|
||||
# tests 1
|
||||
# suites 0
|
||||
# pass 0
|
||||
# fail 1
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 100.649138
|
||||
@@ -0,0 +1,88 @@
|
||||
TAP version 13
|
||||
# Subtest: unbound run stops by verified registry identity, fixed 5s grace and 2s observe policy
|
||||
ok 1 - unbound run stops by verified registry identity, fixed 5s grace and 2s observe policy
|
||||
---
|
||||
duration_ms: 36.122553
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: same run joins the identical promise and completed repeats preserve owner and send no signals
|
||||
ok 2 - same run joins the identical promise and completed repeats preserve owner and send no signals
|
||||
---
|
||||
duration_ms: 24.270208
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: identity changed before TERM or between TERM and KILL refuses the changed signal
|
||||
ok 3 - identity changed before TERM or between TERM and KILL refuses the changed signal
|
||||
---
|
||||
duration_ms: 13.289288
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: failed signal delivery observes alive, records no invented signals and never restarts escalation
|
||||
ok 4 - failed signal delivery observes alive, records no invented signals and never restarts escalation
|
||||
---
|
||||
duration_ms: 27.743499
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a sleep past the stop deadline still observes an alive run after both signals
|
||||
ok 5 - a sleep past the stop deadline still observes an alive run after both signals
|
||||
---
|
||||
duration_ms: 26.252224
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: missing run and another business never borrow a pid or signal
|
||||
ok 6 - missing run and another business never borrow a pid or signal
|
||||
---
|
||||
duration_ms: 9.103416
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: halt joins an in-progress fire without another TERM or deadline and links its first receipt
|
||||
ok 7 - halt joins an in-progress fire without another TERM or deadline and links its first receipt
|
||||
---
|
||||
duration_ms: 25.918671
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a separate host joins durable first ownership without duplicate signals
|
||||
ok 8 - a separate host joins durable first ownership without duplicate signals
|
||||
---
|
||||
duration_ms: 99.095272
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: corrupt and symlinked final receipts refuse as unknown rather than signalling again
|
||||
ok 9 - corrupt and symlinked final receipts refuse as unknown rather than signalling again
|
||||
---
|
||||
duration_ms: 23.700708
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a later exit gets separate halt evidence while the original alive result stays immutable
|
||||
ok 10 - a later exit gets separate halt evidence while the original alive result stays immutable
|
||||
---
|
||||
duration_ms: 55.938599
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: root aliases join but a different root never shares the run stop
|
||||
ok 11 - root aliases join but a different root never shares the run stop
|
||||
---
|
||||
duration_ms: 42.386018
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: a changed runtime record cannot replace the original stop identity after TERM
|
||||
ok 12 - a changed runtime record cannot replace the original stop identity after TERM
|
||||
---
|
||||
duration_ms: 7.168469
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: identity is rechecked at actual signal delivery, not just at the loop observation
|
||||
ok 13 - identity is rechecked at actual signal delivery, not just at the loop observation
|
||||
---
|
||||
duration_ms: 6.715559
|
||||
type: 'test'
|
||||
...
|
||||
1..13
|
||||
# tests 13
|
||||
# suites 0
|
||||
# pass 13
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 445.396108
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"M1","file":"packages/processing-control/src/runtimes.mjs","old":" for (;;) {\n try { record = runtime(root, record.id); }","new":" while (now() <= deadline) {\n try { record = runtime(root, record.id); }","test":"packages/processing-control/tests/stop-run.test.mjs","pattern":"a sleep past the stop deadline still observes an alive run after both signals","required":"named assertion kill, never syntax or timeout"}
|
||||
@@ -0,0 +1,20 @@
|
||||
6d33d35302499d66036145976f8f777a4c438c6b3f5c7b613fcfa5651c49faab BUILD.md
|
||||
8521af77deed1d3b2c722f30b776159eb373df407a2a698ee116ef4174125f01 base.txt
|
||||
74efdcea480e6c089f586b7330591b66164a3aa338fb1e1a60b74f6b7b9f3b0a build.patch
|
||||
312ed511d8f1cff826ee2fd547de8368923130c7bfe06236d8e29d8655b80aaa candidate-manifest.sha256
|
||||
960c366a732e4dc20133bf490d842cc42a345fefad1432ca6eba6dbd0058f337 candidate.txt
|
||||
3099049a5acd051207fb5631b7bb6362dd84c246191009a44eca1ba696d27d73 changed-paths.txt
|
||||
960c366a732e4dc20133bf490d842cc42a345fefad1432ca6eba6dbd0058f337 commit.txt
|
||||
98a4da4e1c62f7e4ed5f50adc16cf99462a5e012e9736e658441e8eda3db894c logs/M1.log
|
||||
7f878c13be43640f501b72d36e8d9e0c8d844bc5451f969154cd75d8fab0ee42 logs/processing-control-whole.log
|
||||
62f83e511ad860d0f7da42d87e063eb691a95f29a0806b88784912374d2e7c47 logs/regression-red.log
|
||||
4de8028674472cc75f61dc78cac624c336c8db785580a189e0b705584f80d636 logs/stop-run-whole.log
|
||||
7669ce9f04189f659dbc23dae6b635d5ffac354e03d00fbae10e6fadc7e98791 mutant-plan.json
|
||||
84f1080a9689374f7000197119074e53b459641cd709745f95eb0ebe37b5ef2f reader-search.txt
|
||||
dd6b2ea95782154e1c9839bae7a6d76a60566762a2374901ae64b22f9a7f54f7 results.json
|
||||
b9408890f30a72451d9171d8ceec40eb4f4f671811b30ba74f50f178e0eb8350 run-step.py
|
||||
b8140e3919a5d342eb92c1cd34b13bbb62d6419c6a5a01a9cb4870e9a94c64ed scan-result.json
|
||||
9e5c2e8cd2b59ac4559b0d67348a2a98e59b44a71eec7359018ea7a84d7a4082 skips.txt
|
||||
43d77fe5bffa916f444a77bacda5b4ddbe78035b6ca7631378056c3158aa3253 source-scope-check.json
|
||||
37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570 sweep.json
|
||||
74b3eae937fdcc92cf2b0dd15fb67f4f6addd4a046f74e934febc565e4b5d2ed tmpdir.txt
|
||||
@@ -0,0 +1,12 @@
|
||||
packages/processing-control/tests/runtimes.test.mjs:9:const api = await import('../src/runtimes.mjs').catch(e => { if (e.code === 'ERR_MODULE_NOT_FOUND') return {}; throw e; });
|
||||
packages/processing-control/tests/runtimes.test.mjs:139: new URL('../src/runtimes.mjs', import.meta.url).href, new URL('../src/state.mjs', import.meta.url).href, root], { encoding: 'utf8' });
|
||||
packages/processing-control/tests/effects.test.mjs:60: const { listRuntimes } = await import('../src/runtimes.mjs');
|
||||
packages/processing-control/tests/coordinator.test.mjs:9:import { registerRuntime, updateRuntime, processIdentity, unregisterRuntime } from '../src/runtimes.mjs';
|
||||
packages/processing-control/tests/containers.test.mjs:62: const { updateRuntime } = await import('../src/runtimes.mjs');
|
||||
packages/processing-control/tests/task.test.mjs:12: const runtimes = new URL('../src/runtimes.mjs', import.meta.url).href;
|
||||
packages/processing-control/tests/stop-run.test.mjs:7:import { registerRuntime, updateRuntime, runtime, stopRun, sweepRuntimes, readStops } from '../src/runtimes.mjs';
|
||||
packages/processing-control/tests/stop-run.test.mjs:104: const f = setup(t), source = new URL('../src/runtimes.mjs', import.meta.url).href;
|
||||
packages/processing-control/tests/stop-run.test.mjs:148: const { processIdentity } = await import('../src/runtimes.mjs');
|
||||
packages/bus/tests/processing-runtime.test.mjs:10:import { registerRuntime, updateRuntime, processIdentity } from '../../processing-control/src/runtimes.mjs';
|
||||
packages/discord/tests/processing-stop.test.mjs:35: const { registerRuntime, updateRuntime } = await import('../../processing-control/src/runtimes.mjs');
|
||||
packages/discord/tests/processing.test.mjs:68: const { listRuntimes, sweepRuntimes, processIdentity } = await import('../../processing-control/src/runtimes.mjs');
|
||||
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"step": "regression-red",
|
||||
"start": "2026-10-22T05:56:03Z",
|
||||
"end": "2026-10-22T05:56:03Z",
|
||||
"exit": 1,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"skipped": 0
|
||||
},
|
||||
"failing": [
|
||||
"a sleep past the stop deadline still observes an alive run after both signals"
|
||||
],
|
||||
"log": "/mnt/storage/scratch/rocko-r279/agents/rocko/work/queue-279/logs/regression-red.log"
|
||||
},
|
||||
{
|
||||
"step": "stop-run-whole",
|
||||
"start": "2026-10-22T05:57:47Z",
|
||||
"end": "2026-10-22T05:57:47Z",
|
||||
"exit": 0,
|
||||
"counts": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"failing": [],
|
||||
"log": "/mnt/storage/scratch/rocko-r279/agents/rocko/work/queue-279/logs/stop-run-whole.log"
|
||||
},
|
||||
{
|
||||
"step": "processing-control-whole",
|
||||
"start": "2026-10-22T05:57:47Z",
|
||||
"end": "2026-10-22T05:57:49Z",
|
||||
"exit": 0,
|
||||
"counts": {
|
||||
"tests": 62,
|
||||
"pass": 62,
|
||||
"fail": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"failing": [],
|
||||
"log": "/mnt/storage/scratch/rocko-r279/agents/rocko/work/queue-279/logs/processing-control-whole.log"
|
||||
},
|
||||
{
|
||||
"step": "M1",
|
||||
"start": "2026-10-22T05:58:03Z",
|
||||
"end": "2026-10-22T05:58:03Z",
|
||||
"exit": 1,
|
||||
"counts": {
|
||||
"tests": 1,
|
||||
"pass": 0,
|
||||
"fail": 1,
|
||||
"skipped": 0
|
||||
},
|
||||
"failing": [
|
||||
"a sleep past the stop deadline still observes an alive run after both signals"
|
||||
],
|
||||
"log": "/mnt/storage/scratch/rocko-r279/agents/rocko/work/queue-279/logs/M1.log"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
from pathlib import Path
|
||||
import subprocess,signal,os,json,time,sys,re
|
||||
root=Path('/mnt/storage/scratch/rocko-r279');p=root/'agents/rocko/work/queue-279';logs=p/'logs';logs.mkdir(exist_ok=True);name=sys.argv[1];command=sys.argv[2:]
|
||||
start=time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime());log=logs/(name+'.log')
|
||||
with log.open('w') as out:
|
||||
child=subprocess.Popen(command,cwd=root,env=os.environ,stdout=out,stderr=subprocess.STDOUT,start_new_session=True)
|
||||
try:rc=child.wait(timeout=120)
|
||||
except subprocess.TimeoutExpired:
|
||||
os.killpg(child.pid,signal.SIGKILL);child.wait();rc=124
|
||||
text=log.read_text();counts={k:int(v) for k,v in re.findall(r'^# (tests|pass|fail|skipped) (\d+)\s*$',text,re.M)};failing=re.findall(r'^not ok \d+ - (.*)$',text,re.M)
|
||||
row=dict(step=name,start=start,end=time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime()),exit=rc,counts=counts,failing=failing,log=str(log));result=p/'results.json';rows=json.loads(result.read_text()) if result.exists() else [];rows.append(row);result.write_text(json.dumps(rows,indent=2)+'\n');print(json.dumps(row));print(text[-3200:])
|
||||
if name in ['regression-red','M1']:
|
||||
ok=rc==1 and failing==['a sleep past the stop deadline still observes an alive run after both signals'] and "actual: 'unknown'" in text and "expected: 'alive'" in text
|
||||
print('EXPECTED_UNKNOWN_VS_ALIVE',ok);raise SystemExit(0 if ok else 1)
|
||||
raise SystemExit(rc)
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"secret_matches": [],
|
||||
"binary_files": []
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
None. All four TAP records report skipped 0.
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"base": "f40f2e770e0d8be394f1ef53b404045fd6a49c0e",
|
||||
"only_product_change": "while (now() <= deadline) -> for (;;)",
|
||||
"other_product_bytes_unchanged": true,
|
||||
"trailing_unknown_fallback": "unchanged; unreachable"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
/mnt/storage/scratch/tmp/gwxq
|
||||
Reference in new issue
Block a user