Skip to content

fix(pm): H44 stops reading a session id as a dateless tree tip - #18437

Merged
os-elon-musk merged 2 commits into
mainfrom
claude/issue-18385-h44-session-id-not-tree-tip
Sep 16, 2026
Merged

os-elon-musk merged 2 commits into
mainfrom
claude/issue-18385-h44-session-id-not-tree-tip

Conversation

@os-elon-musk

Copy link
Copy Markdown
Collaborator

Fixes #18385

H44_READING_FRAGMENTS's tree shape reads "7-40 hex characters carrying at least one letter and at least one digit". A session identifier satisfies that, and the row's remedy — add the time the reading was taken — applied to an identifier asks a seat to stamp a reading nobody took. On the board the card measured, 6 of 9 H44 rows in one sweep were exactly this. The failure direction is "a patrol row teaches the wrong discipline", not "a patrol row is noisy".

Before / after, measured on this branch

h44UntimestampedReading(body, false) fed claim-shaped strings. BEFORE is the module at the merge base (90b23ab1), AFTER is this branch's HEAD; both were imported into one process so the two readings are taken on the same inputs.

input (first line Claim: …) before after
Claim: PM session c5c0ce54 — dispatching this card FIRES · tree · c5c0ce54 quiet
Claim: PM 会话 c5c0ce54 派发本卡(席位 F)。 FIRES · tree · c5c0ce54 quiet
a Session: line carrying a backticked session_71836b57-5db6-459d-ae4d-c6d9d7dd2cc6 FIRES · tree · c6d9d7dd2cc6 (the UUID's last segment) quiet
⭐ CONTROL A — a dateless real tip, reviewed head + a backticked 480080c7a0 FIRES (correct) FIRES · tree · 480080c7a0
⭐ CONTROL B — the same tip plus at 2026-09-16T06:48Z quiet (correct) quiet
⭐ CONTROL C — a backticked session_01TAUTP6Yky8QWoHUAPDKNJQ quiet (correct) quiet

Six of six agree with the card's table before the change, and the two controls hold after it.

CONTROL D was found while measuring, and it moved the design. Over a corpus of 251 real comments from 30 recently-updated cards in this repo, the first spelling of the introduction leg ("the candidate's SENTENCE mentions a session") silenced exactly one comment — 5695539587, 「every harness-loaded path on origin/main is in this session's checkout HEAD 588475c3」 — which is a genuine dateless tip reading this row exists to file. A possessive three words away introduces nothing, so the leg was tightened to adjacency: only separators and decoration may stand between the word and the candidate. Re-measured on the same corpus afterwards: 251 comments, 12 fired before, 12 fired after, 0 changed — the narrowing takes the false positives and no live reading with them.

What changed

  • The tree shape itself is untouched and pinned as its regex source in the self-test, so a later widening of the token cannot ride in under this row. The change is an exclusion on the candidate, added as a per-shape exclude(paragraph, index, matched) seam declared on the tree entry alone, so the self-test drives it by name.
  • Two legs, both measured: the UUID leg (the candidate sits behind a hyphen or an underscore that itself follows a word character, i.e. it is the tail of a longer token) and the introduction leg (session / 会话 / session_ immediately before it, decoration only in between).
  • The lead a candidate is judged against is its own sentence, not its paragraph — the boundary the card left open, decided and pinned. Every claim comment carries a Session: line by template, so a paragraph-scoped test would silence H44 across the whole claim population, which is CONTROL A's habitat. A Session: line one line above a dateless tip therefore leaves the tip firing.
  • The paragraph is rescanned past an excluded candidate, and only for a shape that declares an exclusion. A comment that fired can change which fragment it names; a quiet one cannot start firing.
  • Declared residual: an intervening word (session id c5c0ce54) is not excluded — one measurement away, not a guess. It is pinned as a case in that direction.

Self-test

before after
whole file 4270 cases 4297 cases
H44 cases 105 132

node scripts/pm/check-half-states.mjs --self-test✓ check-half-states self-test: 4297 cases pass.

Ablation (two legs, each restored, each proven on disk before the run):

  1. Remove the one exclude: wiring line (occurrences 1 → 0 verified on disk): 9 of 4297 cases fail, including all three firing inputs and the whole rescan block.
  2. Loosen the introduction leg back to "the sentence mentions a session" (strict spelling 1 → 0, loose spelling injected 1, verified on disk): 6 of 4297 cases fail, led by CONTROL D — which is the measurement that chose adjacency.

Both legs restored from HEAD under a trap; after each, git status --porcelain is empty and git hash-object on the file equals the HEAD blob hash.

Gates

node scripts/pm/dispatch-gates.mjs --commands (no paths) derived 40 commands; all 40 ran in the foreground with exit codes captured before any pipe, and all 40 exited 0. Reconciled: ✓ dispatch-gates --ran: 40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3). Heavy runs went through scripts/pm/os-verify-lock.sh (VERDICT command-exit 0 · held the lock 841s).

Named among them: pnpm check:pm-half-states (the self-test, 4297 pass), pnpm check:nul-bytes (OK (scanned 8721 text file(s) … no raw ASCII control bytes)), pnpm check:pm-dispatch-gates, node scripts/check-self-test-wired.mjs (and its --self-test), node scripts/check-scripts-symbol-anchors.mjs and pnpm check:commit-card-trailers.

Lint, as a declared narrowing (the repo-wide pnpm lint is CI's run): ① the population is read from eslint's own config — ESLint#isPathIgnored over the tracked JS/TS set says 6786 of 6786 files are in scope; ② the targeted run npx eslint scripts/pm/check-half-states.mjs --no-inline-config --format json reports 1 file linted, 0 errors, 0 warnings (count read from the JSON); ③ invariance: eslint.config.mjs states in its own text that this repo "runs one eslint.config.mjs, which never enables type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY file", so a one-file diff cannot move the verdict on any file it did not touch.

Changeset

No changeset. AGENTS.md, Post-Task Checklist step 3, the line acted on: 「⛔ never skip-changeset: that label is for a diff that publishes nothing from any released package」 — this diff is one file under scripts/pm/**, which no package's files[] ships, so the skip-changeset label is the declaration and a changeset would be the wrong one. Clause-②: no.

Acceptance notes

  • Scope held to the H44 region. Only H44_READING_FRAGMENTS's tree entry, h44UntimestampedReading and the new helpers beside them are touched, plus H44 self-test cases appended after the existing H44 block. The H38 region and its cases, the file's tail entry/argv parser and the H64 region are untouched — those are other cards in flight on this same file, and the hunks are kept tight so the later lander merges cleanly.
  • The row's remedy sentence (h44UntimestampedReadingRow) is unchanged: it is now only ever rendered for a reading, so it stays truthful without an edit. The card asked for the predicate, not a new message.
  • Noted, not filed: the H44_READING_TIMESTAMP paragraph leg means a claim whose Session: line and tip share one paragraph WITH a stamp elsewhere in that paragraph is clean for a reason unrelated to this change. Carrier for that reading: none — no open card and no PR touches that leg, and it is the row's declared design, not a defect.
  • Noted, not filed: the introduction leg knows two words (session, 会话). A board that writes 「席位」 or another coinage beside a shorthand id would fire again. Carrier: the next H44 patrol row that shows one — a spelling nobody has measured is not a defect to file today.
  • out of scope: [finding] check-half-states.mjs H64's rationale prose still quotes the retired 「REST 按会话为 claude[bot] 或用户」 premise — the code enforces the landed rule, the header explains it with the fact platform-readings retired #18393 remains open — the H64 half of the card's adjacent reading is that card's, not this one.

Generated by Claude Code

`H44_READING_FRAGMENTS`'s `tree` shape is 7-40 hex characters carrying both
a letter and a digit, and a session identifier satisfies it: on one live board
6 of 9 H44 rows in a sweep were 「PM session c5c0ce54」/「PM 会话 c5c0ce54」
or the LAST SEGMENT of a `session_<uuid>` line, where the hyphen is a word
boundary. The row's remedy — add the time the reading was taken — applied to an
identifier asks a seat to stamp a reading nobody took, so the row taught the
wrong discipline rather than merely being noisy.

The `tree` shape itself is unchanged (pinned by its regex source). What is
added is narrowing 4: a per-shape `exclude` predicate, declared on the `tree`
entry alone, that drops a CANDIDATE which is lexically part of an identifier —
the tail of a longer token behind a flush `-`/`_`, or one introduced
immediately by `session` / `会话` / `session_`. The introduction leg reads
ADJACENCY rather than 「the sentence mentions a session」 because the loose
spelling silenced a real dateless tip reading measured on this board
(「this session's checkout HEAD `588475c3`」), which is pinned as CONTROL D.

The paragraph is rescanned past an excluded candidate for a shape that
declares an exclusion, so a comment that fired can change which fragment it
names but a quiet one cannot start firing.

Self-test: 4270 -> 4297 cases, H44 105 -> 132. CONTROL A (a dateless real tip)
still fires and CONTROL B (the same tip stamped) stays quiet.

Claude-Session: https://claude.ai/code/session_01HPfcjvF23QBoBj7P47DDxs
Co-authored-by: Claude <noreply@anthropic.com>
… the verdict

A case that dereferences a null match throws, and the throw takes the whole
self-test down before its verdict line — every sibling reading in the run is
hidden with it. Measured while ablating the introduction leg: the run died on
one case instead of reporting the rows that had gone red.

Claude-Session: https://claude.ai/code/session_01HPfcjvF23QBoBj7P47DDxs
Co-authored-by: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 4fa9580a148ce6935671be26eb8e9115619173fd

Skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T10:40Z — in-seat review of the dispatched dev's PR for #18385 (claim 5695659064, Clause-②: no; ACCEPT on the card records the checklist).

① Derived judgments

  • Accept / reject set: the change touches no runtime contract, no packages/spec path, no error code and no public export of a released package. It narrows what the report-only patrol row H44 FILES (a tree candidate that is lexically part of an identifier is no longer a finding); the tree regex itself is unchanged (/\b(?=[0-9a-f]*[a-f])(?=[0-9a-f]*\d)[0-9a-f]{7,40}\b/ on both sides). Direction: quieter only — h44AdmittedMatch rescans a paragraph only for a shape declaring exclude, so a paragraph that was quiet cannot start firing. Judged correct against the grading's direction (5695031295): an exclusion on the candidate, never a loosening for real tips (CONTROL A still fires, measured by the seat at this head).
  • Public surface: three new exports (H44_IDENTIFIER_INTRO, H44_SENTENCE_BREAKS, h44SentenceLead, h44TreeCandidateIsIdentifier, h44AdmittedMatch) in an internal PM script that no package publishes — not a published surface, no Clause-②: yes owed.
  • The Clause-②: no declaration on the claim is consistent with the diff (no widening tell: no new key on a published payload, no new member of a published enum, no new export from a released package).

② Semver level

None owed: scripts/pm/** is shipped by no package's files[]; skip-changeset applied by the dev is AGENTS.md's own arm for a diff that publishes nothing. No changeset expected, none present — consistent.

③ Boundary flags

  • Dev open_questions: empty. Dev deviation 「sentence → adjacency」: answered above (accepted, pinned by CONTROL D and a 251-comment corpus reading with 0 changed rows).
  • Region boundary: the diff's hunks sit at the H44 banner / fragments / reading function and the H44 case block; no hunk in H38, H64 or the entry parser — the parallel cards' regions are untouched.
  • Self-test at this head: 4297 cases pass (seat's own run on a detached worktree).

Implemented-by: claude/issue-18385-h44-session-id-not-tree-tip
Reviewed-by: session_01HPfcjvF23QBoBj7P47DDxs

VERDICT: PASS


Generated by Claude Code

@os-elon-musk
os-elon-musk marked this pull request as ready for review September 16, 2026 12:18
@os-elon-musk
os-elon-musk added this pull request to the merge queue Sep 16, 2026

Copy link
Copy Markdown
Collaborator Author

Landing provenance — skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T12:18Z. In-seat contract review PASS 5696151261 on head 4fa9580a (Served-tier: CONTRACT_REVIEW_TIER); ACCEPT 5696150912 on #18385. Non-governed ⇒ in-seat landing. Held since 10:40Z on the parity gate's 2 MiB size skip (this PR's merged size 2,109,808 B on today's main would have been reported as a stale registry row); the fix, PR #18449 (#18435), merged as e4449b4e at 2026-09-16T12:16:28Z and is on origin/main. Pre-checks: ① that record ✓ · ② check-clause2-carriers.mjs --pair 18437 exit 0 (re-run at landing) ✓ · ③ every check-run on 4fa9580a success or a rostered skip (check-expected-skips.mjs VERDICT OK, 11 skips all in the roster) ✓. Landed by the seat through the CCR routes at 2026-09-16T12:18Z: POST …/ccr/ready_for_review (200; ready_for_review 12:18:11Z) then PUT …/ccr/auto_merge {"merge_method":"SQUASH"} (200; added_to_merge_queue 12:18:12Z). Its merge group merges origin/main (PR #18444's H64 re-key and PR #18430's argv parser now on it) and re-runs the self-test in CI. Tracked to MERGED with the two readings. Card #18385 stays pm:dispatched + assignee until Fixes closes it.


Generated by Claude Code

Merged via the queue into main with commit e915c19 Sep 16, 2026
39 checks passed
@os-elon-musk
os-elon-musk deleted the claude/issue-18385-h44-session-id-not-tree-tip branch September 16, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants