docs(agents): before editing a workflow file, derive its test readers with git grep and run them (objectui#9198) - #9489
Conversation
… with git grep and run them The workflows discipline in AGENTS.md tells a round how to find out whether a workflow runs here. It said nothing about which tests read one, so that question was answered from memory, and memory indexes on names: a round that edited the lint job listed six pins by name similarity to the workflow and missed the pin that went red, because that pin is not named after any workflow. Adds one habit line beside the `git cat-file -e` probes: derive the readers with a `git grep` over test paths and run every hit locally; a workflow edit that reddens an un-listed pin is a finding against the habit, not against the round. The line states its own limit — the text search is wrong in both directions and the readers it cannot see are recorded on objectui#9198 rather than covered here. No collector and no gate: the one incident is inside the search's own hits, and the director seat's ruling on that card declines to build an instrument for the readers it misses. Empty-frontmatter changeset: AGENTS.md is not published package source, so this declares no release rather than bumping the 39-package fixed group. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
Contract reviewServed-tier: 9/9 In-seat record on a GOVERNED surface (objectui ① Derived judgments
② Semver levelNone. ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
维护者速读这个 PR 往 objectui dev 把这条习惯用在了它自己身上:改 为什么要你点: 要不要批准这条习惯行? 是 / 否。 Generated by Claude Code |
|
Landing under ruling C — Generated by Claude Code |
Fixes #9198
One line added to the workflows discipline in
AGENTS.md. No collector, no gate, no script.Governed surface — this PR is DRAFT and draft is its finished state
node scripts/check-governed-queue-guard.mjs --test AGENTS.md(exit 3):It is not flipped ready, not enqueued, no auto-merge is armed, and no review is submitted from this side.
The specification — the director seat's class-one ruling, quoted
From comment 5651818810 on #9198, 2026-09-13. One substitution, made deliberately and flagged here
rather than silently: the ruling's placeholder is written with angle brackets, and this repository's
own rule on GitHub body rewrites (
AGENTS.md, the section on GitHub rewriting body bytes, mitigationone) says placeholders must be spelled as words because tag-shaped fragments are eaten on save —
backticks and fenced blocks do not protect them. The placeholder below is therefore spelled
NAME.yml;nothing else is changed.
Its authority line is 「零拉动 ⇒ 荐不扩散」: ⛔ no collector, ⛔ no gate, ⛔ no script — the habit line only.
Premise readings
All three taken in the worktree at
origin/main541ce4e0on 2026-09-14, between 10:09Z and 10:12Z.P1 — where the workflows discipline lives, anchored by content, and the control that no such line
already exists. The section heading 「本仓到底跑不跑 X?」 is at :387; the two
git cat-file -eprobesare at :390 and :391; the enumeration-versus-read paragraph and its
for f in .github/workflows/*.ymlloop follow at :397 and :403. Control:
git grep -n "__tests__" origin/main -- AGENTS.mdreturnsexactly two hits, at :221 and :457 — neither inside :383–:410, so nothing in that section named a test
reader before this change. Positive control on the same grep, so that a zero could have failed:
git grep -n "cat-file" origin/main -- AGENTS.mdhits :390 and :391, inside the region. P1 holds.P2 — the dev-round guidance this repository's rounds read is
AGENTS.md.ls .claude/agents/onthe tip:
No such file or directory, exit 2. Enumerated from the same ref as the read rather than froma working-tree glob, per this file's own enumeration rule:
git ls-tree -r --name-only origin/main .claude/returns 14 entries — four hook scripts and their four self-tests,launch.json,settings.json, and two internal skills — and noagents/path.os-dev.mddoes not exist anywherein the tree. P2 holds; the ruling's landing point resolves here.
P3 — the ruling's own control, re-run on the tip.
git grep -l 'lint.yml' -- '**/__tests__/**' '**/*.test.*'returns 21 files, matching the card's reading at its own ref, andscripts/__tests__/ci-cd-pipeline-doc.test.ts— the pin that actually went red on the round the cardwas found in — is among them. Same command against the
origin/mainref returns the same 21. That isthe whole basis for a habit rather than an instrument: the one measured incident is inside the search's
hits. The card's runtime collector was ⛔ not re-run; that instrument is exactly what the ruling declines
to build.
The line
Added at :397–:398 of
AGENTS.md(net +3 including the blank separator; nothing moved or reflowed),between the positive-control paragraph and the enumeration-versus-read subsection — where a reader is
standing when they are about to touch a workflow file:
The placeholder is spelled
X.yml, which is how :390 directly above already spells it, so the readercopies one convention rather than two. No count is written into the prose: the blind spot points at
#9198 instead of restating its numbers, which is Coding Standard #9 applied to the line itself.
Changeset
.changeset/issue-9198-workflow-test-readers-habit.md, empty frontmatter — the declared-once form fora change that publishes nothing.
node scripts/check-changeset-presence.mjsagrees it is not owed(
0 of them published source of a package the release covers); it is written anyway in the shape of.changeset/issue-8875-cite-by-content-convention.md, the siblingAGENTS.mdchange.majoris notdeclared, so the 39-package fixed group is not moved.
Gates
The gate list was derived, not recalled — objectui has no dispatch-gates script. Sources: the root
package.jsonscripts; the workflow files that nameAGENTS.md, enumerated git-side asgit grep -l 'AGENTS.md' -- '.github/workflows/*.yml'(11: changeset-guard, changeset-presence,changeset-release, ci, control-bytes, dependabot-auto-merge, docs-links, governed-surface-guard,
hook-selftests, lint, shell-escape-residue); and the tests that read
AGENTS.md, derived by the veryhabit this PR adds — this is the habit applied to itself.
git grep -l 'AGENTS.md' -- '**/__tests__/**' '**/*.test.*'returns 371 files, and every one ofthem was run: 20 under
scripts/__tests__/and the remaining 351 in a second invocation through theshared verify lock. All exit codes captured before any pipe.
node scripts/check-governed-queue-guard.mjs --test AGENTS.mdpnpm check:governed-queue-guardOK check-governed-queue-guard self-test: 185 cases passpnpm exec vitest runover the 20scripts/__tests__hitsTest Files 20 passed (20)·Tests 775 passed (775)· 25.83spnpm exec vitest runover the other 351 hits, under the verify lockTest Files 351 passed (351)·Tests 6296 passed, 1 skipped (6297)·VERDICT command-exit 0 · held the lock 442spnpm check:control-bytes✅ check-control-bytes: OK (scanned 7658 tracked text file(s); skipped 85 binary)pnpm lint --concurrency=2, under the verify lockTasks: 47 successful, 47 total·VERDICT command-exit 0 · held the lock 182s; the 830 warnings are pre-existingno-explicit-anyand 0 errorspnpm type-check --concurrency=2, under the verify lockTasks: 81 successful, 81 total·VERDICT command-exit 0 · held the lock 435snode scripts/check-changeset-presence.mjs✅ No source or published contract of a released package changed in this rangenode scripts/check-changeset-no-major.mjs✅ No changeset declares a major bump.pnpm check:changeset-claims1 file(s) changed outside .changeset/read against 1070 pending bodies, no finding raised against this diffpnpm check:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s)pnpm check:shell-escape-residue✅ OK (5/5 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ...)node scripts/check-doc-links.mjsLinks are valid across 17 scan roots.Beyond the gate, the control-character scan was also run by hand over both changed files —
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'returns exit 1 on each.Acceptance notes
AGENTS.md;git diff --statreports3 insertions and 0 deletions in that file. The two sibling region claims on the same file — finding: AGENTS.md forbids
new URL(<相对路径>, import.meta.url)as fatal, and the tree carries 21 live instances of it inside the transform that sentence names — plus four comments asserting the hazard #9191 at:232–:239 and PR docs(agents): record the merge_group leg's SECOND refusal predicate (the contract-review carrier) #9466 at :519 — are untouched. If this lands second,
origin/maingets merged infirst.
so. For
lint.ymlthe command returns 21 files. ForAGENTS.mdit returns 371, of which 342mention the filename only on comment lines (
// AGENTS.md §测试纪律and the like) and 9 more carry itinside a test name or an assertion message; 63 of the 351 non-
scriptshits reference anynode:fsread surface at all. That is the text-search false-positive direction the card measured, at a
different magnitude, and it is why the line is scoped to
.github/workflowsfiles, whose names aredistinctive, rather than to any path. Noted, not filed — this is an observation about the line's
reach, not a defect in anything.
this repo matches only
**/*.{ts,tsx}and**/*.tsxand registers no Markdown processor, and.mdis not a tsc input — so
lintandtype-checkwere run in full anyway rather than relied on forcoverage of this diff.
text search misses stay recorded on finding(test-infra): "which tests read this workflow file" is recalled by name, not derived — measured: 35 readers, name-recall found 6 #9198 as the evidence a future card would need; they are ⛔ not
addressed here.
Clause-②: no
Generated by Claude Code