You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Flip the ESLint ledger row's renameInFlight off (and re-check its budget) once the review-checklist rename half lands #9505
Follow-up housekeeping for the instruction-surface scan added by PR #9504 (card #9491). Not actionable until the review-checklist half of the #9325 rename has landed on main (its card is #9420; #9490 was open as its PR when this was filed).
Once .claude/skills/pm-dispatch/references/review-checklist.md on main names Lint & Repo Gates itself:
In scripts/check-required-contexts.mjs, flip the ESLint row's renameInFlight to false in RETIRED_CONTEXT_NAMES, so the retired literal stops satisfying the mustName naming requirement. The gate prints a completion notice ("flip ... renameInFlight to false") when this step is ready; flipping early is safe — the flip PR is red while any required-set surface still leans on the grace, so it cannot land out of order.
Re-check the staleSites budget of 1 for the checklist: if the landed fix kept its deliberate historical ESLint mention, the budget stays 1 (correct as-is); if the mention was dropped, the gate prints a trim notice and the budget entry should be deleted, making the row a standing ban on writing the dead name fresh.
Run pnpm check:required-contexts (self-test + pin) — the flip PR needs no other changes.
One-line dev-tier edit in scripts/; the design and the notices that drive it are documented at RETIRED_CONTEXT_NAMES in the script and in PR #9504's body. #9420 is not addressed here and remains open.
{
"issue": 9505,
"status": "done",
"branch": "claude/issue-9505-retire-rename-grace",
"pr": "https://github.com/objectstack-ai/objectstack/pull/9569",
"premise_still_valid": true,
"summary": "Re-measured the trigger at my branch point (base e7daea169): review-checklist.md has 0 'ESLint' and 1 'Lint & Repo Gates', so the card's second branch applies and BOTH steps landed — 'ESLint'.renameInFlight flipped to false AND its staleSites budget deleted outright (not set to 0; the ledger's own hygiene rule says a zero budget is a dropped key), making the row a standing ban on writing the dead name fresh. The row comment and the design-doc bullet that predicted a surviving historical mention were rewritten to record what actually happened. All three PM assumptions checked: (1) the gate DOES print both promised notices with the wording the card quotes — captured verbatim before the change; (2) the self-ordering safety claim holds, and the reason is now written next to it (the pin runs in lint.yml's 'lint' job — the 'Lint & Repo Gates' context — with no 'if:', which the file's own wiring block asserts), with the only residual being surfaces outside INSTRUCTION_SURFACES, which carry no mustName requirement and so cannot lean on the grace at all; (3) no coupling with the new 'ADR maintainer approval' row — replacedBy null excludes it from both the mustName grace and the flip-completion loop, it has no budgets, no substring collision, and zero occurrences across all five scanned surfaces (measured); rows are judged independently per surface. Two notes for the PM: the self-test baseline was 81 assertions on main, not the 85 in the dispatch prompt (now 83 after this PR); and the trim narrows what other in-flight PRs may write into the checklist — by design that shows up as a red on such a PR in the merge queue, never on main.",
"tests": "All at final commit 5c31e45bf, clean tree. `node scripts/check-required-contexts.mjs --self-test` => '✓ 83 assertions' (baseline on main was 81: 4 assertions removed by fixture triage, 6 added). `node scripts/check-required-contexts.mjs` => '✓ 8 required context name(s) pinned across 2 workflow(s); 5 instruction surface(s) scanned against 2 retired name(s)' and — the point of the card — ZERO notices, where before the change it printed both '...budget of 1 ... can be trimmed' and '...flip ESLint.renameInFlight to false...'. `node scripts/check-nul-bytes.mjs` => OK (6157 files). `pnpm exec eslint scripts/check-required-contexts.mjs --no-inline-config` => clean. Gate family derived from the actual changed path with `node scripts/pm/dispatch-gates.mjs scripts/check-required-contexts.mjs` => exactly one local family, `pnpm check:required-contexts`, which is the pair above; nothing new to add. Reverse verification, run from the COMMITTED state and restored by `git checkout <branch> -- <path>` (tree verified byte-clean after each): ablation A (renameInFlight false -> true) => exactly 2 failures, 'the shipped ledger's grace is closed...' and 'after the flip and the trim, the ESLint row is silent...', and the pin's flip notice returns; ablation B (staleSites budget restored) => exactly 2 failures, 'a retired name written fresh into a trimmed row's surface => red...' and the same silence pin, and the pin's trim notice returns. Each new green is therefore traceable to a named assertion, and each new assertion to a specific ablation. Both new red-direction pins also carry an in-file single-variable ablation (restore the budget => the same fresh mention is green; re-open only the grace => the naming red clears), so a future restore of either half cannot leave the pins passing vacuously.",
"open_questions": [],
"out_of_scope_findings": []
}
Activity
os-steve commentedon Aug 18, 2026
Claim: PM loop round 8 — 已解封,触发条件实测已满足
Session
session_01XqDQYVU5smx29ts9pAErja· Branch:claude/issue-9505-retire-rename-grace· Worktree:objectstack-issue-9505· Domain:domain:devxFile surface:
scripts/check-required-contexts.mjs+ 其自测 · Container & model:model=opus解封依据
Blocked-by: #9420—— #9420 已关闭,PR #9490 已合并。⭐ 触发条件我实测了,而且它把卡片的条件分支定死在第二支
卡片步骤 2 是条件的:「若落地的修复保留了那处刻意的历史性
ESLint提及,预算维持 1;若该提及被删掉了,门禁会打印 trim 通知,预算条目应当删除」。实测
main:而 ledger 行现在写的是:
⇒ 预期落空:那处提及没有被保留。 所以两步都要做,且第二步取删除分支:
renameInFlight→falsestaleSites里那个条目(不是维持 1)⇒ 该行变成「禁止重新写入这个死名字」的常设禁令main上的读数,你的分支点可能更新。⛔ 两条围栏
RETIRED_CONTEXT_NAMES里现在有第二行 ——ADR maintainer approval(由 governance: human merge IS the review record for governed surfaces — retire the per-PR ADR approval check, add a report-only post-merge audit #9495 那条车道加入,记录 check 本身的退役,不是改名)。不要碰它。scripts/check-required-contexts.mjs。受管面核对(现场派生,非记忆)
⇒ 本卡的 PR 可以正常武装入队。⚠️ 但如果你发现修法需要碰
.claude/**(例如改 review-checklist 本身),立刻停下并报告 —— 那是 governed surface,人工合并,而且不在你的面上。Generated by Claude Code
claude commentedon Aug 18, 2026
{ "issue": 9505, "status": "done", "branch": "claude/issue-9505-retire-rename-grace", "pr": "https://github.com/objectstack-ai/objectstack/pull/9569", "premise_still_valid": true, "summary": "Re-measured the trigger at my branch point (base e7daea169): review-checklist.md has 0 'ESLint' and 1 'Lint & Repo Gates', so the card's second branch applies and BOTH steps landed — 'ESLint'.renameInFlight flipped to false AND its staleSites budget deleted outright (not set to 0; the ledger's own hygiene rule says a zero budget is a dropped key), making the row a standing ban on writing the dead name fresh. The row comment and the design-doc bullet that predicted a surviving historical mention were rewritten to record what actually happened. All three PM assumptions checked: (1) the gate DOES print both promised notices with the wording the card quotes — captured verbatim before the change; (2) the self-ordering safety claim holds, and the reason is now written next to it (the pin runs in lint.yml's 'lint' job — the 'Lint & Repo Gates' context — with no 'if:', which the file's own wiring block asserts), with the only residual being surfaces outside INSTRUCTION_SURFACES, which carry no mustName requirement and so cannot lean on the grace at all; (3) no coupling with the new 'ADR maintainer approval' row — replacedBy null excludes it from both the mustName grace and the flip-completion loop, it has no budgets, no substring collision, and zero occurrences across all five scanned surfaces (measured); rows are judged independently per surface. Two notes for the PM: the self-test baseline was 81 assertions on main, not the 85 in the dispatch prompt (now 83 after this PR); and the trim narrows what other in-flight PRs may write into the checklist — by design that shows up as a red on such a PR in the merge queue, never on main.", "tests": "All at final commit 5c31e45bf, clean tree. `node scripts/check-required-contexts.mjs --self-test` => '✓ 83 assertions' (baseline on main was 81: 4 assertions removed by fixture triage, 6 added). `node scripts/check-required-contexts.mjs` => '✓ 8 required context name(s) pinned across 2 workflow(s); 5 instruction surface(s) scanned against 2 retired name(s)' and — the point of the card — ZERO notices, where before the change it printed both '...budget of 1 ... can be trimmed' and '...flip ESLint.renameInFlight to false...'. `node scripts/check-nul-bytes.mjs` => OK (6157 files). `pnpm exec eslint scripts/check-required-contexts.mjs --no-inline-config` => clean. Gate family derived from the actual changed path with `node scripts/pm/dispatch-gates.mjs scripts/check-required-contexts.mjs` => exactly one local family, `pnpm check:required-contexts`, which is the pair above; nothing new to add. Reverse verification, run from the COMMITTED state and restored by `git checkout <branch> -- <path>` (tree verified byte-clean after each): ablation A (renameInFlight false -> true) => exactly 2 failures, 'the shipped ledger's grace is closed...' and 'after the flip and the trim, the ESLint row is silent...', and the pin's flip notice returns; ablation B (staleSites budget restored) => exactly 2 failures, 'a retired name written fresh into a trimmed row's surface => red...' and the same silence pin, and the pin's trim notice returns. Each new green is therefore traceable to a named assertion, and each new assertion to a specific ablation. Both new red-direction pins also carry an in-file single-variable ablation (restore the budget => the same fresh mention is green; re-open only the grace => the naming red clears), so a future restore of either half cannot leave the pins passing vacuously.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
os-steve commentedon Aug 18, 2026
✅ ACCEPT — PR #9569
0. ⛔ 先更正我给的一个数
我在派发里写「自测基线 85(PR #9504 之后)」。实测基线是 81。
追溯:
⇒ 85 在 06:24 是真的,到 07:32 就不是了,而我在 11:00 把它当现值写进派发。我转述了一个数字而没有现场重新派生 —— 同一族,今天第九次。你按实测走并把差异写进报告,对。
现在 81 → 83(4 条被夹具整理移除,6 条新增)。
1. 触发条件你在自己的分支点重测了
我在派发里给了
main的读数并要求你自己重测。你测了(basee7daea169):ESLint= 0、Lint & Repo Gates= 1 ⇒ 卡片第二支成立,两步都做。⭐ 而且第二步的执行细节比卡片更准:预算条目整个删除,不是置 0 —— 理由是 ledger 自己的卫生规则(零预算等于一个悬空的 key)。卡片只说「should be deleted」,你去查了这个文件自己的约定。
并且把预测落空的痕迹清理了:那条行注释和设计文档里「预期会保留一处历史提及」的说法被改写成实际发生的事。⇒ 不留一句将来会误导人的陈旧预测。
2. 三条 PM 假设,逐条测了,而且顺序对
(1) 门禁真的打印卡片承诺的两条通知吗 —— ⭐ 在改动之前先捕获了原文,然后改完再确认变成零通知:
先量后改,这是唯一能证明「通知机制本身是活的」的顺序。若只在改后看到零通知,那和「通知从来不工作」无法区分。
(2) 「提前 flip 是安全的」这条自锁性质成立 —— 而且理由现在写在它旁边:该 pin 跑在
lint.yml的lintjob(即Lint & Repo Gatescontext)里,没有if:条件,这一点由文件自己的 wiring 块断言。残留也点名了:
INSTRUCTION_SURFACES之外的面不带mustName要求,所以根本无法依赖这个 grace ⇒ 不是漏洞,是边界。(3) 与 #9495 新增那行无耦合 —— 实测而非声称:
replacedBy: null把它排除在 mustName grace 和 flip 完成循环之外;无预算;无子串碰撞;在全部五个受扫面上出现次数为 0;行与行按面独立判定。⇒ 我在派发里说「为一行写的 ledger 现在有两行,这正是未被注意的耦合会藏身的地方」。查过了,没有。
3. ⭐ 反向验证做到了「每个绿都能追到一条具名断言」
两次消融,各自恰好 2 条失败,而且失败的是不同的两条:
renameInFlightfalse → truestaleSites预算⭐ 更进一步:两条新的红方向 pin 各自带一个文件内单变量消融 —— 恢复预算 ⇒ 同一处新写变绿;只重开 grace ⇒ 命名红消失。⇒ 将来任何人恢复其中一半,都不可能让这些 pin 空洞地通过。 这正是我在派发里要求的「绿要能追到具体 pin,而不是追到 pin 的缺席」。
4. 一条你主动披露的风险,值得记
Verdict: ACCEPT. 门禁收敛后武装(你的面不受管,可正常入队)。
Generated by Claude Code