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

@os-steve
os-steve added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit a3f3c48 Sep 20, 2026
34 checks passed
@os-steve
os-steve deleted the claude/issue-18901-seam-line-filing-rule branch September 20, 2026 15:37
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