Skip to content

docs(agents): os-dev.md :286–:287 re-keyed to the register's two tiers; H43/H48 stand down on Tier S - #19802

Merged
huangyiirene merged 3 commits into
mainfrom
claude/issue-19146-os-dev-fact-layer-rekey
Sep 23, 2026
Merged

huangyiirene merged 3 commits into
mainfrom
claude/issue-19146-os-dev-fact-layer-rekey

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #19146

Clause-②: no

维护者速读(草稿)

改了什么:两处。① .claude/agents/os-dev.md :286–:287 两行(净 0 行,402/402)从已废止的「事实层 = references/ 目录、余为规则层」改写成登记表现行的两层:受管路径全在 .claude/** 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批;## 维护者速读(草稿) 两层同欠(第二行不再豁免「事实层」)。② scripts/pm/check-half-states.mjs 的 H43(受管 PR 未向授权账户请审)与 H48(ACCEPT 后缺 needs-user-decision 标签或速读评论)在 Tier S PR 上停手:懒加载的登记表多带出 landingTierOfGOVERNED_TIER_S,一个 governedLandsOnRecord 助手在两行已匹配的切片上问登记表,S 则不判;混合 diff 有一条 Tier H 命中仍判;登记表没加载则一律不停手。自测新增 15 例(4897 → 4912),用真实登记表自己的切片驱动;⛔ 不新增巡查行、不新增电池。

为什么改:这两行是每个 dev 子代理都读的自我定义,写的是 2026-09-18 分层裁决之前的边界;H43/H48 在 Tier S PR 上开的处方(请授权账户审、挂维护者收件箱标签)正是裁决取消的那一下点击,且 H43 的理由句「队列守卫仍拒收未批准的受管入队」对 Tier S 为假(PR #19351 零批准、凭复核记录经队列落地)。

风险与代价(含回滚):文字面零行为变化。H43/H48 在 Tier S PR 上不再报告——这是裁决的意图,不是丢失:Tier S 的落地由队列守卫按 ## Contract review 记录把关。Tier H 与混合 diff 的行为字节不变;登记表缺席时仍照旧报 NOT MEASURED。消融证明:把 tier 读取删掉,5/4912 例转红,还原后 blob == HEAD。回滚 = revert 两个提交(各一类,可单独回退)。

席位意见:(席位填写)

你要做的:本 PR 为 Tier S(.claude/**),由归属席位在 ## Contract review PASS 记录 + 全绿后经队列落地,⛔ 不需要您点击。卡上余项一条(SKILL.md:618,见下方 On the card),由 skills 席位自处置。

Summary

The two os-dev.md lines still spelled the pre-tiering split (fact layer = the references/ directory, everything else rules layer). They are re-keyed to the register's rule as AGENTS.md Prime Directive #14 states it: a PR whose governed paths ALL lie under .claude/** is Tier S and lands on the owning seat's ## Contract review record; every other governed surface is Tier H and waits for the maintainer's word. The maintainer-brief draft is owed on both tiers (SKILL.md :623 has no tier split; the seat fills 席位意见 on both), so the second line simply stops exempting a "fact layer".

The card also names check-half-states.mjs H48 and H43. Measured on the base: both rows still exist and are tier-blind (governedTierFor / landingTierOf: 0 hits in the file; H43 reads GOVERNED_APPROVERS only). On a Tier S PR each remedy asks for the click the tiering removed, so both stand down there. The tier is the register's own answer on the slice the matcher already returned — no second list of surfaces lives in the patrol.

Per-site before → after

.claude/agents/os-dev.md (402 → 402 lines, net 0; both lines within the 120-byte cap)

line before after bytes
:286 「- 受管路径全在 .claude/skills/pm-dispatch/references/ 者为事实层,席位复审即记录;余为规则层。」 「- 受管路径全在 .claude/** 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批。」 118 → 120
:287 「- 规则层 PR 正文带 ## 维护者速读(草稿) 节,中文、业务角度,席位意见留空;事实层不欠。」 「- 受管面 PR 正文带 ## 维护者速读(草稿) 节,中文、业务角度,席位意见留空;两层同欠。」 117 → 114

The rule they now mirror: AGENTS.md :272–:280 (Tier H = docs/adr/**, docs/NORTH-STAR.md, skills/**, AGENTS.md, CLAUDE.md, an authorized APPROVED review; Tier S = all of .claude/**, a ## Contract review record for the current head with Served-tier: CONTRACT_REVIEW_TIER and a PASS verdict, the owning seat lands it through the queue) and SKILL.md :623 (「草稿归 dev:受管面 PR 正文带 ## 维护者速读(草稿)」, no tier split). grep -n 事实层 .claude/agents/os-dev.md on the head: 0 hits.

scripts/pm/check-half-states.mjs (H43 / H48)

site before after
loadGovernedRegister reads governedPathsIn + GOVERNED_APPROVERS also reads landingTierOf + GOVERNED_TIER_S (tierOf, recordTier); a register missing any of the four is "did not export what this row reads", as before
new governedLandsOnRecord(governed, register) true only when the register is available AND landingTierOf(slice) === GOVERNED_TIER_S; false for a Tier H or mixed slice, an empty or tier-less slice, or an unloaded register
h43NeedsReviewProbe(pr, governedCount, approvers) took a COUNT takes the matched SLICE, stands down on Tier S — a Tier S PR buys no review page and takes no slot under the oldest-first cap
h43GovernedReviewRequestGap fired on every governed PR short of coverage null on a Tier S slice; the sentence reads "open and GOVERNED on Tier H" and "refuses an unapproved Tier H enqueue"
h48SpeaksAbout population = governed ∧ open ∧ not Tier S — so h48GovernedVerdictWithoutBrief is null there and the sweep buys no PR comment thread for it
H43 / H48 headers, both summary clauses tier-blind prose name Tier H as the population; Tier S stated as out
sweep call site h43NeedsReviewProbe(pr, governedByPr.get(n)?.length ?? 0, …) h43NeedsReviewProbe(pr, governedByPr.get(n) ?? [], …)

Self-test: 15 new t() cases (no new battery, no floor moved): the Tier S and mixed slices come from GOVERNED_REGISTER.matcher(...) on the real register, so the tier answer is the register's; the hand-built GOV43 / GOV48 fixtures carry no tier and read as H (fail closed), which the comments now say. Register pin extended: tierOf(matcher(['.claude/agents/os-dev.md'])) === recordTier. Case counts: 4897 on the base → 4912.

Why stand down rather than re-aim: the card offered both. Re-aiming H43 at "a Tier S PR without a review of record" would be a new patrol row in disguise (新增门禁默认否), and the queue guard already refuses a Tier S enqueue without the record — nothing ships through that gap. Standing down is the minimal, mechanical repair the card's item 3 spells for H48 and it is the same change class for H43, so the two ride together.

Measurement the change rests on (reads taken 2026-09-23T05:24Z–05:36Z against origin/main = 2cf9db7c4; each item names its own clock)

  • 2026-09-23T05:24Z — .claude/agents/os-dev.md :286–:287 read byte-identical to the card's quotation (premise valid).
  • 2026-09-23T05:25Z — check-half-states.mjs @ 2cf9db7c4: H48 row at :10888–:11100, H43 row at :9607–:9850; governedTierFor / landingTierOf / recordTier: 0 hits in the 34,841-line file; GOVERNED_APPROVERS is H43's only firing control. PR pm: retire the needs:contract-review label from the tree (ruling B step ③) #19737 retired H31/H35/H51/H53/H61 and left both rows in place.
  • 2026-09-23T05:30Z — the seat's practice on a landed Tier S PR (feat(pm): second Unlock-action: value — a label-transition exit on a named card (#19255) #19351, all .claude/** + scripts/pm/): 0 reviews, no review request, no **ACCEPT** on the thread, no needs-user-decision, no ## 维护者速读 comment — one ## Contract review PASS record, landed through the queue. H43's shape fires on exactly that PR; it fired on fix(pm): repair two carriers still spelling the superseded references-tier boundary #19379 too (card comment 5750573385).
  • 2026-09-23T05:36Z — register verdict on this PR's two paths: check-governed-merges.mjs --testGOVERNED — Tier S(席内达档复核落地), exit 3 (= EXIT_TEST_GOVERNED); scripts/pm/check-half-states.mjs is not on the register.
  • 2026-09-23T05:25Z — no open PR touches either file (all 16 open PRs' file lists read over REST at claim time).

Reverse verification (ablation), run 2026-09-23T05:37Z at head bd5bbd2bb (the file is byte-identical at c9617adde)

node scripts/ablation-replace.mjs --file scripts/pm/check-half-states.mjs --anchor ' return register.tierOf(list) === register.recordTier;' --replacement ' return false; // ABLATION: tier reading removed' -- node scripts/pm/check-half-states.mjs --self-test

  • mutation landed on disk: anchor 1 → 0, marker 0 → 1, blob d2d9ba38ac6352c8e2e35f0d
  • direction observed: RED — ✗ check-half-states self-test: 5 of 4912 case(s) failed (the H43 Tier S clean case, the H43 Tier S probe case, the register-answer join case, the H48 Tier S population case, the H48 Tier S no-finding case); the mixed-slice controls stayed green
  • restore proven: blob after restore d2d9ba38ac63 == blob at HEAD; git diff HEAD empty; re-read on the absolute path: anchor 1, marker 0
  • no dist/ is involved (the patrol runs from source), so no build leg

Gates on the final head c9617adde (run 2026-09-23T06:02Z–06:19Z; exit codes captured before any pipe; verdict lines from the gate logs)

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands on this head (47 commands, list identical to the derivation at bd5bbd2bb); --ran reconciliation: ✓ dispatch-gates --ran: 47 derived famil(ies) accounted for — 46 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)..

# command exit verdict line (from the gate log)
01 node scripts/check-ci-filter-parity.mjs 0 OK: all 185 declared cross-package glob(s) (132 unique) are covered by core or crosspkg, every crosspkg entry still covers one, and the test j
02 node scripts/check-closing-keyword-parity.mjs 0 • packages/spec/CHANGELOG.md -- 6080503 bytes exceeds the sweep's 2097152-byte cutoff for UNREGISTERED files
03 node scripts/check-closing-keyword-parity.mjs --self-test 0 ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.
04 node scripts/check-comment-mask-corpus.mjs 0 ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 7015 files, 0 disagree, 0 unparseable, 60.0s (comparator self-test: 26 cases pass).
05 node scripts/check-declaration-mirrors.mjs 0 scripts/invoked-as.d.mts
06 node scripts/check-declaration-mirrors.mjs --self-test 0 All 29 self-test cases passed.
07 node scripts/check-scripts-symbol-anchors.mjs 0 ✅ check-scripts-symbol-anchors: 3684 anchors across 280 scripts resolve — 52 symbol (52 declaration, 0 literal), 3632 file-level, 0 cross-repo, 1 exem
08 node scripts/check-scripts-symbol-anchors.mjs --self-test 0 ✅ check-scripts-symbol-anchors --self-test: every finding class provoked, comment-prose projection wired, declined shapes counted not missed, allowanc
09 node scripts/check-self-test-wired.mjs 0 ✓ check-self-test-wired: every one of the 229 script(s) CI runs that ship a --self-test has that self-test run by CI.
10 node scripts/check-self-test-wired.mjs --self-test 0 check-self-test-wired --self-test: 3 live ledger row(s) verified, plus the comment mask, the right boundary, alias resolution and both audit direction
11 node scripts/check-self-test-workflow-commands.mjs 0 scope: 229 script(s) CI runs ship a --self-test (0 of them package-local gate(s) CI names by path, present because this population is the one chec
12 node scripts/check-self-test-workflow-commands.mjs --self-test 0 check-self-test-workflow-commands --self-test: both measured parse rules pinned (legacy form anywhere in a line, current form only at line start), the
13 node scripts/check-whole-set-label-write.mjs 0 PROSE_PROBES make run() refuse rather than pass if it ever stops finding them.
14 node scripts/check-whole-set-label-write.mjs --self-test 0 ✓ check-whole-set-label-write --self-test: all cases pass (24 fixture trees + 5 refusals + 1 allowlist hatch)
15 node scripts/pm/bare-root-worklist.mjs --self-test 0 OK self-test: 81 live row(s), 59 unreachable as spelled, 46 recorded verdict(s) — none stale, none missing, none contradicted (12 row(s) whose gate c
16 node scripts/pm/board-snapshot.mjs --self-test 0 OK board-snapshot self-test: 156 cases pass across 12 batteries (open-first walk order, the delta-first run order and its budget split driven end to e
17 node scripts/pm/check-governed-queue-guard.mjs --self-test 0 ✓ check-governed-queue-guard self-test: 279 cases pass (register-driven verdicts, the queue/PR event split, latest-decisive approval reduction, the 20
18 node scripts/pm/check-harness-current.mjs --self-test 0 check-harness-current --self-test: all 26 cases passed.
19 node scripts/pm/sweep-closed-cards.mjs --self-test 0 ✓ sweep-closed-cards self-test: 87 cases pass across 9 batteries (the imported residue set, the offline screen, the two closing routes with the measur
20 pnpm --filter @objectstack/lint run check:doc-formula-expressions 3 Exit status 3
21 pnpm check:agent-model-declared 0 ✓ check-agent-model-declared: 1 agent definition(s) under .claude/agents/ all declare a model
22 pnpm check:agent-test-spelling 0 ✓ check-agent-test-spelling: 0 violations — 560 file(s) · 9601 bare -- token(s) · 1810 launcher-rooted run(s) · 13 separator(s) JUDGED · 6 vitest-ba
23 pnpm check:bash32-floor 0 ✓ check-bash32-floor: 33 tracked shell file(s) under scripts/, .claude/hooks/, .githooks/** name no bash 4+ construct outside a comment, a guarded
24 pnpm check:cli-command-ids 0 ✓ check-cli-command-ids: 63 module(s) under packages/cli/src/commands examined, all of them default-export a class whose inheritance chain reaches ocl
25 pnpm check:closing-target-claim 0 ✓ check-closing-target-claim self-test: 105 cases pass.
26 pnpm check:commit-card-trailers 0 ✓ check-commit-card-trailers self-test: 81 cases pass.
27 pnpm check:cross-package-test-inputs 0 All 255 self-test cases passed.
28 pnpm check:doc-authoring 0 ✓ doc authoring guard: sibling-package prose ids hold the baseline — 819 pinned site(s) across 231 file(s), 90595 string(s) read in 1247 parsed source
29 pnpm check:driver-memory-census 0 check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states "#6664 census: 2 ruled consume
30 pnpm check:entry-guard 0 ✓ check:entry-guard: 280 scripts/ file(s) — every entry guard goes through invoked-as.mjs; 219 export bindings, 219 of them inert on import (0 known-u
31 pnpm check:gitlink-declared 0 ✓ check-gitlink-declared --self-test: 36 assertions over throwaway git repos (real scan() path)
32 pnpm check:issue-citations 0 ✅ check-issue-citations --self-test: grammar narrowed, four 404 causes kept apart, both board strategies agree, diff scope red AND green, scope contra
33 pnpm check:nul-bytes 0 ✓ check-nul-bytes --self-test: 75 assertions over a temp git repo (real scan() path)
34 pnpm check:parse-guard 0 packages/cli/test/published-subpath-hook-body.pin.test.ts:417 ts.createSourceFile
35 pnpm check:partof-closing-keyword 0 ✓ check-partof-closing-keyword self-test: 45 cases pass.
36 pnpm check:pm-governed-merges 0 ✓ check-governed-merges --self-test: 441 assertions (the unified governed predicate + near misses, subject→PR spellings, window parsing, the #12633 la
37 pnpm check:pm-half-states 0 ✓ check-half-states self-test: 4912 cases pass. Batteries: H66 released queue card 182/172, H19 judged-set founding 37/34, H65 tier declaration spelli
38 pnpm check:pm-post-stamped 0 ✓ post-stamped self-test: 610 cases pass across 21 batteries — offline, no network, no token.
39 pnpm check:pm-skill-id-lint 0 ✓ check-skill-id-lint: 30 file(s) clean (pattern /#[0-9]{3,}/g).
40 pnpm check:pm-skill-ratchet 0 ✓ check-skill-line-ratchet: declared cross-file moves: 1, total ceilings down 9 lines.
41 pnpm check:pnpm-filter-targets 0 ✓ check:pnpm-filter-targets: 152/207 --filter occurrence(s) across 41 file(s) resolve against 81 workspace package(s); 55 not judged (2 foreign, 30
42 pnpm check:ratchet-remedy-authority 0 OK self-test: the lexer holds, messages are bounded, both offer word orders and path-named registries are reached, declaration registries are not, th
43 pnpm check:refd-timer-probe 0 ✓ check-refd-timer-probe self-test: 11 cases pass, negative controls included.
44 pnpm check:single-claim-paths 0 ✓ check-single-claim-paths self-test: 93 cases pass.
45 pnpm check:skill-frame-sync 0 ✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md; no second copy to c
46 pnpm check:watch-hint-literal 0 ✓ check-watch-hint-literal: 71 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 47, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECL
47 pnpm check:pm-dispatch-gates 0 ✓ dispatch-gates self-test: 1905 cases pass. (738.5s on this box)

Row 20 is exit 3 = PREREQUISITE NOT MET (the gate's own NOT-MEASURED code, see Acceptance notes); every other row exit 0. The same 47 ran at bd5bbd2bb with the same readings before the merge of origin/main.

Line budget

  • .claude/agents/os-dev.md: 402 / ceiling 402 before and after (headroom 0, net 0 lines); check:pm-skill-ratchet exit 0 on the head. Max content bytes per line 120 before and after.
  • skills/** (the published catalog) is not touched, so no whole-file / whole-package token readings are owed.
  • .claude/** and scripts/pm/** publish nothing from any package's files[] (fast lane), so skip-changeset applies and no changeset is written.

On the card

  • landing-operations.md :27–:28 and the queue guard's SUCCESS line: landed by PR fix(pm): repair two carriers still spelling the superseded references-tier boundary #19379 (merged 1f53b0b685); the guard's :236 hit is a verbatim ruling quotation and stays.
  • os-dev.md :286–:287, H48, H43: this PR.
  • REMAINDER, measured on origin/main at fae870352 and not in this PR's claimed file surface: .claude/skills/pm-dispatch/SKILL.md:618 (the size clause ending 「⛔ 无事实层例外」) still spells the retired word (the skills seat's addendum 5737973707 joined it to this card), and 「规则层」 survives as a synonym for Tier H at SKILL.md:617, references/core-rules.md:122, references/landing-operations.md:26 and references/lanes/skills.md:17 (vocabulary only; each rule stays true). That is why the first line is Part of rather than a closing keyword: skills: re-key the three 事实层 = references/ spellings the Tier S ruling leaves false (os-dev.md :286–:287, landing-operations.md :27–:28, H48) #19146 remains open after this PR merges, with its own addendum item still owed. The dispatch asked for a closing first line on the premise that the two os-dev.md lines were the whole remainder; the tree-wide grep says otherwise, and os-dev.md's rule (a PR whose merge should not close the card uses Part of) wins.

Acceptance notes (observations, not filed)

  • check-half-states.mjs H48's sentence still says the handoff exists because "a Tier H surface lands only on the maintainer's word" — accurate for Tier H under PD feat: Comprehensive CRM example demonstrating all ObjectStack protocol features #14 (the maintainer's hand or an authorized approval); the pre-existing "by hand" wording was narrowed to that in the same edit.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions answers exit 3 PREREQUISITE NOT MET in this worktree (the gate needs @objectstack/formula / @objectstack/lint built; this diff touches no package, so no build closure is owed). Recorded as NOT MEASURED, not as a failure; its population (docs formula expressions) is disjoint from both changed paths.
  • Landing: Tier S — draft stays draft; the owning seat renders the ## Contract review record for head c9617adde and lands it through the queue after every check is green.

Generated by Claude Code

…ing tiers

The two lines still spelled the superseded split (fact layer = the
pm-dispatch references directory only, everything else rules layer). The
register and AGENTS.md Prime Directive #14 now tier the landing: a PR whose
governed paths all lie under `.claude/**` is Tier S and lands on the owning
seat's contract review record; every other governed surface is Tier H and
waits for the maintainer's word. The maintainer brief draft is owed on
every governed PR, on both tiers — the second line stops exempting a
"fact layer". Net 0 lines; both lines within the 120-byte cap.

Claude-Session: https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc
Co-authored-by: Claude <noreply@anthropic.com>
…e register, never a second list

Both rows prescribed the maintainer's word on every governed PR: H43 a
review request to GOVERNED_APPROVERS (or the assign fallback), H48 the
needs-user-decision inbox label plus the final brief comment behind a
seat's ACCEPT verdict. The landing is tiered now — a PR whose governed
paths all lie under `.claude/**` lands on the owning seat's contract
review record with no approval and no maintainer click — so on such a PR
each remedy asked for exactly the click the tiering removed, and H43's
"the queue guard still refuses an unapproved governed enqueue" rationale
was false there.

The register the sweep already loads lazily now also carries
`landingTierOf` and `GOVERNED_TIER_S`; one helper, `governedLandsOnRecord`,
asks it on the slice the matcher already returned (ALL-quantified: one
Tier H row keeps a mixed diff in both rows; an empty, tier-less or
unloaded answer stands nothing down). H43's probe policy reads the same
slice as its row, so a Tier S PR buys no review page and takes no slot
under the oldest-first cap. Row sentences and both summary clauses name
Tier H as the population. Self-test: 15 cases driven by the real
register's own slices; 4897 -> 4912, no new battery, no new row.

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

Pre-PR merge; the incoming commit touches neither os-dev.md nor
check-half-states.mjs.

Claude-Session: https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation labels Sep 23, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 23, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: c9617adde479c093cd30e92691a3403efb9a9824

① Derived judgments

Rendered in-seat by the skills seat 1 session at the served tier the maintainer named (ruling record 5771798588; 「契约复审继续用 fable 不变」 5788482806 of this date). The contract is the card #19146 as graded by the lane (class (b), Path: none) with os-steve's Release 5773572115 / 5773579070 naming the remainder: .claude/agents/os-dev.md :286–:287 still spell the pre-Tier-S fact-layer / rules-layer split; H48 / H43 of scripts/pm/check-half-states.mjs only if they still read false; ⛔ no new row, ⛔ no other file (the claim 5789534995).

  • (a) The diff — measured by this seat on a review worktree at the head. Three commits on merge-base fae870352 (the re-key, the H43 / H48 repair, a merge of origin/main); two files vs the merge-base, +141 / −43. os-dev.md :286 「受管路径全在 .claude/skills/pm-dispatch/references/ 者为事实层,席位复审即记录;余为规则层。」 → 「受管路径全在 .claude/** 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批。」 and :287 「规则层 PR 正文带 ## 维护者速读(草稿) 节,中文、业务角度,席位意见留空;事实层不欠。」 → 「受管面 PR 正文带 ## 维护者速读(草稿) 节,中文、业务角度,席位意见留空;两层同欠。」 — the register's two tiers exactly as AGENTS.md :276–:279 and check-governed-merges.mjs state them, and the brief owed on every governed PR as SKILL.md :623 already says; 402 / 402 lines, the widest line 120 bytes, 事实层 0 hits in the file.
  • (b) H43 / H48 — the premise re-measured by the dev and re-read by this seat. Both rows were tier-blind (no landingTierOf reader in the file; H43 asked for a review on every governed PR, H48 expected a maintainer brief reader on Tier S where there is none). The repair: the lazily loaded register now also carries landingTierOf and GOVERNED_TIER_S (both exported by check-governed-merges.mjs :1294 / :1016 — read by this seat), one helper governedLandsOnRecord answers on the already-matched slice and stands a row down ONLY when the register loaded, exports the tier reader and every matched path lands on the record tier (an unloaded register or a missing reader stands nothing down — fail-closed, pinned by cases), H43's probe policy takes the slice so a Tier S PR buys no review page, and both rows plus both summary clauses name Tier H as their population. No new row (id: 'H…' additions 0), no new battery; 15 self-test cases added (4897 → 4912), driven by the real register's slices; the dev's ablation (the tier read replaced by false) turned five of them red and restored clean.
  • (c) Acceptance — the card's own Done-when, measured on the tree. Per the card: every dev-facing instruction line reads the register's tiering — done for os-dev.md (the file every dev reads); the two instrument rows agree with the register — done. Not done and correctly left: .claude/skills/pm-dispatch/SKILL.md :618 「⛔ 无事实层例外」 (joined to this card by the earlier seat's addendum 5737973707) and 「规则层」 as a Tier H synonym at SKILL.md :617, references/core-rules.md :122, references/landing-operations.md :26, references/lanes/skills.md :17 — outside the claim's file surface and on files another in-flight card (PM protocol: SKILL.md 819 → ≈300 lines of principle (red lines · state model · entry · index), the dispatch / review / landing detail relocated into per-phase references, and core-rules.md retired as a duplicate (maintainer direct dispatch, batch #213 item 4) #19716) is relocating; hence Part of #19146, the right call under os-dev.md's rule.
  • (d) Gates — re-run by this seat on the review worktree at the head after pnpm install --frozen-lockfile --offline. check:pm-skill-ratchet 0 (402 / 402); check:skill-frame-sync 0; check:doc-authoring 0; check:pm-skill-id-lint 0; check:agent-model-declared 0; check:pm-governed-prose 0; check-half-states.mjs --self-test 0 (4912 cases); check-governed-queue-guard.mjs --self-test 0 (279 cases); check-governed-merges.mjs --pr 19802 exit 3 — GOVERNED, Tier S (.claude/** ×1; check-half-states.mjs not on the register; 184 changed lines, under the human-merge threshold). The dev's derivation: 47 families by --commands, --ran 46 / 47 / 1 NOT-MEASURED (check:doc-formula-expressions exit 3 prerequisite — no package touched, population disjoint), the 1905-case dispatch-gates self-test run in its own call. CI at the head at the seat's read: 31 latest-per-name check runs — 16 success, 10 skipped, 5 in progress; the landing waits for green and the expected-skips roster.

② Semver level

None — no release. .claude/** and scripts/pm/** are in no package's files[]; skip-changeset written through label-write.mjs with read-back (the dev's report).

③ Boundary flags

  • Tier S (.claude/** on the register): this record PASS plus every check green ⇒ the seat readies the PR and arms auto-merge through the CCR routes; the post-merge audit is the compensating control.
  • The dev's open question, graded in-lane → A: keep Part of; the remainder — SKILL.md :618 and, at the seat's option, the four 规则层 spellings — stays on this card and is dispatched after PM protocol: SKILL.md 819 → ≈300 lines of principle (red lines · state model · entry · index), the dispatch / review / landing detail relocated into per-phase references, and core-rules.md retired as a duplicate (maintainer direct dispatch, batch #213 item 4) #19716 (which relocates those very lines) lands; B would leave the card's acceptance line unmet; C is outside the claim. The card returns to pm:queue with a Release: naming the remainder at this PR's landing.
  • H43 stood down on Tier S rather than re-aimed at the record: correct under 新增门禁默认否 — re-aiming would be a patrol row in disguise, and the queue guard already refuses a Tier S enqueue without the record.
  • Report 5790159743 on the card parses; mcp_calls 0; three REST writes through the fleet-write relay plus four pushes; no body PATCH by the dev; the pre-push hook 0 on each push. Deviations as recorded by the dev — three commits plus a merge instead of one or two (each bisectable), the NOT-MEASURED formula gate, the 738-second dispatch-gates self-test run in the background — none blocking.
  • Out of scope, noted by the dev, ⛔ not touched: the four 规则层 vocabulary sites (carrier: the remainder above); H48's 「lands only on the maintainer's word」 framing narrowed, not widened.

Implemented-by: claude/issue-19146-os-dev-fact-layer-rekey
Reviewed-by: session_01Wnstp2kTth7sGXfr8fXypc

VERDICT: PASS

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

Development

Successfully merging this pull request may close these issues.

2 participants