Repository navigation
Commit f7e5231
docs(agents): a claim pre-check hit is a hint, not a claim (#18827)
Fixes #18811
Clause-②: no
## The defect
`AGENTS.md` rule 2 hands the dev `git ls-remote --heads origin | grep
issue-N` as a one-command claim pre-check and states only what the
command IS — never what a HIT MEANS. The reading rule was not missing
from the repo; it was in a layer this reader is never sent to. It stands
today in the fact layer,
`.claude/skills/pm-dispatch/references/platform-readings.md` :378, while
the dev agent definition `.claude/agents/os-dev.md` points at
`AGENTS.md` eight times and carries the strings `ls-remote` and `Claim:`
zero times. So the layer holding the rule has no reader, and the layer
with the reader has no rule. The failure direction is the silent one: a
stale head reads as "already claimed", a live card is skipped, and
nothing goes red — and most heads are stale, because a dev container can
create a remote branch but cannot delete one.
## Re-derived readings
Taken in this worktree, not carried from the card or the triage.
### Head census — re-taken
`git ls-remote --heads origin 'refs/heads/claude/issue-*' | wc -l` at
**2026-09-17T22:52Z**, exit 0:
| reading | value |
|:---|:---|
| `claude/issue-*` heads on `origin` | **290** — and that INCLUDES this
PR's own branch, so **289** pre-existing |
| seat census 2026-09-17T21:45Z | 291 |
| the #18774 dev's re-take 2026-09-17T21:48Z | 291 |
⭐ The population moved DOWN by two between 21:45Z and 22:52Z (291
pre-existing, then 289 pre-existing plus this branch). Both vanished
heads were headless ones. The census is a moving reading, which is
itself the argument for a clause that states a direction rather than a
number.
### The split — re-taken on the same window the seat used
Newest 1,200 PRs, `state=all`, back to 2026-09-05T14:45Z; read at
**2026-09-17T22:54Z**:
| | re-derived (290 heads) | seat's reading (291 heads) |
|:---|---:|---:|
| head with an OPEN PR | 26 | 26 |
| head with a closed / merged PR, branch never deleted | 8 | 8 |
| head with NO PR | **256** | 257 |
The two readings are the same population less the two deleted heads,
plus this PR's own (PR-less at census time). **Roughly 88% of hits are
stale in both.**
### The two pointer readings on `.claude/agents/os-dev.md`
On `a7bafc29af`:
| command | result | exit |
|:---|:---|---:|
| `git grep -c 'AGENTS\.md' -- .claude/agents/os-dev.md` |
`.claude/agents/os-dev.md:8` | 0 |
| `git grep -n 'ls-remote\|Claim:' -- .claude/agents/os-dev.md` | no
output | 1 |
| **lit control** `git grep -c 'worktree' -- .claude/agents/os-dev.md` |
`.claude/agents/os-dev.md:9` | 0 |
| `git grep -n 'platform-readings' -- .claude/agents/os-dev.md` | one
hit, `:54`, and only for the single-card read spelling | 0 |
The lit control is what makes the empty reading a real absence rather
than a mis-typed pattern: the same grep over the same file finds 9 hits
for a word that IS there. And `.claude/agents/os-dev.md` :19 is the
pointer itself, verbatim and untranslated:
> 仓库根的 AGENTS.md 有约束力,第一次编辑前先读它。
## The clause
One sentence, appended to the existing sentence in the same bullet — not
a new paragraph, and no second read added to the one-command pre-check.
Verbatim:
```
A hit is a hint, not a claim — most heads carry no PR: ⛔ never skip a card on one, the `Claim:` comment decides.
```
**112 characters / 116 bytes.** It lands on rule 2 at what is now
`AGENTS.md` :463–:464, and costs **one line**.
It does two things the pre-check could not do by itself: it names the
wrong action (skipping a card on a hit) rather than only describing the
instrument, and it names the record that DOES decide — the `Claim:`
comment, which `AGENTS.md` :393–:395 already defines ("the identity
record is the `Claim:` comment — first line beginning `Claim:`"). The
clause therefore adds a reading, not a mechanism.
### Two declared deviations from the dispatch
1. **The ratio is stated qualitatively, not dated.** The dispatch asked
for the measured ratio, dated. This file's own preamble governs its
authoring: *"A rule states what to do and what never to do, in one
executable sentence; it carries no incident narrative, no ruling date or
quotation, and no issue-number citation"*. A dated census in the rules
layer is exactly the incident narrative that preamble excludes, and
`pnpm check:pm-skill-id-lint` scans this file for the issue-number half
of it. So the clause says "most heads carry no PR" and the dated census
lives here, in the PR body, and in the fact layer. This also keeps the
clause from rotting — the census moved twice today.
2. **No third pointer to the fact layer.** `AGENTS.md` already points at
pm-dispatch `references/platform-readings.md` twice, at :431 and :450,
both times for exactly "the readings". A third pointer measured 2 added
lines instead of 1 (and wrapped the code span across a line break), i.e.
it would have cost a second retired line to restate a pointer the file
already carries. The defect the card names is that the RULE was not in
the reader's layer; the rule is now there.
## The payment
`AGENTS.md` was at **1099 / 1099** — no headroom. The clause adds one
line, so one line retires. **No re-wrap is used as currency**: the line
is bought by deleting ~109 characters of content, and the surviving
sentence is shorter than either line it replaces.
Retired — `AGENTS.md` :799–:800, two lines:
```
⛔ **Both roots are governed surfaces** — human-merge only, or queued under **Prime Directive #14**'s pinned-approval
path; no per-PR check holds it: the queue guard refuses an unpinned governed diff at queue time.
```
Now — one line:
```
⛔ **Both roots are governed surfaces** — human-merge only, or **Prime Directive #14**'s pinned-approval path.
```
Where the retired content survives, **in this same file**:
| retired fragment | survives at |
|:---|:---|
| "the queue guard refuses an unpinned governed diff at queue time" |
Prime Directive #14, :284 — *"Behind it: the queue guard refuses an
unpinned governed diff"* |
| "queued under ... pinned-approval path" as a mechanism | Prime
Directive #14, :268–:274, which defines the approval, who may give it,
and that the owning seat then lands |
| "Both roots are governed" | Prime Directive #14, :257–:258, which
enumerates `.claude/**` and `skills/**` in the governed-surface list |
The surviving sentence keeps the pointer (a reader in the Skills section
still learns both roots are governed and where the rule is); what
retires is the restatement of the mechanism.
⛔ The ratchet's widest-row pin is untouched — no table row is edited.
`AGENTS.md`: widest table row **768 bytes (pin 768)** before and after.
| ratchet | before | after |
|:---|---:|---:|
| `AGENTS.md` lines | 1099 (ceiling 1099, headroom 0) | **1099**
(ceiling 1099, headroom 0) |
| `AGENTS.md` widest table row | 768 bytes (pin 768) | **768 bytes (pin
768)** |
| `node scripts/pm/check-skill-line-ratchet.mjs` | exit 0 | exit 0 |
`git diff --stat`: `1 file changed, 3 insertions(+), 3 deletions(-)` —
net zero lines.
## The victim search the triage left
Report-only. **Zero state writes** — no card touched, no label, no
branch deleted.
**Method.** All 290 `claude/issue-*` heads mapped to card numbers (281
distinct, 0 unparseable); the 256 with no PR in the 1,200-PR window
re-checked per branch against the **unbounded**
`pulls?state=all&head=...` endpoint (so the window is not a source of
false "headless"); their card numbers intersected with the 518 open
non-PR issues; each survivor's full comment list tested against the
machine predicate `CLAIM_COMMENT_MARKER` = the regex at
`scripts/pm/check-half-states.mjs` :1138, i.e. `Claim:` or `Claimed:` at
line start, case-insensitive, blockquote allowed.
**Population**: 27 open cards carry a confirmed same-number headless
head. **Result: the list is NOT empty — 9 rows.** Read at
**2026-09-17T22:55Z–22:56Z**. 1 parent a09d797 commit f7e5231
1 file changed
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
460 | 460 | | |
461 | 461 | | |
462 | 462 | | |
463 | | - | |
| 463 | + | |
| 464 | + | |
464 | 465 | | |
465 | 466 | | |
466 | 467 | | |
| |||
796 | 797 | | |
797 | 798 | | |
798 | 799 | | |
799 | | - | |
800 | | - | |
| 800 | + | |
801 | 801 | | |
802 | 802 | | |
803 | 803 | | |
| |||
0 commit comments