Skip to content

feat(pm): a class-(b) finding names its seam — the Seam: line on os-dev.md rule 3, and the H68 patrol row for a (b) card without one - #19356

Merged
os-steve merged 2 commits into
mainfrom
claude/issue-18901-seam-line-filing-rule
Sep 20, 2026
Merged

os-steve merged 2 commits into
mainfrom
claude/issue-18901-seam-line-filing-rule

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes #18901

Clause-②: no
Ruling-ref: 5727134819 — director seat batch #157 item 3, letter A′ on #18900 (item ①, this card, as filed); triage handover 5725479658 binds (every governed text at its ceiling; the retired line is named below).
Seat domain:skills#2 · claim 5749402494 · branch claude/issue-18901-seam-line-filing-rule · head 5033c4d (on origin/main 13d5294).

What lands

1. .claude/agents/os-dev.md 六条基本规则 3 — net 0 (403 / 403), every touched line under the 120 B line ratchet

  • :42 before (97 B): 「 - (a) 可复现缺陷(复现或失败探针具名);(b) 违背已声明契约(引契约原文);」
  • :42 after (113 B): 「 - (a) 可复现缺陷(复现或失败探针具名);(b) 违背已声明契约(引契约原文,带 Seam: 行);」
  • :43 NEW (112 B), the grammar in ONE line directly under (b): Seam: spec:KEY → runtime:CALL_SITE | renderer:COMPONENT, then 「,无消费者写 consumer: none。」 — in the file the three placeholders are written in Chinese inside ASCII angle brackets (键或符号 / 调用点 / 组件), spelled out here as words because this body is a GitHub body.
  • RETIRED to pay for it — :53 at 13d5294 (115 B): 「 - ⛔ 不用 MCP GitHub 写工具;令牌按会话定:installation ⇒ claude[bot],user-to-server ⇒ 用户。」 Surviving homes, clause by clause: the ban lives on :51 「GitHub 写一律走 REST 代理(curlGITHUB_TOKEN)」 (all writes REST ⇒ no MCP write), :307 「不走 MCP」, :308 「⛔ 不换路重发(curl/MCP/手工)」 and the report template :371 mcp_calls 「a write tool in the list = this report is refused」; the token → login fact lives at .claude/skills/pm-dispatch/references/platform-readings.md:130 「容器 curl 的 REST 通道令牌两类:installation(claude[bot])与 user-to-server(用户)」, and the rule that fact served — 「归属 = 文本里的 session ID,非 user.login」 — stays on :51. Line numbers are pre-edit; after the edit the REST line is :52 and :307 / :308 / :371 are unchanged (one insert and one delete above them cancel). No gate pins the retired line's phrases (grepped scripts/, .claude/, .github/).
  • Spelling agreed with the routing half (pm-dispatch: a Seam: card routes by the seam — vertical dispatch by default inside objectstack (file surface names both ends; acceptance = the consumer reads it or the key retires with its ledger row), and rule 2's parent + per-repo sub-issues trigger on a spec↔objectui seam, not only on a feature (item ② of #18900) #18902, in flight on this seat): the key is backticked Seam: in both texts.

2. scripts/pm/check-half-states.mjs — H68, ONE report-only row, net +120 (124 insertions / 4 deletions)

The class-(b) signal, measured (board read 2026-09-20T11:12Z, 537 open non-PR cards, saved listing replayed against the finished row)

Reader test

「I found a declared key the runtime never reads — what do I write?」 ⇒ the (b) line — 违背已声明契约(引契约原文,带 Seam: 行): cite the contract text and add Seam: spec:THE_KEY → consumer: none (you measured no consumer). Where a consumer exists but does not honour the key: Seam: spec:THE_KEY → runtime:THE_CALL_SITE, or Seam: spec:THE_KEY → renderer:THE_COMPONENT.

Verification — all on head 5033c4d, every exit code captured before any pipe

  • node scripts/pm/check-half-states.mjs --self-test → exit 0 — 「✓ check-half-states self-test: 5107 cases pass. Batteries: H66 released queue card 183/172, H19 judged-set founding 37/34, H65 tier declaration spelling 46/42, H67 queued merged-delivery reading 152/142, H2/H47/H66 decorated ownership marker 213/184, ISSUE_BODY_LIMIT measured cap 55/52, H68 class-(b) seam line 26/24」.
  • pnpm check:pm-skill-ratchet → exit 0 — 「✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0)」.
  • Gate union from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 5033c4d (47 commands, no paths passed): 47 / 47 ran on 5033c4d, every one exit 0 — --ran reconciliation: 「47 derived famil(ies) accounted for — 47 run, 0 NOT-MEASURED (a DERIVED zero — all 47 recorded an exit code and none of them is 3)」. The list: node scripts/check-changeset-no-major.mjs --base origin/main · node scripts/check-changeset-no-major.mjs --self-test · node scripts/check-ci-filter-parity.mjs · node scripts/check-closing-keyword-parity.mjs · node scripts/check-closing-keyword-parity.mjs --self-test · node scripts/check-comment-mask-corpus.mjs · node scripts/check-declaration-mirrors.mjs · node scripts/check-declaration-mirrors.mjs --self-test · node scripts/check-scripts-symbol-anchors.mjs · node scripts/check-scripts-symbol-anchors.mjs --self-test · node scripts/check-self-test-wired.mjs · node scripts/check-self-test-wired.mjs --self-test · node scripts/check-self-test-workflow-commands.mjs · node scripts/check-self-test-workflow-commands.mjs --self-test · node scripts/check-whole-set-label-write.mjs · node scripts/check-whole-set-label-write.mjs --self-test · node scripts/pm/bare-root-worklist.mjs --self-test · node scripts/pm/board-snapshot.mjs --self-test · node scripts/pm/check-governed-queue-guard.mjs --self-test · node scripts/pm/check-harness-current.mjs --self-test · node scripts/pm/sweep-closed-cards.mjs --self-test · pnpm --filter @objectstack/lint run check:doc-formula-expressions · pnpm check:agent-model-declared · pnpm check:agent-test-spelling · pnpm check:bash32-floor · pnpm check:changeset-gate-self-tests · pnpm check:cli-command-ids · pnpm check:closing-target-claim · pnpm check:commit-card-trailers · pnpm check:cross-package-test-inputs · pnpm check:doc-authoring · pnpm check:driver-memory-census · pnpm check:entry-guard · pnpm check:nul-bytes · pnpm check:parse-guard · pnpm check:partof-closing-keyword · pnpm check:pm-dispatch-gates · pnpm check:pm-governed-merges · pnpm check:pm-half-states · pnpm check:pm-skill-id-lint · pnpm check:pm-skill-ratchet · pnpm check:pnpm-filter-targets · pnpm check:ratchet-remedy-authority · pnpm check:refd-timer-probe · pnpm check:single-claim-paths · pnpm check:skill-frame-sync · pnpm check:watch-hint-literal.
  • node scripts/pm/check-governed-merges.mjs --test .claude/agents/os-dev.md scripts/pm/check-half-states.mjs → exit 3 = GOVERNED, Tier S (.claude/** ×1; scripts/pm/check-half-states.mjs not on the register) — the expected reading: this PR stays DRAFT until the seat's ## Contract review record for the current head.
  • Build for check:doc-formula-expressions: pnpm --workspace-concurrency=2 --filter '@objectstack/lint...' build under scripts/pm/os-verify-lock.sh — 「VERDICT command-exit 0 · held the lock 220s」.

Acceptance notes (noted, not filed)

维护者速读(草稿)

改了什么:给开发 agent 的立卡规则加了一句:凡是「协议里声明了、运行时或渲染器没兑现」这一类(b 类)发现,卡面上必须带一行机器可读的 Seam:,写明这条缝的两端(哪个协议键 → 哪个运行时调用点或哪个渲染组件;实测没有消费者就写 consumer: none)。同时巡检脚本新增一行只报不判的 H68:把已经声明为 b 类却没写这一行的开放卡按编号列出来。文件行数不变(403 / 403),为此退休了一行重复条款(MCP 写工具禁令 + 令牌说明),它的内容在同规则的 REST-only 行、标签写入条款、报告模板和 platform-readings 里都还在。

为什么改:你 9-18 同意的五项攒批第 ① 项。今天缝卡按「修复落地的包」路由,缝的两端各落一层、各修一次;有了这一行,路由那一半(#18902)才能按缝派发,一个键在一次落地里要么被兑现要么退役。板面实测:15 张开放 b 类卡今天都没有这一行,巡检会把它们列出来。

风险与代价(含回滚):只加一行规则、一行巡检;不改标签、不写板面、不判红。误报边界已量:句中顺带提到「class (b)」的卡不列(3 张),席位帖子不列。回滚 = revert 本 PR。巡检脚本的行数配额已用满(+120);自测下限 6 → 7,与在飞的 #19255 撞同一行,后落地者改为 8。

席位意见:

你要做的:受管面(.claude/**,Tier S)⇒ 席内达档复核后由席位落地,不需要你点击。若你希望巡检也校验 Seam: 行的取值格式(今天只查有没有这一行),回一个字,另立卡。


Generated by Claude Code

…-dev.md rule 3, and the H68 patrol row for a (b) card without one

os-dev.md 六条基本规则 3 (net 0 on 403 / 403): the (b) line gains 「带 `Seam:` 行」 and ONE adjacent
line carries the grammar — `Seam: spec:KEY → runtime:CALL_SITE | renderer:COMPONENT`, `consumer: none`
when no consumer was measured. Paid by retiring the MCP-write/token line, whose ban survives at the REST-only
line, the label-write clauses and the report template's `mcp_calls` field, and whose token→login fact
lives in pm-dispatch references/platform-readings.md.

check-half-states.mjs: H68 — an OPEN card that DECLARES class (b) in its body (a heading naming the class or
a line opening with it, the shapes measured on the live board) and carries no `Seam:` line at line start,
read with the directive reader `Blocked-by:` shares. Report-only, `state` band, the unscoped listing
(H63's channel), no request. Battery beside H63's cases; SELF_TEST_BATTERY_FLOOR 6 → 7.

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

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 5033c4d9a1e3560911bed9922c1954a8ed698257

① Derived judgments

  • Published accept set / public surface: none moves — the dev agent's instruction prose (.claude/agents/os-dev.md, net 0 at 403 / 403) and a report-only row in the PM patrol reader (scripts/pm/check-half-states.mjs, +124 / −4, net +120 against the ≤ +120 budget); no published package, no schema, no error code, no label written, no request added. check-widening-tells --declaration no on the diff: 2 files NOT MEASURED (no declared surface covers either) — the no stands on the seat's reading of the diff, ⛔ not on that exit. check-governed-merges --pr 19356: GOVERNED, Tier S (.claude/** ×1; the script is not on the register). Judged correct.
  • The rule half (六条基本规则 3): (b) now reads 「违背已声明契约(引契约原文,带 Seam: 行)」 (:42, 113 B) and ONE adjacent line carries the grammar Seam: spec:<键或符号> → runtime:<调用点> | renderer:<组件>,无消费者写 consumer: none (:43, 112 B) — both under the 120 B line ratchet; the spelling (backticked Seam:) agrees with the routing half already on origin/main (SKILL.md :241 「Seam: 卡归 spec 席,默认纵向派发」, PR skills(pm-dispatch): a Seam: card routes by the seam — spec seat, vertical dispatch by default; rule 2 splits a spec↔objectui seam into parent + per-repo sub-issues #19321). Paid by retiring :53 at 13d5294 (the MCP-write ban + token-kind fact); the seat verified every surviving home on THIS head: the ban at :52 「GitHub 写一律走 REST 代理」, :307 「不走 MCP」, :308 「⛔ 不换路重发(curl/MCP/手工)」 and the report template :371 (mcp_calls — a write tool in the list refuses the report); the token → login fact at references/platform-readings.md :130; no gate pins the retired phrases. Judged correct.
  • The reader half (H68): one state-band row on the UNSCOPED listing — an OPEN card that DECLARES class (b) in its body (a heading naming the class, or a line opening with it; decoration and a leading Finding tolerated) and carries no Seam: line at line start, read with the Blocked-by: directive reader (directiveValues(text, 'Seam'), same-line value required). The chosen reader is the MEASURED one: 537 open cards at 2026-09-20T11:12Z — 16 declare the class (one a pm:seat post, excluded by NEVER_SWEPT_LABELS), 4 mention it mid-sentence (this card among them — the false positive a mention-reader lists), comments name the class on 0 of 20 finding cards, so the body declaration dominates and costs no request. Closed cards and PR rows null; the VALUE after Seam: is deliberately not judged (the routing half's reading). Registered state beside H63 / H65 with the three refusals argued; familyRegistryCoverage 0 missing / 0 extra; battery 「H68 class-(b) seam line」 26 / pin 24 placed beside H63's cases (⛔ not at selfTest()'s tail); SELF_TEST_BATTERY_FLOOR 6 → 7 with the three existing exact pins moved. The remedy text names the routing rule the line feeds (vertical dispatch for a packages/spec producer; parent + sub-issues for an objectui consumer) as SKILL.md :241–:243 state it. Judged correct — a leg on an existing listing, ⛔ not an invented sweep.
  • Evidence, seat-run on this head in a detached worktree: check-half-states.mjs --self-test exit 0 (5107 cases; the new battery 26 / 24); check-skill-line-ratchet exit 0 (「os-dev.md is 403 lines (ceiling 403; headroom 0)」); check-skill-id-lint / check-governed-prose exit 0; git merge-tree against origin/main c334ba0: 0 conflicts, and neither file has moved on main since merge-base 13d5294; CI on 5033c4d: 37 check runs, all success / skipped. The dev's 47-family gate union reconciles 47 / 47 with --ran (a DERIVED zero).

② Semver level

None — nothing published; skip-changeset on the PR is the correct declaration. Judged correct.

③ Boundary flags

open_questions empty. Deviations read and accepted: the run was cut by the account's usage wall and resumed on its own worktree (base merged as a fast-forward); a first H68 draft measured +215 and was restored and re-applied compact to +120 exactly (no over-budget commit exists); one gate batch was moved to the background by the harness and its remaining commands re-run in the foreground, both readings recorded; the --concurrency flag forwarded into a package script on the first build attempt, corrected on the second; the platform dropped one trailing newline of the PR body. Shared line: SELF_TEST_BATTERY_FLOOR 6 → 7 is also made by PR #19351 (#19255) — that PR was converted back to DRAFT at 2026-09-20T14:16Z by an act that is not this seat's, so if this PR lands first the floor is 7 and #19351's lander resolves the roster to 8 (the claim's rule, unchanged). Three noted, not filed items with named carriers: three live (b) cards declare the class only mid-sentence (#19030 · #18697 · #17735 — the seat that next writes on each); directiveValues's JSDoc key union lacks 'Seam' (the line sits in #19255's hunk — its lander, one word); pnpm check:pm-dispatch-gates runs ~25 min (an observation). Mechanism assumption 3 was refined by measurement (finding is transient, so the (b) population is the whole open board, not finding + domain:*) — accepted, the correct consequence of measuring first.

Implemented-by: claude/issue-18901-seam-line-filing-rule
Reviewed-by: session_017ETYWqMQD4qMtZzAGovWNi

VERDICT: PASS


Generated by Claude Code

… self-test roster carries both new batteries

The label-transition unlock-exit battery landed on main while this branch was open; both sides
raised SELF_TEST_BATTERY_FLOOR 6 → 7 and added a roster row at the same place. Resolved by the seat
as the claim's rule says the later lander does: both rows kept, the floor set to 8, and every floor
pin (the four batteries that count the roster) moved to EIGHT. Self-test: 5118 cases, 8 batteries.

Claude-Session: https://claude.ai/code/session_017ETYWqMQD4qMtZzAGovWNi
Co-authored-by: Claude <noreply@anthropic.com>
@os-steve
os-steve marked this pull request as draft September 20, 2026 14:31
@os-steve
os-steve marked this pull request as ready for review September 20, 2026 14:39
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: ef8358d84b139c8fbc6e1cf2e007484b73947c17

① Derived judgments

② Semver level

None — unchanged from 5750369816; skip-changeset stands. Judged correct.

③ Boundary flags

Unchanged from 5750369816, plus: the roster resolution is the seat's own commit on the dev's branch — a base merge with conflict resolution, the one seat-side write the claim's rule provides for; CI re-runs on this head and the queue entry follows a green run.

Implemented-by: claude/issue-18901-seam-line-filing-rule
Reviewed-by: session_017ETYWqMQD4qMtZzAGovWNi

VERDICT: PASS


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants