Skip to content

fix(pm): the Served-tier line names the tier constant, never a model identifier — AGENTS.md's comment rule (#18060) - #18087

Merged
os-project-manager merged 2 commits into
mainfrom
claude/issue-18060-served-tier-identifier-free
Sep 14, 2026
Merged

os-project-manager merged 2 commits into
mainfrom
claude/issue-18060-served-tier-identifier-free

Conversation

@claude

@claude claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #18060

A review of record is a GitHub comment, and AGENTS.md is unqualified about that surface:

…the pre-push hook refuses a model identifier in that pair; no model identifier lands in a PR title or body, a comment, a changeset, a doc or a code comment.

The Served-tier: top line the in-seat contract-review protocol mandates carried the value of CONTRACT_REVIEW_TIER, which is a literal model identifier. So a record could clear a carrier only by putting that identifier into the very artifact the rule names.

This PR makes the identifier-free spelling the only one: the line's token is the constant's NAME. Nothing evidential is traded away — the line was never the reading. The protocol already says 「⛔ 自述档位与传参皆非读数」, and the authoritative control is the seat's own transcript grep against the constant's value, which produces no repository artifact at all.

Direction was ruled by triage (comment 5656662371, quoted verbatim, untranslated):

⭐ Direction ruled — the convention yields to AGENTS.md. ⛔ Not a decision card.

⛔ Triage rules the direction; the exact replacement wording is the implementer's.

Premise readings

All four checked against origin/main at 57343f761, in the worktree, on 2026-09-14.

# premise verdict evidence
P1 both readers compare the token to the constant's VALUE, which is a literal model identifier ⇒ a record can pass today only by carrying that identifier in a comment holds servedTierStands() read served.value === CONTRACT_REVIEW_TIER; check-governed-queue-guard.mjs imports that very predicate through loadRecordRecognisers, so both gates answered from one comparison (00:10Z)
P2 contract-review.md :29 and :56 require that value holds :29 read 「值取转录 harness model 盖章」 and :56 「裁决 Served-tier:CONTRACT_REVIEW_TIER ⇒ exit 4」 (00:08Z)
P3 git grep -n Served-tier origin/main -- .claude AGENTS.md skills finds ONLY those two lines holds exactly 2 hits, both contract-review.md; the whole-tree grep adds only the two script files, 26 + 14 hits (00:09Z)
P4 the card's 「no gate reads it yet」 is already false on origin/main FALSIFIED — the window the card names has closed 273a66501 (2026-09-13T13:12Z, #17990) and 60b99552a (2026-09-13T15:00Z, #18036) are both ancestors of origin/maingit merge-base --is-ancestor exit 0 for each, the self-proving direction that needs no control leg (00:41Z)

P4 is why the readers change too rather than only the prose. The card was filed while this was a habit; it is a gate now, and 「a gate is much harder to walk back than a habit」.

What changed

  1. references/contract-review.md :29 and :56 — equal-line edits, file still 60 lines, both lines inside the 120-byte CJK prose budget (110 B and 120 B).
    • :29 — 「值写常量名 CONTRACT_REVIEW_TIER,可前置 N/N;无此行不成裁决。」
    • :56 — 「Served-tier: ≠ 常量名 ⇒ exit 4,点名 PR、评论、读数;型号串按 AGENTS.md 拒。」
    • The evidence stays exactly where :53 already puts it — the seat's transcript grep, which lands no artifact.
  2. check-clause2-carriers.mjs — new CONTRACT_REVIEW_TIER_NAME is the one accepted token; new isModelIdentifierToken() refuses the constant's value and the id shape (the word claude, a hyphen, a model word — a shape, never a list, so a model nobody has named yet binds). C7's remedy quotes the new rule lines and names AGENTS.md's rule, and ⛔ never quotes an identifier token back — a refusal that echoed it would land the identifier in one more artifact.
  3. check-governed-queue-guard.mjs — its references-tier record reader takes the predicate through the same lazy recogniser import (fail-closed on a rename: a missing export is available: false), carries the flag on the record so the renderer never re-decides it, and its merge-queue refusal prints no identifier either. Remedy 3 now spells the token as the NAME.

Neither gate is weakened. The line is still required, a missing line is still a refusal, the comparison is still EXACT — no family match, no prefix floor — and the accepted token is still exactly one. The only behavioural delta is which single token, plus one new refusal class.

Tests

Self-test batteries, on 57132927c. ⛔ No case deleted — 15 cases were re-spelled and the rest are additions:

battery before after delta
check-clause2-carriers --self-test 598 605 +7
check-governed-queue-guard --self-test 229 233 +4

The 598 baseline was measured by running origin/main's own copy of the file in this tree. The 229 is derived (4 added assert( calls, 0 removed), because that file's copy cannot be run against a modified sibling — its fixtures are the thing this PR changes.

New cases include: the constant's VALUE is refused; the refusal never quotes it back; the refusal names AGENTS.md's rule; a never-shipped id binds too (a SHAPE, not a list); the two refusals differ exactly on quoting; and the row is not widened.

Gate sweepnode scripts/pm/dispatch-gates.mjs --commands derived 43 families from the three changed paths; all 43 run, recorded with --ran:

✓ dispatch-gates --ran: 43 derived famil(ies) accounted for — 43 run,
  0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3).

pnpm --filter @objectstack/lint run check:doc-formula-expressions first returned exit 3 — PREREQUISITE NOT MET (unbuilt @objectstack/formula / @objectstack/lint, ⛔ not a finding); after turbo run build for those two packages under the shared verify lock it returned exit 0.

Lint — the full repository run, not a narrowed union: pnpm exec eslint . --no-inline-config --format json over 6741 files, 0 errors, 0 warnings, exit 0.

Legacy count — a reading for the seat, ⛔ not a work item here

origin/board-archive at bd7bbf53b (snapshot 2026-09-13T20:23Z), over the archived comment bodies:

probe count
Served-tier 0
lit control — Reviewed-by 88
lit control — CONTRACT_REVIEW_TIER 303

⚠️ Read this zero narrowly. Two corrections to how it was specified:

Landing note

This PR's own governed surface is .claude/skills/pm-dispatch/references/contract-review.mdcheck-governed-merges.mjs --test confirms it hits the register, so the PR is draft-only and human-merged, or lands on the references tier's review of record.

⚠️ The review of record on THIS PR must use the NEW formServed-tier: naming CONTRACT_REVIEW_TIER, ⛔ not its value — because the merge-group leg runs this PR's own guard. A record written in the old spelling is refused by the code this PR ships.

Acceptance notes

Open question surfaced by triage, ⛔ NOT decided here, and ⛔ AGENTS.md untouched. Triage named a class the rule as written does not distinguish: a preserved verbatim maintainer ruling that happens to contain an identifier vs. an identifier a seat emits as its own artifact. This PR only removes the second kind. A blanket cleanup that rewrote preserved maintainer quotes would be worse than the problem (座位制度原话照抄不译). Whoever reconciles AGENTS.md should decide that explicitly.

Out of scope, noted and not filed:

  • 238 occurrences of the constant's literal value already sit in archived comment bodies under board/. That is a pre-existing fact about historical compliance with the AGENTS.md rule, not about Served-tier: (which reads 0 there) — and no migration rides on this PR.
  • The C7 battery feeds the refusal an id nobody has shipped to prove it binds a SHAPE. Spelling it lands no identifier because it identifies no model — the same device check-commit-card-trailers.mjs's own battery uses. A comment beside the case now says so.
  • scripts/pm/dispatch-gates.mjs is untouched: it is a Restart-touch: trigger file of hold dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290, and the fix did not need it. The constant keeps its single value site there.

No changeset: the diff publishes nothing from any released package — .claude/** and scripts/pm/** are on the fast track, and no path in the diff appears in any package's files[].

Clause-②: no

维护者速读(草稿)

改了什么。 契约复核记录里那行 Served-tier:,原先要求写模型档位常量的(一串型号标识);现在改成写常量的名字。两个门禁(check-clause2-carriers.mjs C7、check-governed-queue-guard.mjs 的 references 档记录读取器)同步改判,并新增一条拒绝:凡写成型号串的一律拒,且拒绝文案不回显那个串。

为什么改。 AGENTS.md 明写「no model identifier lands in … a comment …」,而复核记录就是一条 GitHub 评论。优先序 AGENTS.md > 座位惯例,分诊已定向。关键是这笔交易零成本:协议本身就说自述档位不是读数,真凭据是座位的转录 grep,那个动作不落任何仓库产物 —— 所以删掉型号串不损失任何证据价值。

风险与代价(含回滚)。 风险低但有一个真实的过渡成本:本 PR 自己的复核记录必须用新拼写,因为 merge-group 那条腿跑的就是本 PR 带的守卫;用旧拼写写的记录会被拒。存量迁移不在本 PR(板存档读数 0,但那份存档的窗口早于本约定,所以「舰队里有多少条评论带旧拼写」仍未测)。回滚 = revert 两个 commit;门禁与规则文本同笔回到旧拼写,无数据迁移、无发布面。两侧门禁都只收紧不放宽:该行仍必填,缺行仍是拒绝。

席位意见。

你要做的。 确认「预留原文维护者裁决里出现的型号串」这一边界情形该怎么定 —— 本 PR 只清理座位自己产出的那一类,⛔ 没有动 AGENTS.md,也⛔ 没有改写任何被原样保留的裁决引文。


Generated by Claude Code

…identifier

A review of record is a GitHub comment, and AGENTS.md is unqualified about
that surface: no model identifier lands in a PR title or body, a comment, a
changeset, a doc or a code comment. The Served-tier: line required by the
in-seat contract-review protocol carried the constant's VALUE, so a record
could clear a carrier ONLY by putting an identifier into the very artifact
that rule names -- and two gates had already landed readers that compare
against that value, so the convention was on its way from a habit into a
gate, which is much harder to walk back.

So the accepted token is now the constant's NAME. Nothing evidential is
traded away: the line was never the reading. The protocol already says a
self-declared tier and a passed parameter are both non-readings, and the
authoritative control is the seat's own transcript grep against the
constant's value -- a grep that produces no repository artifact at all.

- references/contract-review.md: the two rule lines spell the token as the
  constant's name and name the refusal, at equal line count.
- check-clause2-carriers.mjs: C7 accepts the NAME; a token of identifier
  shape -- the old spelling included -- is refused with a remedy that names
  AGENTS.md's rule and never quotes the token back, because a refusal that
  quotes it lands the identifier in one more artifact.
- check-governed-queue-guard.mjs: the references-tier record reader imports
  that predicate (fail-closed on a rename) and carries the flag to its
  renderer, so the merge-queue refusal never prints one either.

Neither gate is widened: the line is still required, a missing one is still
a refusal, and the accepted token is still exactly one.

Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
Co-authored-by: Claude <noreply@anthropic.com>
The C7 battery proves the refusal binds a SHAPE by feeding it an id nobody
has shipped. Spelling it is safe precisely because it identifies no model,
and that is the same device the pre-push trailer rule's own battery uses --
worth one comment, so a later reader greps `claude-` and finds the answer
beside the case instead of filing it.

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

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Verification on the final head — 57132927c

⚠️ Posted as a comment rather than folded into the body: a bare REST PATCH /pulls is measured in this repo to APPEND a second, bare footer while keeping the existing session-URL one (references/platform-readings.md). The body stays as created.

Gate sweep, re-derived and re-run after the last commit. node scripts/pm/dispatch-gates.mjs --commands derived the same 43 families on 57132927c as on the first commit (set diff: empty). All 43 ran, exit codes captured BEFORE any pipe, all exit 0:

✓ dispatch-gates --ran: 43 derived famil(ies) accounted for — 43 run,
  0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3).

Lint, on the same head: pnpm exec eslint . --no-inline-config --format json6741 files, 0 errors, 0 warnings, exit 0. The whole repository, so no narrowing is claimed and none needs defending.

Ablation — the new refusal can actually fail

A guard that cannot fail is not a guard, so the new refusal was measured rather than asserted.

Mutation: one edit in servedTierStands() — accept the constant's VALUE as well as its NAME, i.e. exactly the widening this PR removes.

On-disk proof, before reading any result — the anchor was counted on both sides (1 occurrence of the removed text before, 0 after; 1 occurrence of the injected text after) and the blob hash moved (679dd831…ee9fb8ce…). ⛔ An editor's exit code is not evidence that anything reached disk.

Result:

battery mutated restored
check-clause2-carriers --self-test exit 1 — the three new #18060 cases failed by name exit 0, 605 pass
check-governed-queue-guard --self-test exit 1 — 2 of 233 failed, the record reading state: "stands" with servedIsIdentifier: true exit 0, 233 pass

⇒ the refusal is load-bearing in both files, and the guard leg fails through the imported predicate rather than a second parser of its own.

Restore proof: the target was checked out by naming HEAD explicitly — ⛔ never the bare two-dash form, which restores from the polluted index and exits 0 having undone nothing — then its blob hash compared equal to the HEAD blob and git diff HEAD read empty. The script armed a restore trap on EXIT, INT and TERM with an absolute repo-root path throughout, and treats an empty hash as a FAILURE rather than as nothing to compare.

⛔ No permanent artifact: the ablation is a one-shot proof, cited here and in the report, and no file from it is left in the tree.


Generated by Claude Code

@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author
  • Served-tier: 1638/1638 CONTRACT_REVIEW_TIER — harness model stamp counted over this seat's own transcript (non-sidechain assistant messages a model served; <synthetic> harness notices excluded) at 2026-09-14T01:08Z and compared to the constant's value outside the repository; get_session external_metadata.last_served_model read equal to the constant at 2026-09-14T00:20Z. This is the spelling this PR makes the only one; the merge-group leg reads this record with the reader this PR ships.

Contract review

Head: 57132927 (PR #18087, card #18060) — reviewed at 2026-09-14T01:08Z by the skills seat at the contract-review tier. Governed references tier (references/contract-review.md, two equal-line edits) + non-governed PM tooling ⇒ the in-seat record lands it (PR #18036's tier, enforced on the merge-group leg).

① derived judgments (seat-measured on the fetched head, ⛔ not taken from the report):

  1. The premise the card led with is falsified in the urgent direction, and the fix follows it: on origin/main both readers already REQUIRED the identifier (273a6650 feat(pm): gate the clause-② carrier strip on the served tier the verdict declares #17990 C7; 60b99552 feat(pm): teach the merge-queue guard the governed surface references tier #18036 the references-tier record reader), so the two contract-review.md lines and both readers change together; the guard imports the recogniser lazily, fail-closed on a rename — still exactly one parser.
  2. The accepted token is the constant's NAME and nothing else: servedTierStands compares served.value === CONTRACT_REVIEW_TIER_NAME; a token of model-identifier SHAPE (the constant's value, or claude + hyphen + a model word) is refused with a remedy that names AGENTS.md's comment rule and ⛔ never quotes the token back; a missing line is still a refusal; the comparison is still exact (a family prefix and a constant-prefixed suffix are still refused). ⛔ Neither gate is weakened — the deltas are which token, and one new refusal class.
  3. contract-review.md: line 29 值写常量名 CONTRACT_REVIEW_TIER; line 56 Served-tier: ≠ 常量名 ⇒ exit 4,型号串按 AGENTS.md 拒 — equal-line, 60/60; check-skill-line-ratchet exit 0 on the head (an archive with the governed tree present).
  4. Self-tests on the head: check-clause2-carriers --self-test 605 cases pass (main 598: +7 new, 15 re-spelled, 0 deleted — 14 of the 15 old case names reappear verbatim; the fifteenth is renamed on purpose, its old assertion 「the fixture carries the constant's value」 being the refusal now pinned); check-governed-queue-guard --self-test 233 cases pass (115 assert( lines before and after). The dev's ablation (accept the VALUE too) fails 3 named C7 cases and 2 guard cases through the imported predicate, then restores to the HEAD blob — falsifiable, no artefact left.
  5. Gates: --ran 43 derived / 43 run / 0 NOT-MEASURED / 0 UNRUN, re-derived on the final head; repo-wide eslint 6741 files, 0 errors; no changeset owed (.claude/** + scripts/pm/**, nothing in any files[]). Checks on the head at 2026-09-14T00:53Z: 38 — 21 green, 15 skipped, 2 running, 0 red.
  6. Byte hygiene: the dev's identifier probe over the three files, the PR body and the report — no match, with a lit control (dispatch-gates.mjs, 1 line: the constant's single value site, untouched — hold dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290's trigger file).
  7. Scope held: three files; ⛔ AGENTS.md untouched; Clause-②: no holds — no contract path. --pair 18087 with THIS PR's reader → exit 0 at 2026-09-14T01:08Z before this record; the post-record run is on the card's ACCEPT.

② semver: unchanged — nothing published.

③ boundary flags: (a) the preserved-verbatim-quotation class — AGENTS.md's comment rule says 「a comment」 without qualification, while seat posts carry maintainer rulings that contain identifiers under 原话照抄不译 — surfaced by triage and the dev, ⛔ not decided here; this seat files it as a decision card (option A recommended: carve out preserved quotations in AGENTS.md). (b) Legacy: Served-tier reads 0 in the board archive only because the archive's window (highest card #17600) predates the convention (#17990); the fleet count stays unmeasured; the dispatch's probe path archive/ does not exist on that branch (the archive lives under board/) — the seat's instruction was wrong, the dev read the right path. (c) Cross-seat: the domain:services seat's Routine and records spell the old form — once this lands its own --pair refuses that spelling; this seat knocks on #6021 with the new form on landing.

Implemented-by: claude/issue-18060-served-tier-identifier-free
Reviewed-by: session_01DAcomhvR9kKizeYgg89Vo8

Verdict: PASS — ready + auto-merge by this seat.


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 14, 2026 01:08
@os-project-manager
os-project-manager added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 66e34d1 Sep 14, 2026
41 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-18060-served-tier-identifier-free branch September 14, 2026 01:36
This was referenced Sep 14, 2026
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 17, 2026
…reserved as a quotation block (objectstack-ai#18315)

Fixes objectstack-ai#18092

## What this PR does

`AGENTS.md`'s comment rule (the **Commit message:** sentence group,
:440–:444) gains the one closed exemption ruled on the card, in place,
at the 1075-line ceiling. No probe changes, because none reads prose for
model identifiers (measured below). The diff is four lines of
`AGENTS.md` and nothing else.

Landing: this is the rules layer, so this PR is a **draft and stays
one** until an authorized APPROVED review; the owning seat lands it
afterwards. Per ruling C on objectstack-ai#17971, no seat readies, queues or arms it,
and this dev requests no reviewer. `skip-changeset`: nothing published
moves.

## The ruling (comment 5682890409, letter A, quoted verbatim and
untranslated)

> - **A** — AGENTS.md's comment rule (:442 「no model identifier lands in
a PR title or body, a comment, a changeset, a doc or a code comment」)
gains one closed exemption: **a verbatim maintainer ruling preserved as
a quotation block** (the seat-post protocol's 「原话照抄不译」 act). The
exemption names the quotation form only; a model identifier a seat
writes in its own prose stays a violation (PR objectstack-ai#18087's class).
> - The model-identifier probes (the H64 family and any 型号探针 audit)
exclude quotation blocks so they stop counting preserved rulings.
> - **B** (rewrite preserved rulings) and **C** (leave it to each seat)
are refused; triage 5656662371's reading stands: a cleanup that rewrites
maintainer quotes would be worse than the problem. ⛔ No existing
quotation is edited.

## The sentence (before → after, `AGENTS.md` :440–:444)

Before (five lines, 77 / 107 / 111 / 104 / 113 bytes):

> …no model identifier lands in a PR title or body, a comment, a
changeset, a doc or a code comment. The one exemption is a REPORTING
one: a harness-written `Co-Authored-By` trailer is not declared a
deviation; the pair stays model-free; landed history is not rewritten.

After (five lines, 77 / 115 / 116 / 119 / 110 bytes; :440
byte-identical, :441–:444 reflowed within the same five lines):

> …no model identifier lands in a PR title or body, a comment, a
changeset, a doc or a code comment. Two exemptions: a harness-written
`Co-Authored-By` trailer (REPORTING: not declared a deviation; landed
history is not rewritten) and a verbatim maintainer ruling preserved as
a quotation block.

The exemption phrase is the ruling's own wording. The maintainer edits
wording and placement at review — nothing here is polished beyond the
ruling.

### Why in place, and what paid for it (the breach the dispatch asked me
to stop on)

The dispatch's route was "extend :443–:444 in place; a long line is
legal there (14 lines already exceed 120 chars)". Measured: `pnpm
check:pm-skill-ratchet` applies a 120-byte width rule to every ceilinged
file, `AGENTS.md` included, and the 14 over-width lines are all table
rows or the one blockquote — structurally exempt classes. A prose line
over 120 bytes goes red (`lengthVerdict`, silent on pass). So the
sentence had to fit five lines of at most 120 bytes each. Byte math
(greedy wrap, code spans as atoms): the group's usable capacity is 77 +
4×120 minus wrap loss; every wording that also kept the clause "the pair
stays model-free" and the 「原话照抄不译」 parenthetical needed a sixth line
(the tightest such wording overflowed by exactly the 27-byte
parenthetical). No line in the paragraph says nothing the new sentence
does not, so the "paid line in the same paragraph" route had no
candidate.

What paid: **the deletion of the restated clause "the pair stays
model-free;"** — :440 already says the commit "ends with the model-free
trailer pair" and :442 says "the pre-push hook refuses a model
identifier in that pair", so the clause restates the sentence group's
own first sentence and its hook. Content deletion is the ratchet's only
legal currency; no line was folded to buy one (line count 1075 → 1075,
and the reflow of :441–:444 frees nothing). The 「原话照抄不译」 act-name is
carried here and on the card rather than in the sentence; the maintainer
may prefer it in the sentence, in which case the ceiling needs a ruled
+1 (the ratchet's `CEILINGS` entry for `AGENTS.md` has precedent for a
ruled raise) — that is the maintainer's call, not this dev's.

## The probes — measured; none reads prose for model identifiers, so
none changes

| candidate | what it reads | keys on identifiers? | reads prose? |
|---|---|---|---|
| `scripts/check-commit-card-trailers.mjs` (:848 iterates four id
literals in its self-test) | the trailer BLOCK of unpushed commit
messages; header: 「WHAT IS JUDGED is the trailer VALUE, and only inside
the trailer block」, 「⛔ NOT the message body」 | yes — `MODEL_ID_FORM` on
the trailer value | no |
| `.githooks/pre-push` | invokes the gate above with the pushed refs |
via the gate | no |
| `scripts/check-agent-model-declared.mjs` | the YAML frontmatter
`model:` key of `.claude/agents/*.md`; a `model:` mention inside
description prose is pinned as NOT a declaration | validates the pin's
shape | no |
| `scripts/pm/check-clause2-carriers.mjs` (`isModelIdentifierToken`) |
the single `Served-tier:` token of a review-of-record comment; header:
「What a seat writes AFTER the token is its argument, which this file
does not read」 | yes — on that one token | no |
| `scripts/pm/check-governed-queue-guard.mjs` | the same `Served-tier:`
token through the clause-2 predicate | yes — same token | no |
| `scripts/pm/check-half-states.mjs` H64 | a seat/dev-signed artefact
that names no `session_` id (`h64SpeaksAbout` = seat signature present
AND no session id) | no — session ids, not identifiers | reads bodies,
but never for identifiers |
| `scripts/pm/check-half-states.mjs` H65 (merged from `origin/main` at
`10a7b9fa` during this PR) | a triage round artefact that names no tier
| no | same |
| `.claude/hooks/*`, `packages/lint/scripts/*`, `.github/workflows/*` |
— | zero identifier-shaped regexes (one workflow comment mentions a pin)
| no |
| a 型号探针 recipe in the skill tree | grep of
`.claude/skills/pm-dispatch/**` and `.claude/agents/**` for 型号 / 探针 | no
such recipe exists; every 探针 hit is a REST/queue probe | — |

So the ruling's probe half has no in-tree target: the seat's own ad-hoc
greps were the only "型号探针", and they are not repository code. A
self-test case "a quotation block carrying an identifier is not counted;
a seat-prose identifier still is" has nothing to attach to without
inventing a new prose scanner, which would be scope the card does not
carry.

## Quotation form (measured on the protocol and the live seat posts)

The protocol names the act as 裁决引文照抄不译
(`.claude/skills/pm-dispatch/SKILL.md` :100; `references/core-rules.md`
:26) and `AGENTS.md` Communication says 「引用中文裁决时保持原文、不翻译」. On the live
posts, every identifier-carrying preserved ruling is a 「…」
corner-bracket span inside prose labelled 原话照抄不译 / 逐字 / verbatim — objectstack-ai#6015
L128 and L130, objectstack-ai#6021 L24, L34 and L136 — and zero are Markdown
blockquotes (`> …`); the 47 blockquote lines in objectstack-ai#6015 are the seat's own
correction notes, objectstack-ai#6021 and objectstack-ai#7623 carry none. The ratchet's own
exemption classes already recognise both shapes as verbatim maintainer
rulings (`quotation` = a multi-line 「…」/『…』 ruling; `blockquote` =
「Every blockquote in this corpus is a verbatim maintainer ruling」). The
sentence pins the ruling's letter, "a quotation block", and this PR pins
no narrower form in code because no code reads one.

## Verification

- Gates derived on the merge commit `b671f83b` by `node
scripts/pm/dispatch-gates.mjs --commands` (14 families, identical to the
derivation on `dc3d1c16`): `check-closing-keyword-parity` (+
`--self-test`), `check-comment-mask-corpus`,
`check:agent-test-spelling`, `check:docs-audit-scope`,
`check:driver-memory-census`, `check:nul-bytes`,
`check:pm-governed-merges`, `check:pm-governed-prose`,
`check:pm-skill-id-lint`, `check:pm-skill-ratchet`,
`check:refd-timer-probe`, `check:required-contexts`,
`check:watch-hint-literal` — all exit 0; `--ran` reconciliation: 「14
derived famil(ies) accounted for — 14 run, 0 NOT-MEASURED」.
- `pnpm check:pm-skill-ratchet`: 「AGENTS.md is 1075 lines (ceiling 1075;
headroom 0)」, no width offender; `check:pm-skill-id-lint`: 27 files
clean; `node scripts/check-self-test-wired.mjs`: exit 0. The battery
`check:pm-dispatch-gates` was not derived and was not run; no `.mjs` was
touched, so no ESLint run is owed.
- Ablation from the committed state (`dc3d1c16`, whose `AGENTS.md` blob
`98e7cd4a` is the merge commit's blob too): base blob `7c7a5eee`
restored with `git restore --source=BASE` (on-disk hash proven equal) →
the sentence count reads 0 and the restated clause reads 1, ratchet exit
0 at 1075 lines; HEAD blob restored with `git checkout HEAD --
AGENTS.md` (hash proven equal), `git diff HEAD` and `git status
--porcelain` both empty; restore trap on EXIT/INT/TERM. On HEAD the
sentence count reads 1 and the restated clause reads 0.

## Acceptance notes

- noted, not filed: the dispatch's premise that a long prose line is
legal in `AGENTS.md` is false under the ratchet's width rule; the 14
over-width lines are table rows and one blockquote. 承接者: the skills
seat's next `AGENTS.md` dispatch reads the `lengthVerdict` exemption
classes before choosing "extend in place".
- noted, not filed: the ruling's probe half names 「the H64 family」; H64
keys on session ids and never on identifiers, so the exclusion it asks
for has no code to land in. 承接者: the director seat, if a prose scanner
is ever proposed.
- `origin/main` moved once under this branch (objectstack-ai#18311,
`scripts/pm/check-half-states.mjs` only); merged in, never rebased; the
union was re-run on the merge commit.

## 维护者速读(草稿)

**改了什么**:`AGENTS.md` 的评论规则句组(:440–:444)从「唯一豁免是
REPORTING」改为「两条豁免」:harness 写入的 `Co-Authored-By`
trailer(REPORTING:不申报为偏差;已落地历史不改写)与逐字保存为引用块的维护者裁决。行数 1075 → 1075,每行 ≤120
字节。

**为什么改**:你在 objectstack-ai#18092 批准了
A:座位贴按制度把你的裁决原话照抄不译,原话里若带型号,转抄不算违规;席位自己写的型号仍算。探针半边:仓库里没有任何脚本按型号扫描散文(逐一实测列在正文表格),所以没有探针要改。

**风险与代价(含回滚)**:代价是删掉了「the pair stays model-free;」这句重述(句组首句与 pre-push
hook 已各说一次),以及豁免句里没放 「原话照抄不译」 这个名字(字节装不下;若你要放进去,需要你裁一次上限 +1)。回滚 = revert
这一个提交,无发布物。

**席位意见**:(留空,席位定稿)

**你要做的**:审阅措辞与位置(你可直接改),若同意则给 APPROVED,由 skills
席落地;不同意「删重述句」的付账方式,则改裁「上限 +1」或指一行删除。

---
_Generated by [Claude
Code](https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr)_

Co-authored-by: Claude <noreply@anthropic.com>
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 domain:skills size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants