Skip to content

Commit 8fc6a5f

Browse files
os-steveclaude
andauthored
docs(agents): a rule's provenance cites the ADR or ruling record, then the commit sha — and runtime strings carry no tracker number (#19453)
Fixes #19294 Clause-②: no AGENTS.md's register paragraph told every agent that a rule's provenance lives in the PR that landed it. Merged-PR numbers decay out of GitHub — the spec seat measured 11.7 %–15.1 % of one week's already deleted, with no 301 and an empty commit-to-PR association — so that convention pointed every reader at objects this repository does not control and has measured itself destroying. The maintainer ruled the replacement (decision batch #195 item 3 letter C+D, verbatim and untranslated: 「同意」; the director recorded it on the card this PR lands on). The sentence is REPLACED, not appended to: no second convention survives beside it. `grep -n -iE 'provenance|PR that landed|landed it' AGENTS.md` on 57ceb9d returns two hits — the sentence at :14 and, at :253, the unrelated instruction that a repo-local ADR mirroring a cloud decision carries a `## Provenance` section. The convention is stated once, so one sentence is replaced and nothing else in the file restates it. ## Before / after — AGENTS.md :14, against 57ceb9d Before: ```text (`pnpm check:pm-skill-id-lint`) — a rule's provenance lives in the PR that landed it. Where a hook or CI gate enforces a rule mechanically, the rule is stated once here and the script's own header is the authority on detail. ``` After: ```text (`pnpm check:pm-skill-id-lint`) — a rule's provenance cites the ADR or ruling record that decided it, otherwise the commit sha in this repository's history; a PR number is a convenience link, ⛔ never the citation. Runtime strings — refusal prose, prescriptions, anything an author is shown — carry no tracker number (`pnpm check:doc-authoring`): the lesson goes into the text. Where a hook or CI gate enforces a rule mechanically, the rule is stated once here and the script's own header is the authority on detail. ``` The ruled clauses land in the ruling's own order: the ADR or ruling record first (stable, in-repo, it carries the narrative); otherwise the commit sha in this repository's history (immutable, and `git` reads it with no network); a PR number demoted to a convenience link and ⛔ never the citation. Letter D is the sentence after it — runtime strings carry no tracker number, under the maintainer's standing words 「处理 issue 时犯的错应该总结成经验,保留 issue id没有意义」: the lesson is written into the text instead of a number the reader must dereference. The neighbouring clause about mechanical enforcement is kept intact, and the new text obeys itself — it carries no bare tracker number, and `pnpm check:pm-skill-id-lint`, which scans AGENTS.md against the pattern it names, is green on it. Stated precisely rather than implied: the gate cited for letter D reaches `packages/` minus `packages/spec` today, on a shrink-only baseline of 821 pinned sites across 231 files. The prose states the repo-wide rule; extending the gate's reach is the separate card already named on the issue body, not this one. ## The AGENTS.md line ratchet — paid at net 0, the ceiling untouched The ruled text is +3 physical lines and AGENTS.md sat at headroom 0 (1099 / 1099), so the first head (9f35c66) measured `pnpm check:pm-skill-ratchet :: exit 1`. The seat widened this card's file surface so the three lines are paid in RETIRED CONTENT — each retired fragment is a verbatim restatement of a rule whose home is another line, or a second pointer to a file already pointed at from a surviving line — ⛔ never by raising the ceiling (the CEILINGS row in `scripts/pm/check-skill-line-ratchet.mjs` is untouched at 1099). Head a799442: AGENTS.md 1099 → 1099, `pnpm check:pm-skill-ratchet :: exit 0`. | retired (pre-edit line) | what it was | the rule still lives at | |:--|:--|:--| | :58–59 「; the script headers are the authority on detail」 | restatement | :19 — the register paragraph's own clause; the two gates it qualified stay named on the line | | :452–453 「The two measured mutation shapes and their triggers live in pm-dispatch `references/platform-readings.md`.」 | second pointer | :433–434, two paragraphs above in the same section | | :758–759 「(shape, sha256 vs that record, record pin == `.objectui-sha`)」 | the gate's detail list | :19 (the script's own header is the authority on detail); `scripts/check-sdui-manifest.mjs` stays named; the regenerate-on-pin-bump rule at :159–161 | | :760–761 「— "could not run" is a failure, not a skip (Route & surface ownership §3) —」 | restatement + second pointer | :851–855, Route & surface ownership rule 3 | All three lines are bought by deleted content, none by re-wrap: each untouched paragraph greedy-wraps to exactly the line count it already had. Candidates rejected and why (an only pointer; PR #19214's reserved region :931–:956; fragments that buy no line; a loosely wrapped paragraph whose lines would be re-wrap currency; gate-pinned governed-surface enumerations) are on the card's second `os-dev-report`. ## Verification Derived union on a799442 (re-run after the retirements and one merge of `origin/main`), `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths, reconciled with `--ran`: **15 derived, 15 run, 0 NOT-MEASURED, 0 UNRUN**, every exit captured before any pipe. Green (15): `check-closing-keyword-parity` (gate and `--self-test`), `check-comment-mask-corpus`, `check:agent-test-spelling`, `check:docs-audit-scope`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:pm-governed-merges`, `check:pm-governed-prose`, `check:pm-skill-id-lint`, `check:refd-timer-probe`, `check:required-contexts`, `check:watch-hint-literal`, `check:pm-skill-ratchet` (AGENTS.md 1099 lines, ceiling 1099, headroom 0). Run beyond the union because the new text names it: `pnpm check:doc-authoring :: exit 0` — 403 files clean, 44 published skill files clean, 15881 customer-facing strings across 1013 spec sources clean, sibling-package prose ids holding the baseline. No package is touched, so there is no dependency closure to build and no package test suite in scope; the repo-wide `pnpm lint` scan is CI's run, not this PR's. `skip-changeset`: AGENTS.md is a repo-root instruction file and ships in no package's `files[]`. ## Acceptance notes - Noted, not filed: the gate cited for letter D excludes `packages/spec` from its prose-id leg and runs on a shrink-only baseline, so the mechanical reach is narrower than the prose rule. Carrier: the reach card already named on the issue body — no new card. - Noted, not filed: the CEILINGS row for AGENTS.md now carries four stacked per-card narratives in a gate script whose own header prescribes moving narrative out of operational text. Carrier: the next ceiling raise on that row, PR #19214, already in flight. ## 维护者速读(草稿) **改了什么** — AGENTS.md 开头「规则登记册」那一段里的一句:规则的出处从「落地它的 PR」改成「先引 ADR / 裁决记录,没有就引本仓的 commit sha,PR 号只能当顺手链接」;并补上一句「运行时字符串(拒绝文案、处方、任何打给作者看的文字)不带任何 issue 号,把教训写进正文」。这三行的增量由退掉文件里四处重复陈述 / 重复指针付账(上表),文件净 0 行,行数棘轮上限没动。 **为什么改** — 旧写法把读者指向 GitHub 上的 PR 号,而实测一周内已合并 PR 号有 11.7%–15.1% 已经被删除(没有 301,commit 到 PR 的关联是空的)。也就是说,规则的出处指向了一个本仓库不拥有、而且已经被测到正在消失的对象。ADR / 裁决记录和 commit sha 都在仓库里,不会消失。这是您在裁决批次 #195 第 3 项 C+D 上批的「同意」。 **风险与代价(含回滚)** — 风险很低:改的是一句给 AI 和人看的约定,没有代码、没有发布面、没有 changeset。代价是退掉的四处重复文字,每一处的规则仍住在上表点名的行;若您认为哪一处不该退,恢复它是一行 revert,但要同时退别的一行才能过棘轮。回滚就是 revert 这一个 commit,没有任何下游依赖。 **席位意见** — (留空,席位复审时定稿) **你要做的** — 一件事:确认正文措辞后点合并(Tier H,这个 PR 一直是 draft,席位已做 ACCEPT;棘轮已绿,不需要您裁行预算)。 --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0f9245c commit 8fc6a5f

1 file changed

Lines changed: 25 additions & 25 deletions

File tree

‎AGENTS.md‎

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ in this repo (including `.claude/skills/**`) conflicts with this one, **AGENTS.m
1111
This file carries principles, binding rules and lookup tables — rules only. A rule states
1212
what to do and what never to do, in one executable sentence; it carries no incident
1313
narrative, no ruling date or quotation, and no issue-number citation
14-
(`pnpm check:pm-skill-id-lint`) — a rule's provenance lives in the PR that landed it. Where
15-
a hook or CI gate enforces a rule mechanically, the rule is stated once here and the
16-
script's own header is the authority on detail.
14+
(`pnpm check:pm-skill-id-lint`) — a rule's provenance cites the ADR or ruling record that
15+
decided it, otherwise the commit sha in this repository's history; a PR number is a
16+
convenience link, ⛔ never the citation. Runtime strings — refusal prose, prescriptions,
17+
anything an author is shown — carry no tracker number (`pnpm check:doc-authoring`): the
18+
lesson goes into the text. Where a hook or CI gate enforces a rule mechanically, the rule is
19+
stated once here and the script's own header is the authority on detail.
1720

1821
---
1922

@@ -52,12 +55,11 @@ out-of-repo path.
5255
gate sweep, an ablation — because the working tree is otherwise the only copy of your work.
5356

5457
Type-check coverage and its debt counts are ratcheted in CI
55-
(`pnpm check:type-check-coverage`, `pnpm check:type-check-debt`; the script headers are
56-
the authority on detail): every package declares a `typecheck` script or carries a
57-
measured, shrink-only DEBT/EXEMPT ledger entry; new packages arrive covered; a package
58-
that graduates deletes its entry in the same PR; when a re-measure forces a count up,
59-
rewrite the entry's `note` too — a note naming only the old errors reads as "nearly
60-
graduated" to the next author.
58+
(`pnpm check:type-check-coverage`, `pnpm check:type-check-debt`): every package
59+
declares a `typecheck` script or carries a measured, shrink-only DEBT/EXEMPT ledger
60+
entry; new packages arrive covered; a package that graduates deletes its entry in the
61+
same PR; when a re-measure forces a count up, rewrite the entry's `note` too — a note
62+
naming only the old errors reads as "nearly graduated" to the next author.
6163

6264
Three principles the ratchet's invariants encode:
6365

@@ -446,10 +448,9 @@ a deviation; landed history is not rewritten) and a verbatim maintainer ruling p
446448
**GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally.**
447449
Regex literals and script-tag-shaped tokens go in fenced code with the dangerous character
448450
spelled out, or are described in words (fences do NOT protect them); after writing any
449-
less-than fragment, read the body back and verify it survived. The two measured mutation
450-
shapes and their triggers live in pm-dispatch `references/platform-readings.md`. ⛔ A body
451-
reading short only through the API is probably intact — check the rendered page before
452-
"repairing" it; a rewrite destroys a correct card.
451+
less-than fragment, read the body back and verify it survived. ⛔ A body reading short
452+
only through the API is probably intact — check the rendered page before "repairing" it;
453+
a rewrite destroys a correct card.
453454

454455
Even inside your own worktree, operate defensively:
455456

@@ -745,18 +746,17 @@ Principles the wrapper encodes (its own output is the authority on detail):
745746
a name, with accepted cases in the shrink-only, hand-edited
746747
`dual-source-exports.baseline.json`.
747748

748-
**`check:react-declaration-parity` compares two DECLARATIONS, not a declaration against
749-
an implementation** — the props the spec zod schema declares vs the inputs the objectui
750-
registry config declares. A prop both sides declare and no renderer reads is, to this
751-
gate, perfect agreement. Its `spec-only` / `registry-only` / `missing` signals are real;
752-
just don't read it as proof anything renders. Its right-hand side is the **tracked
753-
repo-root `sdui.manifest.json`**, written by `node scripts/gen-sdui-manifest-node.mjs`
754-
beside `scripts/sdui-manifest.record.json` and held honest in the required lint job by
755-
`scripts/check-sdui-manifest.mjs` (shape, sha256 vs that record, record pin ==
756-
`.objectui-sha`) — so `lint.yml` runs this gate `--strict` against it on every PR. It
757-
still **exits 1** with no usable manifest — "could not run" is a failure, not a skip
758-
(Route & surface ownership §3) — and `check:generated` files it `EXTERNAL_INPUT_REQUIRED`
759-
because that aggregate hands it none. ⛔ Do not "fix" a red by re-adding a skip.
749+
**`check:react-declaration-parity` compares two DECLARATIONS, not a declaration against an
750+
implementation** — the props the spec zod schema declares vs the inputs the objectui
751+
registry config declares. A prop both sides declare and no renderer reads is, to this gate,
752+
perfect agreement. Its `spec-only` / `registry-only` / `missing` signals are real; just
753+
don't read it as proof anything renders. Its right-hand side is the **tracked repo-root
754+
`sdui.manifest.json`**, written by `node scripts/gen-sdui-manifest-node.mjs` beside
755+
`scripts/sdui-manifest.record.json` and held honest in the required lint job by
756+
`scripts/check-sdui-manifest.mjs` — so `lint.yml` runs this gate `--strict` against it on
757+
every PR. It still **exits 1** with no usable manifest and `check:generated` files it
758+
`EXTERNAL_INPUT_REQUIRED` because that aggregate hands it none. ⛔ Do not "fix" a red by
759+
re-adding a skip.
760760

761761
Two generators have **no** gate at all — `gen:openapi` and `gen:sbom`. Nothing verifies
762762
their output is current; the wrapper reports that each run rather than staying silent.

0 commit comments

Comments
 (0)