Skip to content

fix(pm): stop the slot-ageing comment claiming a per-reset empty ledger (#12828) - #12916

Merged
os-elon merged 2 commits into
mainfrom
claude/issue-12828-ledger-population-comment
Aug 28, 2026
Merged

fix(pm): stop the slot-ageing comment claiming a per-reset empty ledger (#12828)#12916
os-elon merged 2 commits into
mainfrom
claude/issue-12828-ledger-population-comment

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#12828

Comment-only change to scripts/pm/os-verify-lock.sh. No behaviour, no output, no contract, no printed string.

What was wrong

The paragraph that explains why SLOT_MAX_AGE_S cannot be sized against a p95 reasoned from a mechanism, and the mechanism does not hold:

holds: it lives in this container's /tmp and starts empty on every reset, so
the population it holds is one shift's worth of whatever ran since

Re-measured, on a second box, before touching anything

The card measured one container. This branch measured a second, with the card's own instrument discipline — both controls in one command, because a zero is only a reading if the instrument can also return non-zero.

card, 2026-08-28T01:00Zthis branch, 2026-08-28T08:26Z
/proc/uptime608s, derived boot 00:50:13Z619s, derived boot 08:15:53Z
ledger74 records, first 2026-08-27T16:51:12Z14 records, first 2026-08-28T06:12:34Z
ledger file birth (stat %W)2026-08-27T16:51:12Z2026-08-28T06:12:34Z
records at or after derived boot00
records before derived boot74, oldest by 8h11m14, oldest by 2h03m
positive control (file touched then)read as AFTER derived bootread as AFTER derived boot
negative control (PID 1 vs boot)started 0.32s afterstarted 0.27s after

Both ledger files, and every record in them, predate the boot the uptime clock reports. The positive control says the comparison is live — it can return the other answer. The negative control says /proc/uptime and the process tree agree with each other, which is what forces the reading from "the clock is wrong" to "the filesystem did not restart with them".

The two readings are against two different ledger files (different birth times, different record counts), so this is a second independent reading, not a re-read of the first.

What the comment says now

Only what holds: the ledger's population starts where the ledger file starts and no earlier, for reasons nobody has characterised. Plus, in as many words, the boundary the card was careful about:

⚠️The retired sentence is quoted verbatim inside the replacement, deliberately: someone who greps for starts empty on every reset — the phrasing the finding names — lands on its retraction rather than on nothing. So a grep for that literal still returns 1 hit, and that hit is now a quotation being refuted, not a claim.

Scope

Verification

Gate union re-run after the final commit, at 6ea12f25. Families re-derived from the actual diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (10 families, identical to the dispatch-time list — nothing added, nothing dropped). Each verdict below is the line the gate itself printed.

checkverdict line
bash -n scripts/pm/os-verify-lock.shexit 0
bash scripts/pm/os-verify-lock.sh --self-test✓ os-verify-lock self-test: all cases pass. (185 case lines + summary = 186 ✓; 0 failures)
check:agent-test-spelling✓ 0 violations — 391 file(s) · 4331 bare -- token(s) · 1207 launcher-rooted run(s) · 9 separator(s) JUDGED
check:bash32-floor✓ 22 tracked shell file(s) under scripts/**, .claude/hooks/**, .githooks/** name no bash 4+ construct (self-test: 153 cases)
check:cli-command-ids✓ 288 command-id literal(s) across 104 file(s) ... all resolve (self-test: 39 cases)
check:cross-package-test-inputsOK: 20 package(s) read outside themselves, all declared
check:entry-guard✓ 172 scripts/ file(s) — every entry guard goes through invoked-as.mjs (self-test: 54 cases)
check:parse-guard✓ 171 scripts/ file(s) — every TypeScript parse goes through ts-parse.mjs (self-test: 46 cases)
check:pnpm-filter-targets✓ 140/177 --filter occurrence(s) across 30 file(s) resolve against 78 workspace package(s)
check:watch-hint-literal✓ 15 ROOT_DIR_WATCH_HINTS declaration(s), every one an array of quoted literals (self-test: 29 cases)
scripts/check-ci-filter-parity.mjsOK: all 109 declared cross-package glob(s) (84 unique) are covered
scripts/check-cross-package-test-inputs.mjsOK: 20 package(s) read outside themselves, all declared
check:nul-bytescheck-nul-bytes: OK (scanned 7176 text file(s) ... no raw ASCII control bytes)

Plus a direct byte scan of the edited file for raw control characters: no match.

The self-test is the file's own suite and the one CI runs (lint.yml, "Verify-lock entry-point self-test"); no case pins this paragraph — the bash-3.2 source scan at the top of the self-test region excludes comment lines by construction, and a repo-wide grep found no gate, workflow or test that reads this comment's text.

Heavy steps ran through the shared lock (os-verify-lock.sh -- bash ..., slot issue-12828), each hold reported VERDICT command-exit 0 · held the lock 122s.

Repo-wide pnpm lint narrowed, and the narrowing is measured, not assumed.pnpm exec eslint --no-inline-config --format json scripts/pm/os-verify-lock.sh returns File ignored because no matching configuration was supplied., errorCount: 0 — so (1) the population is read from eslint's own config resolution rather than from an assumption about which files count, (2) the count from --format json is 1 result and 0 files actually linted, and (3) the diff touches no eslint config, no manifest and no tsconfig, so eslint's judgment of any untouched file cannot move. The diff's only file is outside eslint's population entirely.

Changeset

None, and skip-changeset applied. Derived rather than asserted — git log receipt over the last commits touching this file:

4a7e1b07 fix(pm): head --report's hold bucket by the filter it actually applies changeset-files=0
5ced18ac fix(pm): make --report state the population it is computed over changeset-files=0
7d587ac1 fix(pm): stop --report labelling the arrival depth as "waiters ahead" changeset-files=0
347a7b39 fix(pm): make the verify lock state the coverage boundary it lacks changeset-files=0
ead73175 fix(pm): serve a verify-lock queue whose holds outlast one turn changeset-files=0
516b213d fix(pm): os-verify-lock reads a redirection's & as a redirection changeset-files=0
e966c592 fix(pm): stop --report presenting command-exit as one certified pop. changeset-files=0
c8bf50f5 fix(pm): stop the verify-lock VERDICT certifying a batch it cannot changeset-files=0
c312a562 feat(pm): measure the verify lock, and stop a queued caller losing place changeset-files=0

Nine consecutive scripts/pm/**-only changes, zero changesets. scripts/pm/** publishes nothing, so this PR declares no release of its own.


Generated by Claude Code

…er (#12828)
The paragraph explaining why `SLOT_MAX_AGE_S` cannot be sized against a p95
reasoned from a mechanism that was measured not holding: "it lives in this
container's /tmp and starts empty on every reset".
Measured twice, against two different ledger files, each reading carrying both
controls in one command:
2026-08-28T01:00Z uptime 608s 74 records, oldest 8h11m BEFORE derived boot
2026-08-28T08:26Z uptime 619s 14 records, oldest 2h03m BEFORE derived boot
In both, the ledger file's own birth time predated the reported boot too; a
file touched at that moment read as after the derived boot (so the comparison
can return either answer), and PID 1 started 0.32s / 0.27s after that boot (so
the uptime clock and the process tree agree with each other). It is the
filesystem that did not restart with them, not the clock that is wrong.
The comment now claims only what holds: the population starts where the ledger
FILE starts, for reasons nobody has characterised. It says in as many words
that the opposite premise is NOT claimed either — nothing here measured that
/tmp survives a reset; two readings disqualify a mechanism, they do not
establish its negation. The arithmetic conclusion is untouched and explicitly
noted as needing neither answer: it rests on the population being bounded and
thin, never on why it begins where it does.
Comment-only. No behaviour, no output, no contract.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
@os-elonClaude

Copy link
Copy Markdown
CollaboratorAuthor

⚠️ Held, not armed — Lint & Repo Gates is red for a defect that is not this PR's

domain:devx seat, session session_01CPrUz21stTFhJRUirdc4yw, R24. Posting once rather than re-running, per the standing rule that a base-branch failure is neither this PR's to fix nor a flake to re-roll.

The failing check and its exact signature:

✗ check-adr-anchors --self-test — 1 failure(s) of 106 assertion(s)
• live-decision-letters-are-green-today
ADR-0006 D4 is cited by 1 file(s), but ADR-0006 declares no D4 —
it decides: D1, D1.1, D1.2, D1.3, D2, D3
packages/spec/src/data/object.zod.ts

Why it is not this PR's, established rather than asserted:

  1. This PR's entire diff is one comment block in scripts/pm/os-verify-lock.sh — 1 file, +34/−8, no behaviour. packages/spec/src/data/object.zod.ts is not in it and cannot be reached from it.
  2. main is red on its own. Re-run in a throwaway worktree checked out at origin/mainaef1b7e6 with nothing from this branch applied: MAIN_SELFTEST_EXIT=1, same single assertion. ⇒ base-branch red, reproduced away from this PR.
  3. The string was introduced by 4f24e9d2 (feat(spec,auth)!: one declared audience posture for self-registration — invite_only|email_domain|open, default invite_only #11767), measured with git log -S over that file.

Already owned elsewhere: #12913 (priority:p0, domain:spec, pm:queue) — "The merge queue is blocked repo-wide" — with #12910 as a duplicate of the same defect. This lane added its independent confirmation and the introducing commit to #12913 and is ⛔ not claiming, grading or fixing it: the repair lands in packages/spec, which belongs to the domain:spec seat, and choosing the right citation is a spec judgement (ADR-0006 v4 declares D1/D2/D3, none about namespace, so the fix may be "cite a different record" rather than "a different letter").

What happens to this PR: the ACCEPT above stands — everything in it was verified and every other check is green. It stays draft and unarmed until main goes green, because entry qualification is every check green, ⛔ not the required subset, and enqueueing now would just eject. ⛔ No re-run has been spent: a re-run cannot fix a deterministic assertion about the base tree.

This seat holds it and will arm it once the p0 lands.


Generated by Claude Code

@os-elonClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my hold note above, point 3 only: I wrote that the ADR-0006 D4 string was introduced by 4f24e9d2 (#11767). Wrong. It is 7bba90b06, 2026-08-01 (#4522) — a 27-day-latent citation exposed by a correct gate landing today (8c0b5cf06, #12785).

My git log -S ran against a shallow clone horizoned at 2026-08-25, so it could not see the introduction and named the oldest visible commit that touched the line, exiting 0 with a plausible wrong answer — the failure scripts/pm/git-history.mjs refuses rather than commits. Full correction on #12913.

Points 1 and 2 are unaffected and are what the hold rests on: this PR's diff is one comment block in scripts/pm/os-verify-lock.sh, and main is red on its own (MAIN_SELFTEST_EXIT=1 at origin/mainaef1b7e6, clean worktree). The PR stays draft and unarmed until main is green.


Generated by Claude Code

@os-elon
os-elon marked this pull request as ready for review August 28, 2026 09:40
@os-elon
os-elon enabled auto-merge August 28, 2026 09:40
@os-elon
os-elon added this pull request to the merge queueAug 28, 2026
Merged via the queue into main with commit e5f6621Aug 28, 2026
31 checks passed
@os-elon
os-elon deleted the claude/issue-12828-ledger-population-comment branch August 28, 2026 09:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-elon@claude