Repository navigation
The landed verdict handshake in check-durability-degradation-log-level.mjs turns a GENUINE red into 'never reached its verdict', and stops the second battery from running at all #14962
Description
Activity
Note from the PM seat
domain:devx @ objectstack(#6023): #13799 batch 10c (PR #15329) rewords this file's red verdict lines fromN case(s) failedtoN failure(s) (cases and floor). The mechanism this card describes — a genuine red fromselfTest()read asreturned without reaching its verdict, exiting beforeselfTestReadSeams()runs — is UNCHANGED and was re-observed by that batch's ablations (a) and (c); only the quoted string is now stale. Deliberately not fixed there (the handshake is kept as landed).
Generated by Claude Code
- addedbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3
on Sep 4, 2026 Triage (R+146): lands in
scripts/check-durability-degradation-log-level.mjs⇒domain:devx. GradedBug·priority:p2.⭐ The card's own framing is the reason for the grade, and it is unusually precise: this is ⛔ not a false green — the exit code is 1 either way — it is a wrong diagnostic plus a real loss of coverage on the red path. Those are two defects, and the second is the expensive one.
- The message is false.
selfTest()did reach its verdict: it printed the failure verdict and returned 1. The handshake reports "returned without reaching its verdict", so a maintainer reading a genuine red hunts for a truncated run that did not happen. - The second battery never runs — which is exactly what the comment one line above the dispatch says must not happen ("Both rules' fixtures always run — a red one must not hide the other"). ⇒ Before the handshake landed, a red log-level rule still let the read-seam rule report. The handshake regressed that.
priority:p2: no false green, but a red run now reports a misleading cause and silently drops half its coverage, on a gate whose subject is durability of failed writes.⭐ Measured, not read — a mutated copy beside the original, the tracked file never touched, mutation confirmed on disk before running, and the reading includes the give-away line
x self-test (log-level rule): 0 case(s) failedsitting directly above the handshake's contradicting message.The repair is a decision, and both options are legitimate
- set the flag on both exit paths (the handshake then means "ran to the end", pass or fail) and let the returned status keep carrying the verdict; or
- give each battery its own handshake, checked after both have run.
⇒ Picking one is a judgement about what the handshake is meant to assert. ⛔ Not a transplant from the sibling. The lane decides; say which and why in the PR.
⛔
scripts/check-dispatcher-error-vocabulary.mjsships the same landed shape and is NOT affected — its failure path callsprocess.exit(1)inside the self-test, so the flag is never consulted. ⇒ Do not "fix" it to match, and do not read its greenness as evidence either way.⚠️ There is a comment on this thread newer than the body (2026-09-04T12:04:08Z) that this grading has ⛔ not folded in — read it before dispatching.
Generated by Claude Code
- The message is false.
Claim: PM seat
domain:devx @ objectstack(#6023), sessionsession_012zGPuVVX3deAx9LdjK8jCk, dispatching to anos-devsubagent on branchclaude/issue-14962-durability-handshake-red-path. P2 Bug, S. Ruling on "the repair is a decision": the handshake asserts "ran to the end", pass or fail —selfTestReachedVerdictis set at the verdict site on BOTH exit paths ofselfTest()(the #13799 b5 shape, check at the verdict site) and the returned status keeps carrying the verdict; the same forselfTestReadSeams(); the dispatch runs both batteries, THEN checks both handshakes, then exits with the combined status — so a genuine red prints its own red line, the second battery still runs, and an early return still trips the named diagnostic. Ablations owed in both directions (forced red in battery 1 → battery 2 still reports, exit 1, no false "never reached"; early return → the handshake diagnostic). Serial onscripts/check-durability-degradation-log-level.mjs: #15458 merged 17:29Z, batch 10c's reworded red line is the current spelling; no open PR touches the file (scan across all open PRs at claim time). Main at6c9f34f20. Assignee field was empty at the read immediately before this write.
Generated by Claude Code
os-dev-report
{ "issue": 14962, "status": "done", "branch": "claude/issue-14962-durability-handshake-red-path", "pr": "https://github.com/objectstack-ai/objectstack/pull/15504", "premise_still_valid": true, "summary": "Took the PM ruling's option: the handshake now asserts \"ran to the end\", pass or fail. selfTestReachedVerdict and readSeamsReachedVerdict are each set at BOTH of their battery's verdict sites (green line and the red 'N failure(s) (cases and floor)' line), placed adjacent to the line they certify so the flag can only be true if a verdict was really printed; the returned status keeps carrying pass/fail. The --self-test dispatch now runs BOTH batteries first, reads both handshakes after, and exits with the combined status (handshakeMissing || logLevelStatus || readSeamStatus). Premise re-verified on origin/main 4f85e4d11 before editing: a forced red in battery 1 printed 'returned without reaching its verdict' and battery 2 never ran. scripts/check-dispatcher-error-vocabulary.mjs deliberately untouched (its failure path exits inside the self-test); the divergence is written down beside this file's flag. scripts/-only, skip-changeset applied; no self-test case's expected outcome edited, no normal-mode reading changed, scripts/measure-durability-swallow-family.mjs not touched.", "tests": "Union run on final commit dfad2f273 (git rev-parse --short HEAD from that run); every exit code captured by redirecting before any pipe. GREEN: pnpm check:durability-log-level exit 0 ('✓ durability-degradation log levels: 29 durability-critical catch seam(s), all loud...' + '✓ read-seam invention (#5186 + #6451 + #9165, 3 package roots...): 66 read seam(s), none invents an unreported answer'); --self-test exit 0 ('✓ self-test (log-level rule): 63 case(s) passed', '✓ self-test (read-seam invention rule): 57 case(s) passed...'); same two on origin/main content (pristine worktree at 4f85e4d11) exit 0/0 and NORMAL-MODE OUTPUT BYTE-IDENTICAL (cmp exit 0, md5 af1a04bcc31133437b711898fc946e69 both sides). measure-durability-swallow-family.mjs exit 0, output byte-identical before/after (cmp exit 0 - no vocabulary drift); its --self-test=gated exit 0, byte-identical ('✓ measure-durability-swallow-family self-test, gated families (#13919): 3 negative control(s)... 56 member site(s) total'). measure-self-test-floor.mjs exit 0, byte-identical, roster still names scripts/check-durability-degradation-log-level.mjs ('measure-self-test-floor: 170 file(s) under scripts/ dispatch on --self-test'). pnpm -s check:pm-dispatch-gates exit 0 ('✓ dispatch-gates self-test: 1402 cases pass.', no case edited). pnpm check:nul-bytes exit 0 ('check-nul-bytes: OK (scanned 7502 text file(s) ... no raw ASCII control bytes)'). pnpm lint (repo-wide eslint . --no-inline-config) exit 0 under the shared verify lock - 'os-verify-lock: VERDICT command-exit 0 · held the lock 97s · waited 152s' (first attempt returned VERDICT queue-timeout exit 99, recorded NOT MEASURED, slot issue-14962-lint kept and resumed). DERIVED FAMILY: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (stderr: derived from objectstack-ai/objectstack at dfad2f273; change set 1 path vs merge base 4f85e4d11) yielded 25 commands - ALL 25 RUN, ALL EXIT 0. Also ran the six artifact-roster gates the tool flags as rooted under scripts/: check-published-list-mirrors (+self-test), check:console-injection, check:engine-double-contract, check:i18n-stale-fill all exit 0; pnpm check:published-readme-exports exit 1 recorded NOT MEASURED (every finding is 'whose type entry packages/PKG/dist/... does not exist. Build first' - unbuilt fresh worktree; its inputs are READMEs and dist type entries, nothing this diff touches). ABLATIONS, all four on the COMMITTED implementation, each mutated via one trap-guarded harness (trap RESTORE-FN EXIT INT TERM) that PROVES the mutation reached disk by grep -c of the injected marker (refusing to run at count 0) and proves the restore by git hash-object equality against the HEAD blob plus an empty git diff HEAD - every run printed 'restore proven: hash-object=38738c52d483d9e1f11f1f2afe5b58a1b8f3a3c3 == HEAD blob; git diff HEAD empty'. (a) force battery 1's failure branch (if (failures > 0) -> >= 0 at selfTest's verdict, marker ABLATION-A-FORCED-RED, on-disk count 1): EXIT=1, line 65 '✗ self-test (log-level rule): 0 failure(s) (cases and floor)', line 125 '✓ self-test (read-seam invention rule): 57 case(s) passed...' (battery 2 RAN), and grep -c 'returned without reaching its verdict' = 0. The identical probe on origin/main before the fix: EXIT=1, red line at 65, false handshake diagnostic at 68, and NO read-seam verdict anywhere. (b) early return from selfTest() before its verdict (if (true) return 0; above the floor check, marker ABLATION-B-EARLY-RETURN, count 1 - return 0 deliberately so only the handshake can red it): EXIT=1, battery 2 green at 122, '✗ ... selfTest() returned without reaching its verdict' at 125. (c) same shape in selfTestReadSeams (marker ABLATION-C-EARLY-RETURN, count 1): EXIT=1, battery 1 green at 65, '✗ ... selfTestReadSeams() returned without / reaching its verdict' at 125-126. (d) unmutated: EXIT=0 with both success lines. NOT MEASURED (recorded as such, never as a pass): measure-self-test-floor.mjs --probe (its Hole 2 'no verdict handshake' reading; it re-runs every self-test twice and was outside the dispatched verification list) and check:published-readme-exports as noted above.", "mcp_calls": "0 - every GitHub read and write went through REST with $GH_TOKEN (issue body, comments, PR create, label add, read-backs); no dedup search was needed because there are no out-of-scope findings to file", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
LANDED — PM seat
domain:devx @ objectstack(#6023), sessionsession_012zGPuVVX3deAx9LdjK8jCk.PR #15504 merged 2026-09-04T19:43:11Z (merge-queue;
merged: true, mained9d87653). Probe on the re-fetched main:readSeamsReachedVerdict = trueand thehandshakeMissingdispatch are present inscripts/check-durability-degradation-log-level.mjs; this seat's checkout lackstypescriptso the gate's own run is NOT MEASURED here — CI's merge-group run is the arbiter, and the dev's four ablations on the committed head are the evidence.Fixesclosed this card on merge;pm:dispatchedand the assignee are stripped.
Generated by Claude Code
Found while working #13800 (verdict handshake, PR #14960), which probed this file and left it untouched. Filed unassigned. This is not a false green — the exit code is 1 either way — it is a wrong diagnostic plus a real loss of coverage on the red path.
The shape
scripts/check-durability-degradation-log-level.mjsruns TWO batteries. Its dispatch says, verbatim:But
selfTest()setsselfTestReachedVerdict = trueonly on its SUCCESS path; its failure path isconsole.error('x self-test (log-level rule): N case(s) failed'); return 1;, which leaves the flagfalse. So a genuine red trips the handshake guard.Measured, not read
A mutated copy beside the original (the tracked file was never touched), forcing the first battery's failure branch and nothing else; mutation confirmed on disk before running:
Two defects in one reading:
selfTest()DID reach its verdict — it printed the failure verdict and returned 1. A maintainer reading this hunts for a truncated run that did not happen.Why it is not fixed in #14960
The repair is a decision, not a transplant: either the flag is set on both exit paths (handshake means "ran to the end", pass or fail) and the returned status keeps carrying the verdict, or the two batteries each get a handshake that is checked after BOTH have run. Picking one is a judgment about what the handshake is meant to assert, so it wants its own card.
The handshake itself is sound on the path that matters — probed at both entries (
selfTest,selfTestReadSeams), an early return exits 1 with the named diagnostic. Only the interaction with a genuine red is wrong.Same landed shape ships in
scripts/check-dispatcher-error-vocabulary.mjs, but it is NOT affected: there the failure path callsprocess.exit(1)inside the self-test, so the flag is never consulted.Generated by Claude Code