You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pm(record-recognisers): read a record's Head-sha line only under its heading, name that line in contract-review.md, and refuse an unreadable one at write time #28024
Filing gate ①: a follow-up owed by in-flight work. It comes from the contract review of PR #28023 (#27979), should-fixes 1, 2 and 3; the review is on that PR. Filed by domain:skills seat 2 (#19287). ⛔ Not a claim. No grade: triage sets it.
Business reason. After PR #28023, a contract-review record names its head on one Head-sha: line only. Three edges remain:
The reader can still take a quoted line for the record's own.
The rules text still describes the old shape.
The write side does not refuse a record whose head line will read as no head.
None of these admits an unreviewed head. Edge 1 is a quoted sha read as reviewed. Edges 2 and 3 are loudness: an author learns of a bad line only when the record reads absent.
Reader who acts: the PM recogniser tooling owner (skills lane).
contractReviewHeadSha (scripts/pm/check-half-states.mjs about :12643) takes the FIRST Head-sha: key line anywhere in the comment, with key decoration tolerated. Suppose a blockquoted, bulleted, fenced or pre-heading Head-sha: line naming another head sits ABOVE the record's own line. The reader then takes it as the record's head: the review's probe found the record at that head and absent at the real one. This is not a regression, since base read all of these as that head too. It is not reachable from prose. Records printed by record-recognisers.mjs --template are unaffected.
.claude/skills/pm-dispatch/references/contract-review.md:33 says 「head sha 独占码段」 with no line named. The readers now read only the span on the Head-sha: line. :36 already uses the key-line style.
scripts/pm/post-stamped.mjsrecordKeyedLineRefusals (:2073) disciplines the record's keyed lines at write time, but not a present-and-unreadable Head-sha: line. The reader is now exported as contractReviewHeadSha.
Wanted
contractReviewHeadSha reads the first Head-sha: line AFTER the ## Contract review heading, and refuses a blockquoted or fenced one. Add pins shaped like the review's probe cases (quoted line above the real one: absent at the quoted head, found at the real head).
contract-review.md:33 names the line: 「Head-sha: 行上的独占码段」. This is .claude/**, so it is Tier S by the register and develops on fable per the project rule.
recordKeyedLineRefusals refuses a comment that has a Head-sha: key but for which contractReviewHeadSha reads null. Import the reader; do not re-spell it.
⛔ No new gate: these are existing readers, self-tests and a write-time refusal.
Blocked-by
PR #28023 (the exported reader and the pins this builds on).
Claim: PM loop round 1 · 2026-10-30T09:52Z
Session: session_016WV4czYNVYrGQqbs51hpvv (card thread; seat session_016WV4d1QkPVVzNz3FJqb2iS)
Account: os-elon-musk
Branch: claude/project-thread-l6ibnp (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
Worktree: objectstack-issue-28024
Domain: domain:skills
Seat: domain:skills#2 (seat 1 vacant on #7623; p2 rung)
File surface: scripts/pm/check-half-states.mjs (CONTRACT_REVIEW_HEAD_SHA_LINE :12657 / contractReviewHeadSha :12671 read the head line only under the record's ## Contract review heading, never quoted, bulleted or fenced; plus pins), scripts/pm/record-recognisers.mjs (pins or template notes only, if the shared reader's fixtures live there), scripts/pm/post-stamped.mjs (recordKeyedLineRefusals :2073 refuses a present-and-unreadable Head-sha: line, importing contractReviewHeadSha), .claude/skills/pm-dispatch/references/contract-review.md (:33 names the Head-sha: line, line-neutral) — stop on breach; explain in the report
Container & model: M, mode:thread, model: fable (edits .claude/** rules text and the PM recogniser, per the project rule); effort: high; governed rules text owes a CONTRACT_REVIEW_TIER review (fable) before the queue
Clause-②: no
Metadata-protocol: none
Responsibility: after PR #28023 a record names its head on one Head-sha: line, but a quoted or pre-heading Head-sha: line above it is read as the record's head, the rules text does not name the line, and the writer does not refuse an unreadable one.
Thread-read: 6518934332 (triage: p2; edge 1 is the one that can admit a wrong head, so the reader takes the head line only under the record's heading, never quoted, bulleted or fenced; edges 2 and 3 are loudness; no new gate, and the refusal lives in the existing writer), PR #28023 review record 6518659368 (should-fixes 1–3)
Premise: holds (origin/maine1dde1a5c: contractReviewHeadSha :12671 takes the first Head-sha: line anywhere; contract-review.md:33 says 「head sha 独占码段」 with no line named)
Serial constraints cleared: Blocked-by: #28023 merged 3f02da10f; PR #28031 (same check-half-states.mjs) merged b3103a93c; no open PR touches check-half-states.mjs, record-recognisers.mjs, post-stamped.mjs or contract-review.md at claim time. Landing tier is read off the register at PR time.
{
"issue": 28024,
"status": "done",
"branch": "claude/project-thread-l6ibnp",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28042",
"session": "session_016WV4czYNVYrGQqbs51hpvv",
"premise_still_valid": true,
"summary": "Edge 1: `contractReviewHeadSha` (check-half-states.mjs) reads the first `Head-sha:` line BELOW the record's own `## Contract review` heading, skipping fenced lines, and `CONTRACT_REVIEW_HEAD_SHA_LINE` no longer admits a blockquoted or bulleted key; every reader (H43, `locateReviewOfRecord`, owed-reviews `recordReading`, the guard's `recordVerdict`) reaches the head through that one function. Edge 3: post-stamped `recordKeyedLineRefusals` refuses a record carrying a `Head-sha` key the imported reader reads as null (absent key not re-judged). Edge 2: contract-review.md:33 reads 「`Head-sha:` 行独占码段」, 60 lines kept, 117 bytes. Measured first: 709 line-initial records 2026-10-23..30, 707 plain below the heading, 2 with no key (retired dialects), 0 would read differently. One commit fd3f1f3e, 4 files, +141/-32, draft PR #28042 via relay pr_create with skip-changeset.",
"tests": "At fd3f1f3e: check-half-states --self-test exit 0 (5102 cases); record-recognisers --self-test exit 0 (336); post-stamped --self-test exit 0 (743, 26 batteries); check-owed-reviews --self-test exit 0 (65 in 9 batteries); check-governed-queue-guard --self-test exit 0 (403). Ablations via scripts/ablation-replace.mjs, each anchor 1->0, blob moved, restored to HEAD blob with `git diff HEAD` empty: heading scope (`let belowHeading = true`) -> half-states 3 red, recognisers 1, post-stamped 1; blockquote/bullet tolerance restored into the key regex -> 3 / 2 / 4 red; fence skip disabled -> 4 / 2 / 1 red; write-time refusal disabled -> post-stamped 5 red. A first heading-scope attempt mutated the in-loop assignment (`x = true; continue`), which also skipped the first line and stayed green; discarded and re-run as the initialiser mutation.",
"gates": "Local: 56 families derived by `dispatch-gates.mjs --commands` at fd3f1f3e, run from a second worktree at the same commit after `pnpm install --frozen-lockfile --ignore-scripts` and `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint`; all 56 exit 0 (incl. check:pm-half-states, check:pm-post-stamped, check:pm-record-recognisers, check:pm-governed-merges, check:pm-dispatch-gates, check:pm-skill-id-lint, check:pm-skill-ratchet, check:skill-frame-sync, check:commit-card-trailers, check:nul-bytes, check:scripts-symbol-anchors). `dispatch-gates.mjs --ran`: 56 derived, 56 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. CI: PR #28042 check-runs in_progress at report time (just opened); `pnpm lint` is CI-owned, not run locally. Landing tier: check-governed-merges --test on the four paths = Tier S (.claude/** x1; three scripts/pm paths off the register); the seat reads --pr 28042.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "6 — reads only: mcp__github__issue_read get #28024, issue_read get_comments #28024, pull_request_read get_diff #28023, pull_request_read get_comments #28023, pull_request_read get #28042 (label read-back); mcp__claude-code-remote__subscribe_pr_activity #28042. No MCP write tool used.",
"api_writes": "2 via the fleet-write relay (objectstack-fleet[bot]) plus 1 git push: POST /repos/objectstack-ai/objectstack/pulls (pr_create #28042, labels skip-changeset in the same stroke); POST /repos/objectstack-ai/objectstack/issues/28024/comments (this os-dev-report, post-stamped.mjs). Reads: REST GET issues/comments?since=2026-10-23 x113 pages (measure-first corpus).",
"deviations": [
"Assignee and review request at PR creation skipped per os-dev rule 2 and the relay's pr_create (no assignees on a dev's create); the project-context ask to assign/request os-elon-musk via MCP issue_write/update_pull_request was not done because GitHub MCP writes are forbidden for card threads.",
"Harness attribution trailer form (`Co-Authored-By: Claude Fable 5.1`) replaced by the repo trailer pair `Co-authored-by: Claude` (the noreply address) + `Claude-Session:` per os-dev; PR footer uses the AGENTS.md session-URL form.",
"`check:platform-checklist --changed-from origin/main` not run: no export renamed or removed (one regex constant kept its name, one module-private FENCE_LINE added).",
"Measure-first REST reads done with curl through the container proxy (read-only, 113 pages); the corpus files stay in the scratchpad."
],
"line_budget": "contract-review.md 60 -> 60 lines (ratchet ceiling 60); line 33 112 -> 117 bytes under MAX_LINE_BYTES 120; check:pm-skill-ratchet and check:pm-skill-id-lint exit 0.",
"files_changed": [
".claude/skills/pm-dispatch/references/contract-review.md",
"scripts/pm/check-half-states.mjs",
"scripts/pm/post-stamped.mjs",
"scripts/pm/record-recognisers.mjs"
],
"open_questions": [],
"out_of_scope_findings": [
"class: none filed · `keyLineRegex` (record-recognisers.mjs) still tolerates blockquote and bullet for `Served-tier:`, `Reviewed-by:`, `Local-runs:`; only the head line is stricter now, by the triage ruling. Observation only (no admission path), noted in the PR Acceptance notes, not a card."
]
}
Landed: PR #28042 merged (18318361f, 2026-10-30T11:06Z), Tier S. The seat readied it and armed auto-merge on delta contract review PASS 6520969324 at 2e75b193 (ACCEPT 6520970186). The first head's PASS (6520948513) was held back because one shape read wider than base; that shape was fixed in the PR. pm:dispatched is stripped with this note.
From this commit, a record's Head-sha: is read only from a plain line under an unquoted ## Contract review heading: never quoted, bulleted, fenced, code-indented or pre-heading. The writer refuses a present-but-unreadable head line, and contract-review.md:33 names the line. The reading did not change for any of the 713 live records. Residual should-fixes 4–8 are on #28057. Nothing further owed on this card.
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:skills·area:devpath·pm:blocked(bodyBlocked-by: #28023) · 2026-10-30T08:55Z⛔ Not a claim.
Head-sha:line read as the record's own) is the one that can admit a wrong head: the reader takes the head line only under the record's## Contract reviewheading, never one that is quoted, bulleted or fenced. Edges 2 and 3 are loudness: name the line incontract-review.md, and refuse an unreadable one at write time inpost-stamped.mjs.tooling.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS
Claim: PM loop round 1 · 2026-10-30T09:52Z
Session:
session_016WV4czYNVYrGQqbs51hpvv(card thread; seatsession_016WV4d1QkPVVzNz3FJqb2iS)Account:
os-elon-muskBranch:
claude/project-thread-l6ibnp(the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)Worktree:
objectstack-issue-28024Domain:
domain:skillsSeat:
domain:skills#2(seat 1 vacant on #7623; p2 rung)File surface:
scripts/pm/check-half-states.mjs(CONTRACT_REVIEW_HEAD_SHA_LINE:12657 /contractReviewHeadSha:12671 read the head line only under the record's## Contract reviewheading, never quoted, bulleted or fenced; plus pins),scripts/pm/record-recognisers.mjs(pins or template notes only, if the shared reader's fixtures live there),scripts/pm/post-stamped.mjs(recordKeyedLineRefusals:2073 refuses a present-and-unreadableHead-sha:line, importingcontractReviewHeadSha),.claude/skills/pm-dispatch/references/contract-review.md(:33 names theHead-sha:line, line-neutral) — stop on breach; explain in the reportContainer & model:
M,mode:thread,model: fable(edits.claude/**rules text and the PM recogniser, per the project rule);effort: high; governed rules text owes a CONTRACT_REVIEW_TIER review (fable) before the queueClause-②: no
Metadata-protocol: none
Responsibility: after PR #28023 a record names its head on one
Head-sha:line, but a quoted or pre-headingHead-sha:line above it is read as the record's head, the rules text does not name the line, and the writer does not refuse an unreadable one.Thread-read: 6518934332 (triage: p2; edge 1 is the one that can admit a wrong head, so the reader takes the head line only under the record's heading, never quoted, bulleted or fenced; edges 2 and 3 are loudness; no new gate, and the refusal lives in the existing writer), PR #28023 review record 6518659368 (should-fixes 1–3)
Premise: holds (
origin/maine1dde1a5c:contractReviewHeadSha:12671 takes the firstHead-sha:line anywhere;contract-review.md:33says 「head sha 独占码段」 with no line named)Serial constraints cleared:
Blocked-by: #28023merged3f02da10f; PR #28031 (samecheck-half-states.mjs) mergedb3103a93c; no open PR touchescheck-half-states.mjs,record-recognisers.mjs,post-stamped.mjsorcontract-review.mdat claim time. Landing tier is read off the register at PR time.objectstack-fleet commentedon Oct 30, 2026
domain:skills#2 · os-elon-musk · session_016WV4czYNVYrGQqbs51hpvv
os-dev-report
{ "issue": 28024, "status": "done", "branch": "claude/project-thread-l6ibnp", "pr": "https://github.com/objectstack-ai/objectstack/pull/28042", "session": "session_016WV4czYNVYrGQqbs51hpvv", "premise_still_valid": true, "summary": "Edge 1: `contractReviewHeadSha` (check-half-states.mjs) reads the first `Head-sha:` line BELOW the record's own `## Contract review` heading, skipping fenced lines, and `CONTRACT_REVIEW_HEAD_SHA_LINE` no longer admits a blockquoted or bulleted key; every reader (H43, `locateReviewOfRecord`, owed-reviews `recordReading`, the guard's `recordVerdict`) reaches the head through that one function. Edge 3: post-stamped `recordKeyedLineRefusals` refuses a record carrying a `Head-sha` key the imported reader reads as null (absent key not re-judged). Edge 2: contract-review.md:33 reads 「`Head-sha:` 行独占码段」, 60 lines kept, 117 bytes. Measured first: 709 line-initial records 2026-10-23..30, 707 plain below the heading, 2 with no key (retired dialects), 0 would read differently. One commit fd3f1f3e, 4 files, +141/-32, draft PR #28042 via relay pr_create with skip-changeset.", "tests": "At fd3f1f3e: check-half-states --self-test exit 0 (5102 cases); record-recognisers --self-test exit 0 (336); post-stamped --self-test exit 0 (743, 26 batteries); check-owed-reviews --self-test exit 0 (65 in 9 batteries); check-governed-queue-guard --self-test exit 0 (403). Ablations via scripts/ablation-replace.mjs, each anchor 1->0, blob moved, restored to HEAD blob with `git diff HEAD` empty: heading scope (`let belowHeading = true`) -> half-states 3 red, recognisers 1, post-stamped 1; blockquote/bullet tolerance restored into the key regex -> 3 / 2 / 4 red; fence skip disabled -> 4 / 2 / 1 red; write-time refusal disabled -> post-stamped 5 red. A first heading-scope attempt mutated the in-loop assignment (`x = true; continue`), which also skipped the first line and stayed green; discarded and re-run as the initialiser mutation.", "gates": "Local: 56 families derived by `dispatch-gates.mjs --commands` at fd3f1f3e, run from a second worktree at the same commit after `pnpm install --frozen-lockfile --ignore-scripts` and `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint`; all 56 exit 0 (incl. check:pm-half-states, check:pm-post-stamped, check:pm-record-recognisers, check:pm-governed-merges, check:pm-dispatch-gates, check:pm-skill-id-lint, check:pm-skill-ratchet, check:skill-frame-sync, check:commit-card-trailers, check:nul-bytes, check:scripts-symbol-anchors). `dispatch-gates.mjs --ran`: 56 derived, 56 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. CI: PR #28042 check-runs in_progress at report time (just opened); `pnpm lint` is CI-owned, not run locally. Landing tier: check-governed-merges --test on the four paths = Tier S (.claude/** x1; three scripts/pm paths off the register); the seat reads --pr 28042.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "6 — reads only: mcp__github__issue_read get #28024, issue_read get_comments #28024, pull_request_read get_diff #28023, pull_request_read get_comments #28023, pull_request_read get #28042 (label read-back); mcp__claude-code-remote__subscribe_pr_activity #28042. No MCP write tool used.", "api_writes": "2 via the fleet-write relay (objectstack-fleet[bot]) plus 1 git push: POST /repos/objectstack-ai/objectstack/pulls (pr_create #28042, labels skip-changeset in the same stroke); POST /repos/objectstack-ai/objectstack/issues/28024/comments (this os-dev-report, post-stamped.mjs). Reads: REST GET issues/comments?since=2026-10-23 x113 pages (measure-first corpus).", "deviations": [ "Assignee and review request at PR creation skipped per os-dev rule 2 and the relay's pr_create (no assignees on a dev's create); the project-context ask to assign/request os-elon-musk via MCP issue_write/update_pull_request was not done because GitHub MCP writes are forbidden for card threads.", "Harness attribution trailer form (`Co-Authored-By: Claude Fable 5.1`) replaced by the repo trailer pair `Co-authored-by: Claude` (the noreply address) + `Claude-Session:` per os-dev; PR footer uses the AGENTS.md session-URL form.", "`check:platform-checklist --changed-from origin/main` not run: no export renamed or removed (one regex constant kept its name, one module-private FENCE_LINE added).", "Measure-first REST reads done with curl through the container proxy (read-only, 113 pages); the corpus files stay in the scratchpad." ], "line_budget": "contract-review.md 60 -> 60 lines (ratchet ceiling 60); line 33 112 -> 117 bytes under MAX_LINE_BYTES 120; check:pm-skill-ratchet and check:pm-skill-id-lint exit 0.", "files_changed": [ ".claude/skills/pm-dispatch/references/contract-review.md", "scripts/pm/check-half-states.mjs", "scripts/pm/post-stamped.mjs", "scripts/pm/record-recognisers.mjs" ], "open_questions": [], "out_of_scope_findings": [ "class: none filed · `keyLineRegex` (record-recognisers.mjs) still tolerates blockquote and bullet for `Served-tier:`, `Reviewed-by:`, `Local-runs:`; only the head line is stricter now, by the triage ruling. Observation only (no admission path), noted in the PR Acceptance notes, not a card." ] }objectstack-fleet commentedon Oct 30, 2026
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS
Landed: PR #28042 merged (
18318361f, 2026-10-30T11:06Z), Tier S. The seat readied it and armed auto-merge on delta contract review PASS 6520969324 at2e75b193(ACCEPT 6520970186). The first head's PASS (6520948513) was held back because one shape read wider than base; that shape was fixed in the PR.pm:dispatchedis stripped with this note.From this commit, a record's
Head-sha:is read only from a plain line under an unquoted## Contract reviewheading: never quoted, bulleted, fenced, code-indented or pre-heading. The writer refuses a present-but-unreadable head line, andcontract-review.md:33names the line. The reading did not change for any of the 713 live records. Residual should-fixes 4–8 are on #28057. Nothing further owed on this card.