Skip to content

docs(agents): cite by content, not by line address (#8875 clause 1) - #9301

Merged
os-zhuang merged 4 commits into
mainfrom
claude/issue-8875-cite-by-content-convention
Sep 14, 2026
Merged

os-zhuang merged 4 commits into
mainfrom
claude/issue-8875-cite-by-content-convention

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Part of #8875PR 2 of two, clause 1 only. PR 1 landed as #8974 (efead6c60) and carried clauses 2, 3 and 5; this one carries the human-facing convention that gate enforces. ⛔ This PR does not close #8875 on its own.

⛔ Governed surface — draft only

The diff touches AGENTS.md, so the whole PR is governed: ⛔ not flipped ready, ⛔ not enqueued, ⛔ no auto-merge, ⛔ no self-approval. It waits for a human merge, and that is the correct terminal state, not a failure. Confirmed mechanically rather than asserted:

node scripts/check-governed-queue-guard.mjs --test AGENTS.md .changeset/issue-8875-cite-by-content-convention.md
⛔ GOVERNED — 1 of 2 path(s) are on a governed surface:
   AGENTS.md x1 — the repo-root agent instruction file

The premise was re-derived on today's tip, with a firing control

The dispatch that queued this measured zero cite-by-content sentences in AGENTS.md on 2c208d5bb (2026-09-10). That reading is two days old, so it was re-taken on 243fc8317e (2026-09-12T14:56:42Z) with the control in the same run:

pattern in AGENTS.md hits
cite (case-insensitive) 0
按内容 0
行号 0
line address 0
line-address 0
path:line 0
8047 / 7853 0
\.(ts|tsx|mjs|md|js):[0-9]+ 0
firing controlobjectui# 26

The control fires (26, up from the dispatch's 22 — the file grew in between), so the zero is a reading and not a broken grep. The only three hits for 引用 in the file are session 引用 and issue 引用 in the GitHub-body-rewriting section — a different sense of the word, not a cite-by-content sentence. ⇒ the clause's 「若已有 cite-by-content 句则引之」 branch does not apply; this is new text.

What was added

One new commandment in ## 5. Coding Standards, #10 — Cite by CONTENT, not by line address; a CROSS-FILE path:line is banned outright, placed after #9 (the closest neighbour in kind — "point at the instrument, never write down its answer"). Five sub-points:

  1. The rule and its history. Cite by a quoted distinctive string, a symbol name, a test name, an anchor — never a path:line. A line address is read by nothing, so it cannot fail; it rots the first time a line is inserted above what it cites. finding(examples): component-fixture-declared-keys.test.ts cites safe-validate-corpus-6318.test.ts:98 by LINE — a comment-only edit above that line moves it, and nothing goes red #7853 ruled the class (fa7d66c45); finding(core): one it() test NAME still cites tsconfig.typetests.json — the last stale citation, left as out-of-scope by the comment-only sweep #6548, finding(scripts): js-comment-mask.mjs cites two line numbers as evidence and both point at the wrong line (86 and 107 lines off) #6998, finding(gate): the baseline-prose pin generalises to scripts/vite-declared-lazy-views.ts, but only its VALUE half — that file cites five commits with nothing live to check them against #7289, finding(plugin-markdown): toc-anchor-parity cites packages/react/README.md by line address (:224) and the heading has moved to :253 — a citation nothing checks #7913, finding(types): text-value-retired-6951.test.ts names two cases by line address (layout.ts:66) — accurate today, checked by nothing #8045 were the one-at-a-time repairs, and the class kept recurring.
  2. ⭐ The point this card adds. gate(tests): a file:line citation inside a test NAME is read by nothing — five recurrences under a standing ruling, and per-instance repair has not closed the class #8047 mechanized the ruling for test names only, deliberately exempting comments and failure messages on the ground quoted from that rule's own header — "A human reads them beside the code they annotate, and the next reader of that code corrects a wrong one." That justification is positional: it holds for a SAME-FILE citation and does not survive the citation crossing a file boundary. The reader of packages/types/src/crud.ts is not looking at packages/core/src/actions/ActionRunner.ts; nothing puts the cited line in front of them and nothing tells them it moved. The blast-radius measurement (73 hits / 4 syntaxes, 14 moved by one branch's line shifts, 10 of the 14 already false before the branch existed) is recorded explicitly as a historical reading, ⛔ not as a live count — §5 #9 applied to the new text.
  3. The maintainer's ruling, 原文照录、不翻译.
  4. The gate is DIFFERENTIAL. Points at pnpm check:new-line-citations and its ENFORCEMENT constant rather than restating today's mode, and says why an absolute count was refused. Existing citations are ⛔ not the denominator.
  5. Existing citations — repair when you touch the file, ⛔ never as a sweep; ⛔ never re-address a published CHANGELOG; dist/*.d.ts is unresolvable, not a finding. Plus the stored vs computed dividing line for line-number ledger keys.

Fences observed

Changeset

.changeset/issue-8875-cite-by-content-convention.md, empty frontmatter (--- immediately followed by ---) — AGENTS.md §9's first-class way to declare "no release". A patch would version-bump the 39-package fixed group for a change no consumer can observe. git status showed A (new file), not M: the pre-existing .changeset/8875-cross-file-line-citation-census.md was not clobbered.

Gates — exit codes captured before any pipe (cmd > log 2>&1; EXIT=$?)

Run on the merged tree (origin/main merged in immediately before opening, AGENTS.md being hot; merge was clean and brought no AGENTS.md change).

gate exit verdict line
check-changeset-presence 0 ✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major 0 ✅ No changeset declares a major bump.
check-control-bytes 0 ✅ OK (scanned 7494 tracked text file(s); skipped 85 binary)
check-doc-links 0 Links are valid across 17 scan roots.
check-shell-escape-residue 0 ✅ OK (5/5 root(s) resolved — AGENTS.md: 1 file(s), 15 fence(s) …)
check-doc-fence-languages 0 ✅ every TypeScript block in 227 document(s) is fenced ts/tsx/typescript …
check-doc-expression-carriage 0 ✅ Controls pass … ✅ Blind spot: none
check-new-cross-file-line-citations 0 VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0 — all four synthetic controls PASS
check-governed-queue-guard --test 3 ⛔ GOVERNED — the classification this PR wants, not a failure

⚠️ One declared narrowing, not a silent skip: check:doc-examples / check:doc-snippets exit 2 = PREREQUISITE NOT MET locally — they need all 39 packages built (… declares types at packages/*/dist/index.d.ts and it is not on disk). That is NOT MEASURED, neither green nor red. They type-check TypeScript fences in documents, and this diff adds zero fences (git diff … | grep -c '^+```'0), so there is nothing new for them to judge. CI runs them on the full build.

Also 0 control bytes by an independent scan of the changed files: grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' → exit 1 (no match).

维护者速读(草稿)

改了什么 — 给 AGENTS.md 的 §5 加一条 #10:引用代码时按内容指(引一段有辨识度的字符串、符号名、测试名、锚点),⛔ 不写 路径:行号;跨文件的行号引用一律禁止,同文件的保留 #8047 的既有豁免。另加一个空 frontmatter 的 changeset(声明不发版)。⛔ 只动这一个文件,scripts/** 一行没碰。

为什么改 — 这是维护者 2026-09-10 裁决 C 的第 1 条,#8974 已经把第 2/3/5 条(那道差分门)落地了,门有了但人读的约定还不在规程里。本卡真正新增的那一点是:#8047 之所以豁免注释和消息串,理由是「人读它的时候它就在被注释的代码旁边」——这个理由是位置性的,跨了文件就不成立:读 A 文件的人不会看着 B 文件,没有任何东西告诉他被引的那行已经挪了。一次 PR 范围内实测:73 条跨文件引用,14 条被那一个分支的行位移挪偏,其中 10 条在分支存在之前就已经是错的

风险与代价(含回滚) — 风险极低:纯规程文本,不影响任何运行时、不发版、不改门禁行为。代价是 AGENTS.md 又长了 7 行。回滚就是 revert 这一个 commit,没有任何下游依赖它。⚠️ 一个真实但已知的副作用:这条约定把差分门(目前 report-only)的规范依据写死了,以后有人想把门翻成 blocking 时,不需要再重新裁一次。

席位意见(留空,等席位定稿成评论)

你要做的 — 读一遍 §5 新增的 #10,确认措辞符合你 2026-09-10 那句裁决的本意(那句原话已逐字照录在条文里,未翻译),然后由你来合并——这是受管面,agent 不翻 ready、不入队、不自批。

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

Adds Coding Standard #10 to AGENTS.md: when a comment, a failure message,
a doc, a changeset or a script header cites an assertion, a call or a line
of code, cite it by CONTENT — a quoted distinctive string, a symbol name,
a test name, an anchor — never by a `path:line` address.

objectui#7853 ruled the class (landed `fa7d66c45`); objectui#8047 mechanized
it as the `no-line-address-in-test-name` ESLint rule over TEST NAMES ONLY,
deliberately exempting comments and failure messages because "a human reads
them beside the code they annotate". #10 records the point this card adds:
that justification is POSITIONAL. It holds for a same-file citation and does
not survive the citation crossing a file boundary — nothing puts the cited
line in front of the reader of the citing file, and nothing tells them it
moved. The clause also records the stored-vs-computed dividing line for
line-number ledger keys, and that repair is opportunistic, never a sweep.

This is the human-facing convention that the differential gate landed by
objectui#8974 enforces. No released package source is touched, so the
changeset carries empty frontmatter (declares "no release") rather than a
patch bump of the 39-package fixed group.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 12, 2026
@claude

claude Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

ACCEPT — reviewed against the DIFF. ⛔ Terminal here: governed surface, draft, awaiting a human merge.

domain:devx @ objectui PM seat (session_01FhBNJcLRZLe8M87VcUgpKr), R55, 2026-09-12T15:4xZ. Head ad4a3c65c7, base 345e24a0c8. Two files, +21 / −0AGENTS.md +7, changeset +14.

Verified, ⛔ not taken from the report

  • Scope held. AGENTS.md + its changeset only. scripts/** untouched — PR objectui#8974 / efead6c60 already landed that half.
  • Self-consistency, the check this particular PR had to survive: a rule banning cross-file path:line must not contain one. Added lines scanned for <name>.<ext>:<digits>zero hits. The two file paths it does name (crud.ts, ActionRunner.ts) carry no line numbers, which is the rule demonstrating itself.
  • Changeset correct: git diff --name-status reports A, not M — the pre-existing .changeset/8875-cross-file-line-citation-census.md was not clobbered. Frontmatter is genuinely empty (--- immediately followed by ---), the AGENTS.md §9 first-class 「no release」 declaration. ⛔ Not a patch bump, which would have version-bumped the 39-package fixed group.
  • Every existence claim in the new text re-derived on the head, because a standard that names instruments is only as good as their existing:
claim in the text verified
pnpm check:new-line-citations ✅ in package.json
pnpm census:cross-file-line-citations ✅ in package.json
workflow Line Citation Gate .github/workflows/line-citation-gate.yml
the script's ENFORCEMENT constant export const ENFORCEMENT = 'report-only';
placed after #9 #9 at :109, #10 at :110

⭐ Three things this round got right that are worth naming

  1. It labels its own numbers as historical. 「73 cross-file hits … 10 of those 14 were already false」 is written as 「a historical reading, ⛔ not re-derived here and ⛔ not a live count」. This lane spent today undoing the opposite habit — a dev read a figure out of a brief and reported it as a fact about its own card, and a refutation nobody re-measured blocked a correct card for ~13h. A standard that dates its own measurements cannot do that to the next reader.
  2. It points at ENFORCEMENT instead of restating 「report-only」 — and says so: 「⛔ Never copy either instrument's answer into prose — that is 完善设计器的每一个细节 #9 applied to this rule.」 The new commandment obeys the one above it. That is the difference between a standard and a snapshot.
  3. The stored-vs-computed dividing line is a real addition, not restatement: a path:line a script computes at runtime to print a diagnostic cannot expire, while one stored and compared — a ledger key, a baseline entry — is the same defect with a gate wired to it, so it fails loudly instead of rotting quietly.

⭐ The measurement was re-derived on today's tip rather than inherited from the dispatch's 2026-09-10 reading, with the firing control in the same run: objectui# = 26 hits today against the dispatch's 22 — the file grew, the control HITS, so the zero is a reading and not a broken grep. ⇒ the clause's 「若已有 cite-by-content 句则引之」 branch correctly did not apply.

⛔ Terminal shape — and this is the end of this seat's path

AGENTS.md is a governed surface. Read back from the API: draft: true, requested_reviewers: [hotlong, os-zhuang], auto_merge: null, merged: false. ⛔ This seat will not flip it ready, enqueue it, arm auto-merge, approve it, or merge it, at any point and under any framing. The remaining step is a human merge — 「落地需要人工合并,但判断不需要维护者」.

objectui#8875 stays open on this PR, as it has since PR 1: Refs, ⛔ not a closing keyword. ⚠️ It is now the head of this lane's AGENTS.md serial queue — objectui#7800 (PR objectui#8952) merged 2026-09-10T12:55Z and objectui#7833 closed 2026-09-11T06:53Z, so nothing is ahead of it. objectui#9213 is next behind and ⛔ must not be dispatched until this merges.

⚠️ Declared narrowing, recorded rather than buried: check:doc-examples and check:doc-snippets exited 2 = PREREQUISITE NOT MET locally (they need all 39 packages built). That reads NOT MEASURED, ⛔ not green. The diff adds zero code fences, so they have nothing new to judge, and CI runs them on a full build.


Generated by Claude Code

claude Bot and others added 2 commits September 14, 2026 07:53
…e-by-content-convention

Resolve the AGENTS.md numbering collision: bde0780 (#9257) landed
"Never depend on the IDENTITY of a useMemo / useCallback result" as
commandment #10 on main after this branch's base, and this branch had
already claimed #10 for "Cite by CONTENT, not by line address".

Both rules survive. Main's #10 keeps its number byte-identical; this
branch's commandment is renumbered #10 -> #11. That single digit is the
only byte changed in the approved text — the heading tail and all six
sub-bullets are byte-identical to head ad4a3c6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VGeMu3p6qEFWR6K6GGLaW
… not #10

The merge that reconciled this branch with main renumbered this branch's
commandment from #10 to #11, because bde0780 (#9257) had already taken
#10 for "Never depend on the IDENTITY of a useMemo / useCallback result".
That renumber left this changeset naming #10 in two places, where #10 now
resolves to main's rule instead of this one.

Body text only; the frontmatter stays empty and still declares no release.
Two bytes change, both a '0' becoming a '1'. Neither occurrence referred to
main's rule -- the file mentions no useMemo/useCallback/identity text at all.

A stale by-number citation inside the pull request that bans stale by-number
citations is the rule failing on its own diff, which is why this is repaired
here rather than left to the changeset's deletion at version time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VGeMu3p6qEFWR6K6GGLaW
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit c0dab26 Sep 14, 2026
35 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-8875-cite-by-content-convention branch September 14, 2026 08:44
jinyitao123 pushed a commit to jinyitao123/objectui that referenced this pull request Sep 16, 2026
…the contract-review carrier) (objectstack-ai#9466)

Fixes objectstack-ai#9213

## ⛔ This PR is GOVERNED and opens as a DRAFT — the draft state is the
FINISHED state

`AGENTS.md` is governed surface. Verbatim verdict from this branch:

```
$ node scripts/check-governed-queue-guard.mjs --test AGENTS.md   # exit 3
⛔ GOVERNED — 1 of 1 path(s) are on a governed surface:
   AGENTS.md x1 — the repo-root agent instruction file
     - AGENTS.md

   One governed path governs the WHOLE pull request — proportion is not a question.
   ⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge
      to the maintainer; a human merge IS the review record for a governed surface.
   The merge-queue run of "Governed Surface Queue Guard" refuses this diff unless an APPROVED review by an
   authorized approver (GOVERNED_APPROVERS: os-zhuang, hotlong) is on the pull request — on
   whichever commit it was left (maintainer ruling 2026-09-04).
```

⚠️ **The draft state does not mean the work is unfinished.** The change
is complete and the gates
are green. A governed PR needs a human `APPROVED` review from
`GOVERNED_APPROVERS`
(`os-zhuang` / `hotlong`) and a **human merge**. No agent seat will flip
this ready, enqueue it,
arm auto-merge, or approve it.

## What is wrong

`AGENTS.md` § 受管面 states the queue guard's `merge_group` refusal
predicate as **one** thing: an
authorized latest-decisive `APPROVED` review. Since objectstack-ai#9018 / PR objectstack-ai#9212
that leg carries **two
independent predicates**:

| leg | predicate | exits |
|:--|:--|:--|
| governed surface | an authorized latest-decisive `APPROVED` review
record | 3 · 4 · 5 |
| contract-review carrier | no queued pull request carries
`needs:contract-review` | 6 · 7 |

⇒ **a merge group whose diff touches nothing governed at all can now be
refused.** The paragraph
says the opposite *by omission*, and the error points in the
**permissive** direction.

The paragraph's existing caveat (「覆盖面以脚本自己的 `GOVERNED_SURFACES` 为准」)
does **not**
already cover this. It delegates the **surface list**. The carrier leg
reads **no surface at all** —
it reads a **label on the pull request**.

## Measurements, re-derived on this branch's base (`f5b9c17973`), not
inherited from the card

**1. The exits exist and mean what the card said.**

```
$ git grep -n 'EXIT_REFUSED_CARRIER' origin/main -- scripts/check-governed-queue-guard.mjs
origin/main:scripts/check-governed-queue-guard.mjs:258:export const EXIT_REFUSED_CARRIER = 6;
origin/main:scripts/check-governed-queue-guard.mjs:259:export const EXIT_REFUSED_CARRIER_UNREADABLE = 7;
```

6 = a queued pull request carries the label (`refusalKind: 'gated'`). 7
= a label set could not be
read, or the group names no pull request at all (`refusalKind:
'unreadable' | 'no-pull'`).

**2. The carrier leg reads a LABEL, not a surface.** Code path, all in
`scripts/check-governed-queue-guard.mjs`:

`runCarrierGuard({ event, rows, namedPull, fetchLabels })` →
`carrierPullsInGroup(rows, namedPull)`
enumerates the queued PRs **per commit** → for each, `await
fetchLabels(pr)` → the whole predicate is
`names.includes(CONTRACT_REVIEW_LABEL)`, where `export const
CONTRACT_REVIEW_LABEL = 'needs:contract-review'`.
**No path, no diff, no surface set is consulted anywhere on this leg.**
The file says so itself:

> the carrier is REMOTE state hung by a seat, not a property of the
diff. So every merge group pays
> one label read per queued pull request. ⚖️ THE ACCEPTED COST … a
GitHub outage now refuses a merge
> group whose diff touches nothing governed, which the governed leg
alone never did.

**3. `AGENTS.md` carried no mention of it.** ⚠️ Read as **TEXT with
whitespace collapsed**, not with a
line-oriented grep — the target is one enormous wrapping sentence on a
single physical line (1434
chars), and a line grep cannot be trusted to answer a question about a
sentence.

```
needs:contract-review     0      |  GOVERNED_APPROVERS  3   (control, HIT)
contract-review           0      |  merge_group         2   (control, HIT)
carrier                   0      |  latest-decisive     2   (control, HIT)
承载 / 合同评审 / EXIT_REFUSED_CARRIER   0
```

Every zero is carried by three controls that HIT in the same run, in the
same file, with the same
reader.

**4. `content/docs/guide/ci-cd-pipeline.md` (NOT governed) already
carries the corrected account** —
PR objectstack-ai#9212 updated it. This is the strongest available basis for a minimal
correction: the wording
below is **propagated from settled prose already in the tree**, not
invented here.

> **The second leg: the contract-review carrier.** On a **merge-queue
build only**, this check
> carries a second and completely independent predicate, keyed on a
*label* rather than on paths
> (objectstack-ai#9018, a re-implementation of the leg objectstack landed as its own
`objectstack#17484`). It
> enumerates **every** pull request the merge group is landing — per
commit, exactly as the governed
> leg does, because `merge_group.head_ref` names only the *last* pull
request in the group and keying
> on it would let an earlier pull request's open carrier ride into
`main` behind a clean one — reads
> each one's labels from the pull object … and refuses while
`needs:contract-review` is on any of
> them (**exit 6**) or when a label set cannot be read or the group
names no pull request at all
> (**exit 7**, split from 6 for the same reason 4 is split from 3). The
`pull_request` leg is
> untouched and reads no label.

Its row in the same file's check table already says it too:

> a governed-surface diff with no authorized approval record (on any
commit) is refused there, and so
> is any merge group whose queued pull requests still carry
`needs:contract-review`

## ⭐ The wording is the maintainer's to amend — that is why the diff is
this small

objectstack-ai#9213 declines to propose wording, verbatim: 「**Not proposing the
wording.** What the paragraph
should say is a maintainer's call, not a seat's, and the file is
governed precisely so that it is.」
This PR therefore makes the **minimal factual correction** and nothing
else.

**`diff --numstat` → `1 1 AGENTS.md`.** One line changed, because the
paragraph is one physical
line. Text was **added**; nothing was removed.

**What I deliberately did NOT touch:**

- ⛔ did not restructure the paragraph into a two-predicate list, though
that reads better
- ⛔ did not re-translate, re-punctuate, shorten or otherwise "improve"
any existing prose
- ⛔ did not touch the 「覆盖面以脚本自己的 `GOVERNED_SURFACES` 为准」 caveat, even
though it is the
sentence a reader is most likely to over-read (see the alternatives
below)
- ⛔ did not touch any other paragraph, section or file — not the guard
script, not the workflow, not
  `content/docs/guide/ci-cd-pipeline.md`
- ⛔ did not rule on anything the card declined to rule on
- ⛔ did not touch objectstack-ai#9301's region (lines 107..112); this change is in the
受管面 paragraph near line
  522. Verified non-overlapping.

Register: the insertion is Chinese prose with inline code spans,
half-width punctuation
(`,` `;` `:` `(` `)` — measured on the target line: 27 `,`, 13 `()`, 9
`:`, 5 `;`; the only two
full-width `,` in that line are inside the verbatim untranslated
maintainer quote), and the
paragraph's existing ⚠️ / ⇒ / `**bold**` markers. No English sentence
was introduced.

## ⭐ Alternative phrasings I considered — offered here, NOT put in the
file

The maintainer should feel free to take any of these instead; amending
one line is cheap by
construction.

1. **(taken)** One appended sentence-block after the 已接受的代价 caveat and
before 「⚠️ 但它**尚未**是
required context」, opening 「⚠️ 而这条拒绝腿上的判据**不止上面那一条**」. Chosen because it
lands
while 「`merge_group` 腿才是会拒绝的那条 —— 它要求 …」 is still in the reader's eye,
and because the
following 「但它尚未是 required context ⇒ 那条拒绝腿只报告、不阻止队列」 is true of **both**
   predicates, so it now correctly scopes over both.
2. **Restructure into 「它有两条相互独立的拒绝判据:① … ② …」.** Clearer, and what I
would write from
scratch. Rejected: the card forbids restructuring, and it would rewrite
bytes the maintainer
   already ruled on (the 2026-09-04 sha-pin retirement wording).
3. **Insert immediately after 「它要求 [predicate 1] …(维护者 2026-09-04 裁
…)。」, before the
已接受的代价 caveat.** Tightest possible placement. Rejected: 「已接受的代价:批准之后的
push 不再
被这道门重审」 would then have my sentence between it and its antecedent, and
「这道门」 could be
misread as the carrier leg — for which that cost is not the accepted
cost.
4. **Append at the very end of the paragraph, after the
`GOVERNED_SURFACES` caveat**, so it could say
「上面那句托付的是受管面清单,⛔ 不是判据清单」. Rejected: it leaves five sentences of the
paragraph
reading false before the correction arrives. I got the same protection
without the cross-reference
by stating plainly that the leg 「不读任何路径」 — a reader who then meets a
delegation about 覆盖面
   cannot mistake it for covering a leg that reads no surface.
5. **Also correct the `--test` renderer's own advisory text**, which
describes the merge-queue
refusal with the approval predicate alone (quoted at the top of this
PR). Rejected: out of scope
for objectstack-ai#9213, and it is a different file. Reported to the PM rather than
fixed here.

## Gates — PRE / POST, exit codes captured by redirect-then-capture,
never across a pipe

PRE = base bytes restored from `HEAD` by explicit ref; POST = this
commit. The restore leg was proven
by `git hash-object` comparison (base `30f47ec4b5…`, post
`eb017a9f30…`), not by an exit code.

| gate | PRE | POST |
|:--|:--|:--|
| `check:control-bytes` | 0 | 0 |
| `check:new-line-citations` | 0 | 0 |
| `docs:check-links` | 0 | 0 |
| `check:shell-escape-residue` | 0 | 0 |
| `check:governed-queue-guard` (self-test) | 0 | 0 |
| `check:required-check-set` (self-test) | 0 | 0 |
| `check-changeset-presence.mjs` | — | 0 |

Both sides agree, so each instrument is shown to be non-empty and to
have actually read the file:

- `check-control-bytes: OK (scanned 7644 tracked text file(s); skipped
85 binary)`
- `check-shell-escape-residue: OK (5/5 root(s) resolved -- AGENTS.md: 1
file(s), 15 fence(s); …)`
- `Links are valid across 17 scan roots.`
- `VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement
report-only -> exit 0`
- `check-governed-queue-guard self-test: 185 cases pass (… plus the
SECOND queue predicate objectui#9018 added on the merge_group leg — the
contract-review carrier …)` — the guard's own self-test corroborates the
premise on this base.

Changeset: none owed. `check-changeset-presence.mjs` → `✅ No source or
published contract of a
released package changed in this range, so no changeset is owed.` ⚠️ The
`skip-changeset` label was
deliberately **not** applied: in this repository that label object
exists but no workflow or script
reads it, and a pin test holds that in place.

I also self-scanned the file for control bytes outside the gate
(`grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'` → no match, with a
positive control that HIT in the
same run on a fixture containing `0x0c`).

## 维护者速读(草稿)

**改了什么** —— `AGENTS.md` 受管面那段里,关于 `merge_group` 拒绝腿的描述补了一句:那条腿现在有**两条**
相互独立的判据,原文只写了一条(获授权的 APPROVED review),漏掉了 objectstack-ai#9018 加的 contract-review
carrier
(读 PR 上的 `needs:contract-review` label,exit 6 / 7)。一行 diff,只加不删。

**为什么改** —— 漏写的方向是**放宽**:照原文读,一个 diff 完全没碰受管面的 merge group 不可能被这道
check 拒绝;实际上可以。每一次 dispatch 都读这段。

**风险与代价(含回滚)** —— 风险极低:纯文字,不动脚本、不动 workflow、不动任何判定逻辑,六道门禁
PRE/POST 全绿。回滚 = revert 这一个 commit,恢复一行。措辞是从
`content/docs/guide/ci-cd-pipeline.md`
里已经被接受的说法搬过来的,不是新造的。

**席位意见** ——

**你要做的** —— ① 读上面「Alternative phrasings」五条,措辞归你定,改一行很便宜;② 这是受管面 PR,
需要你一条 `APPROVED` 并由你合并 —— 席位不会 ready、不会入队、不会自合、不会批准。

---
🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr

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

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

Projects

None yet

3 participants