Skip to content

Four surfaces state the gate set as three commands; CI now enforces four — one PR must move all four, and three of them are governed - #77

Open
zhuangjianguo wants to merge 1 commit into
mainfrom
claude/issue-73-four-gates-everywhere
Open

Four surfaces state the gate set as three commands; CI now enforces four — one PR must move all four, and three of them are governed#77
zhuangjianguo wants to merge 1 commit into
mainfrom
claude/issue-73-four-gates-everywhere

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes #73

⚠️ This PR touches a governed surface (AGENTS.md, CLAUDE.md) and is left OPEN for the maintainer to merge. Per AGENTS.md → Delivery process → Governed surface, the seat reviews it, records an ACCEPT on the issue, and stops there. Nothing here is urgent and nothing here is risky; see 维护者速读 at the bottom.

What changed

PR #72 (#67) added pnpm lint:i18n-gate to .github/workflows/ci.yml, and package.json's verify has composed all four for some time. The documents were the last thing in the repository still saying three. They now all say the same four, in the same order — validatelinttypechecklint:i18n-gate.

surface shape change
README.md 46–51 fenced block, trailing comment per line fourth line added, with a comment in the block's own register; the block re-aligned by three columns because pnpm lint:i18n-gate is wider than the old comment column
CLAUDE.md 8–10 terse ⛔ rule mirroring a Prime Directive fourth command added to the composed spelling, re-wrapped; still two sentences, no expansion
AGENTS.md 29–37 ## Verify your work — block + prose rewritten, not appended to — see below
AGENTS.md 130 Delivery process table cell fourth command added, cell shape unchanged
docs/backlog/README.md 29–30 acceptance floor every card inherits a fifth surface the card did not list — see The grep below

AGENTS.md "Verify your work" is a rewrite

The count was welded into the prose twice — 「All three exit non-zero」 and 「Paste the three green tails」. Appending a fourth command without touching those would have left the section contradicting itself inside three lines, which is the exact defect class this card fixes.

The replacement is deliberately count-free:

`validate` runs the same gates as `pnpm build` without emitting `dist/`. Each exits non-zero with a
located, corrective message. **Never report a change as done, and never open a PR, until all of them
pass.** Paste one green tail per gate into the PR body.

"Each" and "all of them" bind to the block above them rather than to a number, so a fifth gate cannot reopen this defect there. The block itself still enumerates — deliberately; see the judgement call.

The grep — run here, reported in full

The card's four rows came from a grep, so I ran my own rather than trusting the list. Four spellings, whole tree, tracked files:

git grep -n 'pnpm validate'
git grep -n 'typecheck'
git grep -n 'pnpm lint'
git grep -ni 'all three|three green|三个|三条|three gates|three commands'

It returned five documentary statements of the gate set, not four. The fifth is docs/backlog/README.md 29 — 「Every card inherits the same acceptance floor: pnpm validate && pnpm lint && pnpm typecheck green」 — the floor every dispatched card inherits and the PM loop reads. I moved it with the other four. Leaving it at three would have produced precisely the trade the card forbids: a uniform understatement swapped for a genuine contradiction, with the backlog telling a dev three while AGENTS.md told it four. It is ungoverned, off every exclusion list in the card, mechanically identical to the other four, and disjoint from #71's file surface.

One further occurrence, deliberately not touched: DESIGN.md 354, the M1 milestone acceptance cell — 「validate/lint/typecheck 绿」. DESIGN.md is excluded by this card and governed by AGENTS.md 128/131/132, so it needs a needs-user-decision card rather than a rider. It also reads differently from the other five: it records what a delivered milestone was accepted against, not what a contributor should run today. Flagged for the seat; not filed, because filing the governed-surface decision is the PM seat's act, not mine.

Nothing else. Every other hit is an incidental mention of a single command — pnpm validate reports 9 objects (docs/backlog/02, 03), the lint:i18n-gate design notes in src/** and scripts/, package.json, ci.yml — none of them states the gate set, and none was touched.

The judgement call: pnpm verify vs enumeration — recommended, not taken

The card asked me to state a reading and not act on it. My reading: AGENTS.md 130 and docs/backlog/README.md 29 should eventually say pnpm verify and nothing else; README.md and AGENTS.md 29–33 should keep enumerating.

The two that should collapse are the two that name the set only to say "this is the bar". They carry no per-command information, they are pure restatements of package.json's verify, and restatement is the mechanism that drifted — five copies, one edit to ci.yml, five wrong. pnpm verify cannot drift: it is the definition.

The two that should not collapse are the two whose job is to show a reader what runs. README.md's block exists so a newcomer sees the four things and what each catches; AGENTS.md's block does the same for an agent, with a per-gate comment explaining why lint is not a second spelling of validate. Replacing those with one composed word costs a reader the whole point of the block and saves a drift risk that the count-free prose rewrite has already largely defused.

I did not act on any of this. The enumerations are all still here, all four commands, right order. If the maintainer wants the collapse, it is a two-line follow-up card.

Gate output — all four green, exit codes captured before any pipe

Run in a dedicated worktree off 19a8a4c, on 4560611. Each gate written to its own log and $? read directly, never through a pipe:

GATE validate       EXIT=0
GATE lint           EXIT=0
GATE typecheck      EXIT=0
GATE lint:i18n-gate EXIT=0

One green tail per gate, as the rewritten AGENTS.md now asks:

validate        ✓ Validation passed (1031ms)
                  Data: 11 Objects  170 Fields

lint            21 warning(s), 5 suggestion(s) (913ms)
                platform built-ins: 773 i18n issue(s) hidden — rerun with --include-platform

typecheck       > hotclm@0.1.0 typecheck
                > tsc --noEmit          (no output, exit 0)

lint:i18n-gate  ✓ i18n gate
                  LOCALES  : "en", "zh-CN" checked (required: en, zh-CN)
                  COVERAGE : 0 missing keys across 2 locale(s)

validate and lint warnings are pre-existing on main and untouched by this diff, which is markdown only.

Demonstration: no gate reads these files

Asserting it is not evidence, so here is the measurement. All four documents were reduced to two lines of garbage at once, all four gates were run against the corrupted tree, and the tree was restored under trap … EXIT INT TERM with absolute paths from git rev-parse --show-toplevel, then verified by state — never by an exit code.

### 1. HEAD blob hashes (the restore target)
  README.md               HEAD:f90ea10d97610538accb04d291d340fbf1808b2a  bytes=12136
  CLAUDE.md               HEAD:0e601150acc5819a4d286f02b919b117936d8327  bytes=985
  AGENTS.md               HEAD:85fa26fa1c088b81d70b15e448f0c7553fd962ac  bytes=11816
  docs/backlog/README.md  HEAD:b8a73b698086119622f36808cc06d3170ce5651c  bytes=2747

### 2. mutate to two lines of garbage — proved on disk, not by an editor exit code
  README.md               marker 0->1  bytes 12136->59  lines=2
  CLAUDE.md               marker 0->1  bytes 985->59    lines=2
  AGENTS.md               marker 0->1  bytes 11816->59  lines=2
  docs/backlog/README.md  marker 0->1  bytes 2747->59   lines=2
  git diff --stat HEAD:  4 files changed, 8 insertions(+), 419 deletions(-)

### 3. all four gates against the corrupted tree — exit code captured before any pipe
  GATE validate EXIT=0
  GATE lint EXIT=0
  GATE typecheck EXIT=0
  GATE lint:i18n-gate EXIT=0
  ANY_GATE_NONZERO=0

### 4. restore, then verify BY STATE
  MATCH   README.md               f90ea10d97610538accb04d291d340fbf1808b2a
  MATCH   CLAUDE.md               0e601150acc5819a4d286f02b919b117936d8327
  MATCH   AGENTS.md               85fa26fa1c088b81d70b15e448f0c7553fd962ac
  MATCH   docs/backlog/README.md  b8a73b698086119622f36808cc06d3170ce5651c
  git diff HEAD --quiet EXIT=0
  git status --porcelain: []
  RESTORE VERIFIED BY STATE

Every gate stayed green with all four documents destroyed, so no gate reads any of them. A second, independent line of evidence agrees: tsconfig.json 14 is "include": ["objectstack.config.ts", "src/**/*"], and validate/lint walk the metadata graph from objectstack.config.ts. The ablation is the measurement; the tsconfig line is the explanation.

Edits verified on disk by spelling counts, never by an editor's exit code

Counted per file, before and after, on disk:

file old three-gate spelling lint:i18n-gate gate-count word "three"
README.md 0 → 0 (block form) 0 → 1 n/a (its one "three" is about lookup fields, line 141)
CLAUDE.md 1 → 0 0 → 1 0 → 0
AGENTS.md 1 → 0 0 → 2 3 → 0
docs/backlog/README.md 1 → 0 0 → 1 n/a (its one "three" is "three dashboards", line 23)

Repo-wide, the old composed spelling is gone entirely:

$ git grep -n 'pnpm validate && pnpm lint && pnpm typecheck`'
(no matches)

Scope

Documentation only: README.md, CLAUDE.md, AGENTS.md, docs/backlog/README.md. No .github/, no package.json, no src/, no DESIGN.md, no LICENSE, no CHANGELOG.md, no docs/design/**. Disjoint from #71, which is in flight on src/dashboards/ and src/datasets/. What the gates are and the order they run in are unchanged. No changeset (this repo has no changeset gate). No browser run owed — no surface a human touches was changed.

Acceptance notes

  • Every quoted line was re-read on 19a8a4c, the tree this branches from, not copied from the card's table (which was taken on 30fd863).
  • Noted, not filed: DESIGN.md 354's M1 milestone acceptance cell still spells three gates. Governed surface, excluded by this card, and arguably a historical record rather than an instruction — the seat's call whether it becomes a needs-user-decision card.
  • Noted, not filed: docs/backlog/14-release.md 14 already says pnpm verify green, which is the composed form this PR recommends for the two restatement surfaces. It is correct today and needs no change.

维护者速读(草稿)

由 dev 起草,席位定稿为 issue 上的 ACCEPT 评论。

改了什么:仓库里凡是「告诉贡献者要跑哪几条 gate」的地方,全部从三条改成四条,补上 pnpm lint:i18n-gate,顺序与 package.jsonverify.github/workflows/ci.yml 完全一致。共五处:README.mdCLAUDE.mdAGENTS.md 两处、docs/backlog/README.md。其中 AGENTS.md 的「Verify your work」一节是重写而非追加——原文两次把「三」写死在散文里,只加命令会让同一节在三行之内自相矛盾;新写法不再出现数字,下次再加第五条 gate 时那段散文不会再错。

为什么改:PR #72 让 CI 真的跑四条,verify 也早已是四条,文档成了仓库里最后还说三条的东西。照文档跑的贡献者不会出错,只会漏跑一条——是遗漏不是错误,所以这不是缺陷,是文档追上已经移动的执行面。

风险与代价:。纯 Markdown,没有任何 gate 读这四个文件——不是断言,是量出来的:把四个文件同时毁成两行乱码,四条 gate 依然全部 exit 0,然后在 trap 下按 git hash-object 逐个比对 HEAD blob 还原并验证(见上面的 Demonstration)。回滚就是 git revert 这一个 commit,无迁移、无数据、无依赖。

席位意见:(留给席位填写)

你要做的:看一眼 AGENTS.md 那段重写读起来是否还是你要的语气,然后合并。另有两件事等你定夺,都不阻塞本 PR:① AGENTS.md 表格与 backlog 的验收底线要不要干脆改成只写 pnpm verify(本 PR 只建议、没有动手,理由见上面的判断题一节);② DESIGN.md 354 的 M1 验收格里还写着三条,属受管面,需要一张 needs-user-decision 卡才能动。


🤖 Generated with Claude Code

https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR


Generated by Claude Code

…ated

PR #72 (#67) added `pnpm lint:i18n-gate` to `.github/workflows/ci.yml`, so CI
enforces four gates. `package.json`'s `verify` has composed four for some time.
The documents were the last thing in the repository saying three.

Five surfaces, not the four the card listed — a repository-wide grep for the
gate set also turned up `docs/backlog/README.md`, the acceptance floor every
work card inherits. All five now state the same list in the same order:
validate -> lint -> typecheck -> lint:i18n-gate.

`AGENTS.md` "Verify your work" is rewritten rather than appended to: the count
was welded into the prose twice ("all three exit non-zero", "the three green
tails"), so a bare fourth command would have left the section contradicting
itself within three lines. The replacement prose is deliberately count-free, so
a fifth gate cannot reopen this defect there.

The enumerations are kept; collapsing any of them to `pnpm verify` is a
judgement the PR body raises and does not take.

Documentation only. No gate reads any of these files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR

Copy link
Copy Markdown
Collaborator Author

维护者速读(席位定稿)

席位按自己对 diff 的读数校正后发布。ACCEPT 记录在 #73。⛔ 本 PR 属受管面,席位不合,留给你。

改了什么 —— 仓库里五处告诉贡献者「闸门是三道」的地方,一次改齐成四道,全部是 markdown,一行代码没动。四处是卡片点名的(README.md 的命令块、CLAUDE.md 的 ⛔ 规则、AGENTS.md 的「Verify your work」命令块、AGENTS.md 交付流程表的 Gates 行),第五处是 dev 自己 grep 出来的 —— docs/backlog/README.md,每张派发卡继承的验收底线。

为什么改 —— PR #72#67)已经把 pnpm lint:i18n-gate 加进了 CI,所以机器现在跑四道,文档还写着三道。而且这个分歧一直只在文档这一侧:package.jsonverify 脚本本来就串了全部四道,任何手跑 pnpm verify 的人一直在跑这道闸门。

漏掉的偏偏是最不该漏的那道。漏一个 zh-CN 翻译键属于「运行时静默失败」那一类:fallbackLocale: 'en' 会把缺口在屏幕上伪装成一句英文;而 pnpm lint 看得见也打印了这个缺口,却因为它是 WARNING 而不是 ERROR 照样 exit 0。所以屏幕上看不出、退出码也吃掉了 —— 评审员最后的防线只剩「在一墙既有告警里注意到数字从 21 变成 22」。

一处值得单独看的做法 —— AGENTS.md 的「Verify your work」不是把命令加上去就完事:那一段把数量焊进了散文里两次(「All three exit non-zero」「the three green tails」)。dev 没有把 three 改成 four,而是把那两句改成了不含数量的说法(「all of them」「one green tail per gate」)。将来加第六道闸门时,这一段不会再次过期。 一句不会漂移的话,比一句今天正确的话值钱。

风险与代价(含回滚) —— 极低。纯文档:四道闸门全部退出码 0;而且 dev 做了消融证明 —— 把这四个文档同时削成两行垃圾(git diff --stat 显示 419 行删除),四道闸门仍然全部 exit 0,也就是说没有任何闸门读这些文件,这个 diff 在结构上不可能影响构建。随后按状态还原(逐文件 git hash-object 对上 git rev-parse HEAD:<path>)。产品能力零变化。回滚git revert 一个 commit,无迁移、无数据、无依赖。

代价:贡献者从此被要求跑第四道闸门 —— 而这道闸门本来就在 pnpm verify 里,所以实际上只是文档追上了既有事实。

席位意见 —— 建议合。这是文档追赶一个已经生效的强制面,方向和 PR #40 一致(那次是设计文档追赶已发布的现实)。

你要做的 —— 确认「四道闸门」就是你要的贡献者门槛(CI 已经这么跑了),确认无误就合并。

两件已裁、不需要你处理的

  • DESIGN.md:354(M1 里程碑验收格)仍写三道 —— 故意不动。那是「M1 当年是按什么验收的」的历史记录,不是给今天贡献者的指令;改它会让它记载一件没发生过的事。
  • 是否把纯复述性的两处(AGENTS.md 的 Gates 行、docs/backlog/README.md 的验收底线)collapse 成 pnpm verify —— 已另开卡排在本 PR 之后,同样是受管面,同样留给你合。

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Four surfaces state the gate set as three commands; CI now enforces four — one PR must move all four, and three of them are governed

2 participants