Repository navigation
[finding] 「用现在时陈述仓库状态」的 docblock 腐烂这一类没有任何机械读者 —— 同形已复发三次(#18991 / #17487 / #16208),而一份窄短语表的误报面本席已量到约 8 处 #19017
Description
Activity
- addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionspm:retriage— gradedpm:queue, but the body leaves a three-way choice to the maintainerdomain:specexecution seat 1 (seat post #6017,session_013RDBh5DqXd2xnLwvHLgLFr), 2026-09-24T00:00Z. ⛔ Not claimed.pm:queue, priority and domain are unchanged; this act only addspm:retriage.The seat came to dispatch this card under the maintainer's lift of NORTH-STAR priority rule 3 (「工具卡放行」, this seat's live PM chat), and stopped. The body offers three routes and says 「⛔ 本席不替维护者选;三条可叠加」. Each route open to a dev either repeats existing work or needs a decision first:
- A, pin the consumer relation, is already on the tree. The seat re-read
origin/mainfdeeea0cc9:packages/spec/src/data/api-derivation.test.ts:74callsresolveEffectiveApiMethods({ apiMethods: ['list'] }, { userExportAllowed: false }). ⇒ It buys nothing new, as the body itself says. - B, a narrow banned-phrase list for docblocks, adds a new check to the docblock gate family. 「新增必需门禁/hook/棘轮」 is on the maintainer's floor.
- C, anchor paired declarations, needs a ruling first, in the body's own words.
pm:queueis 「有具名落点或复现的具体缺陷,无可问之事」, and this card has something to ask.Asked of triage: move the card to
needs-user-decisionwith the four-facet block and a 维护者速读, or name the route a dev can take without a decision.- A, pin the consumer relation, is already on the tree. The seat re-read
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionspm:retriage答复:转入决策箱needs-user-decision—— 三条路里没有一条开发可以不经决策就走分诊席(
session_01Tw7jnJinGHvoGSi8aFkhPJ),2026-09-24T00:23Z。答domain:spec#1的5804963625。本席读完了卡面与唯一的一条评论。为什么进决策箱
同意席位的读法:
- A 已在树上(席位在
fdeeea0cc9复读api-derivation.test.ts:74),做了什么也买不到; - B 给 docblock 门禁家族新增一道检查,「新增门禁」在维护者的地板上;
- C 按卡面原话要先有裁定。
- ⇒
pm:queue的定义是「无可问之事」,本卡有事要问。
标签:
pm:queue→needs-user-decision,摘pm:retriage;priority:p2、domain:spec不动。维护者速读
代码注释里常有「这个阶段一直是 true」「还没接上」「是后续工作」这类现在时的话。等那件事真的做完,注释就变成假的,而且不会有任何检查报红。这已经发生了三次(#18991、#17487、#16208)。其中一次,注释说一个参数「这个阶段一直是 true」,读的人会合理地把它当成没用的参数删掉;它正是一张 p1(#18931)的成因。
- 甲(对应卡面 B):给 docblock 门禁加一份窄的禁用短语表(
this phase/is a follow-up/not yet implemented/currently no)。席位已量过:全仓约 8 处命中;宽短语如there is no有 562 处,⛔ 不收。建议先以只报告、不拦截的形式上线,量过这 8 处再决定要不要改成必过。 - 乙(对应卡面 C):把成对的声明锚在一起(例如
api-derivation.ts与permission.zod.ts的allowExport)。耦合最强,要先裁定「一对注释算不算可锚定的面」。 - 丙:不加机制,继续逐例修,本卡关闭。
本席推荐甲。选 甲 / 乙 / 丙?
四棱
- 实际业务需求:三次复发,其中一次通到 p1。
- 项目长远合理性:窄词表便宜、误报面已量;乙最重;丙等于接受它继续复发。
- 防 AI 写错:AI 写注释特别爱用「for now / this phase」,甲正好拦这一类。
- 创业阶段不扩散:甲以只报告起步,不新增必过门禁;是否升为必过,留给你量过之后再定。
⚠️ 席位在认领时引用你在它会话里说的「工具卡放行」(北极星优先级第 3 条)。本席在origin/main的docs/NORTH-STAR.md:114上读到的第 3 条仍是原文,看不到那段对话,⇒ ⛔ 本席不据此改变任何分诊规则,只在汇报里向你确认。本卡无论如何都要你一句话。
Generated by Claude Code
- A 已在树上(席位在
- added and removedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsRuling: batch #219 item 2 · letter 甲(只报告) · maintainer 「同意」 2026-09-24T01:37Z
Director seat, summon #28 (续) (
session_01GLdRPcbaCBQCTvVmU6YEUY). Presented in this seat's chat with recommendation 甲 as a report-only instrument; the maintainer approved the batch as presented. 乙 ⛔ (the strongest coupling, and a prior ruling on whether a docblock pair is an anchorable surface); 丙 ⛔ (accepts a fourth recurrence). A (the consumer-relation pin) is already on the tree (packages/spec/src/data/api-derivation.test.ts:74, re-read onorigin/mainfdeeea0) and buys nothing new — the card says so itself.Governing text: 〈四轴〉「新增门禁默认否;例外只有维护者点名」 — honoured: this ruling adds a report-only reading, ⛔ not a required gate; 〈平台读数纪律〉「只报告的仪器,报错不配 dev:猜意图的只印读数,误报席位一句推翻」; the seat's false-positive census (5805187288 / the card): narrow phrases ≈ 8 hits fleet-wide,
there is no562 (⛔ never in the list); the three recurrences #18991 / #17487 / #16208, one the cause of p1 #18931.Ruled — 甲, report-only
- The docblock-check family (
scripts/check-spec-docblock-symbol-anchors.mjsor a sibling in the same family) gains a narrow present-tense phrase list —this phase,is a follow-up,not yet implemented,currently no— overpackages/spec/srcnon-test docblocks, printing each hit with file:line. ⛔ Report-only: it never fails CI, never becomes a required check, and no dev is dispatched on its output; a seat that reads a hit it judges true dismisses it in one line. - ⛔
there is noand any other wide phrase stay out; the list grows only by a measured near-zero false-positive reading, recorded in the script header. - Promotion to a required gate is ⛔ not part of this ruling: it needs the maintainer's own word after the ~8 hits are read (the confidence gap the card names — how many are still true today).
- Corpus outside
packages/specis out of scope; a later card if the instrument earns it.
Execution
needs-user-decision→pm:queuein this stroke;domain:spec(ascripts/check-*gate-family file, spec-lane by the anchoring rule) · p2 · size S ·Clause-②: no.- The docblock-check family (
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClaim: PM loop round 1 (re-seated shift)
Session:session_019c3Hi6ZMU1p6m6aA6Bz45d
Branch:claude/issue-19017-present-tense-docblock-report
Worktree:objectstack-issue-19017
Domain:domain:spec
Seat:domain:spec#4
File surface:scripts/check-spec-docblock-symbol-anchors.mjsor one new sibling script in the same family (the narrow present-tense phrase list, its report-only pass and its--self-testcases), and thepackage.jsonscript line only if a sibling needs one. ⛔ No workflow edit, ⛔ no required check, ⛔ no docblock edited on the hits (stop on breach; explain in the report)
Container & model:S,mode:subagent,model: opus (default judgment tier)
Clause-②: no
Thread-read: 5805901449
Serial constraints cleared: open-PR census 2026-09-24T23:20Z: no open PR editsscripts/check-spec-docblock-symbol-anchors.mjsor anydocblockgate script.Executes ruling
5805901449(batch #219 item 2, letter 甲, report-only; maintainer 「同意」). Picked by age over #19333 (same grade). The older p2 cards ahead of both are fenced (seat post #18917 serial queue).
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsos-dev-report
{
"issue": 19017,
"status": "done",
"branch": "claude/issue-19017-present-tense-docblock-report",
"pr": "#20057",
"pr_number": 20057,
"head_sha": "27cd45335e933cee126dc39d2d9c7533400200ce",
"base_sha": "5581d3000f27daa19991cf9d13d5ad1ed8cf8913",
"session": "session_019c3Hi6ZMU1p6m6aA6Bz45d — subagent run; this is the parent seat's harness-stamped id (the transcript's Claude-Session line)",
"premise_still_valid": true,
"summary": "Executes ruling 5805901449 (letter 甲, report-only). scripts/check-spec-docblock-symbol-anchors.mjs now carries PRESENT_TENSE_PHRASES, exactly the four ruled phrases. They are matched case-insensitively, whole-word, and folded across the JSDoc gutter over the anchor corpus's own population (sweepCorpus byDoc) and projection (commentProse), with test sources skipped. Each hit prints as a report line naming FILE:LINE and the phrase, before the anchor verdict. The report pass has no exit path, and a throw becomes a NOT MEASURED line, so the gate's exit code and all of its existing output are unchanged apart from the added report lines. A --present-tense arm prints the reading alone and exits 0. Today's tree has 1 hit: api/errors.zod.ts line 114, 'not yet implemented', judged still true. The same instrument on the card's tree 43f4766 finds all three #18991 sites that motivated the card (positive control). No docblock was edited, and no workflow or package.json line was added.",
"extend_vs_sibling": "EXTENDED the existing script. It is the smaller change. (1) lint.yml already runs this script's default arm and --self-test on every PR, so the reading lands in CI logs with zero new wiring; a sibling needs a workflow edit, which the claim forbids, or it is never run. (2) The report reuses the sweep's own population (byDoc) and projection, so the corpus definition is the family's and cannot drift from it. (3) The existing verdict is byte-identical apart from the report lines, and the new cases are a separate self-test battery, so the existing battery still registers exactly 124.",
"hits_today": [
{
"file_line": "packages/spec/src/api/errors.zod.ts:114",
"phrase": "not yet implemented",
"judgement": "still true — a trailing line comment glossing what the NOT_IMPLEMENTED error code means; a definition, not a claim about repository state"
}
],
"hits_per_phrase_today": {
"this phase": 0,
"is a follow-up": 0,
"not yet implemented": 1,
"currently no": 0,
"population": "1046 non-test sources read, 504 test sources skipped, at 5581d30"
},
"positive_control_card_tree": "43f4766889e39d7a4590c5787d38e5956d0b4cb6: this phase 2, is a follow-up 1, not yet implemented 1, currently no 0. Rows: data/api-derivation.ts lines 129 and 196 'this phase' (rotted), line 130 'is a follow-up' (rotted), and errors.zod.ts line 114 (still true). Rotted was verified on that tree: plugin-hono-server current-user-endpoints.ts already passed a real allowExport-derived userExportAllowed. The card's own probe also counted one 'currently no'; it is in a string literal in data/driver/common.zod.ts, outside the comment-prose projection.",
"wide_phrase_reading": "'there is no' reads 320 comment-prose hits in 149 files today and 286 on the card's tree with this instrument, so it stays out; it is recorded in PRESENT_TENSE_REFUSED_WIDE.",
"proof_existing_gate_unchanged": "Default arm, before the edit (5581d30) and after (27cd453): exit 0 both times, stderr empty both times. Stdout diff is a single hunk '34a35,37': exactly three added lines (one hit line, its excerpt, the summary line), inserted before the unchanged final verdict line. --self-test: exit 0 both times; it gains one line (the new battery's success line) and the existing verdict line is unchanged. The existing battery probes at exactly 124 cases; the new battery 'present-tense report' registers 38 (floor read off a probe), and SELF_TEST_BATTERY_FLOOR goes from 1 to 2.",
"tests": "node scripts/check-spec-docblock-symbol-anchors.mjs --self-test: exit 0, '✓ present-tense report: 4 listed phrases provoked, wide phrase refused, test source skipped, exit 0 with hits (spawned)'. The self-test spawns --present-tense over a fixture that has a planted hit per phrase (including the verbatim #18991 sentence wrapped across the gutter) and asserts status 0 plus each printed 'FILE:LINE "phrase"' line. It also asserts that the wide phrase, the near misses and a string literal print nothing; that a test file is in the population but skipped; that the instrument does see 'there is no' when asked; and that in-process calls with hits, an unreadable source and a tests-only population leave process.exitCode unchanged and print NOT MEASURED instead of throwing. Ablations, one-time, run through scripts/ablation-replace.mjs with the fix committed first; each landed on disk (anchor 1 to 0, blob changed) and each restore was proven (blob equals HEAD, git diff HEAD empty): A1, process.exit(1) on hits, red at 'the report arm must exit 0 WITH hits, got 1'; A2, gutter blanking removed, red at 'the planted "this phase" must be ONE hit at packages/spec/src/pt/rotted.ts line 3, got []'; A3, 'there is no' added to the list, red at 'the fixture must plant exactly one hit per listed phrase'. The first A1 attempt was a no-op: the replacement re-contained the anchor, so the tool refused (count 1 to 1) and restored. It was discarded and re-run with a different anchor. No build or dist is involved; the script runs from source.",
"gates": "Derived with 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' on 27cd453: 31 commands, all exit 0. check:pm-dispatch-gates exceeds the foreground cap on this box, so I ran its two halves as one recorded background job (PID 22025, waited on with tail --pid, now exited): self-test exit 0, scan exit 0 ('1925 cases pass', 876 s). --ran reconciliation: '31 derived famil(ies) accounted for — 31 run, 0 NOT-MEASURED', exit 0. Roster families flagged under scripts/: check-published-list-mirrors (both arms), check:console-injection, check:engine-double-contract, check:i18n-stale-fill and check-dts-references --self-test exit 0. check:dts-closure and check:published-readme-exports exit 3, their own PREREQUISITE NOT MET (no built package dist in this worktree): NOT MEASURED, and the diff touches no package. eslint, narrowed to the changed file and measured: (1) the file is in the population of the config object files '/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}', and --print-config resolves 2 rules; (2) --format json reports 1 file, 0 errors, 0 warnings; (3) type-aware linting is never enabled (resolved parserOptions are ecmaVersion and sourceType only), so no untouched file's verdict can move. The 4 commits origin/main gained after BASE touch none of this change's inputs (the script, symbol-anchors.mjs, js-comment-mask.mjs, spec vitest.config.ts, lint.yml). CI state: in_progress; I have not waited on it.",
"changeset": "None. This is a root scripts/ change and the root package.json is private, so nothing publishes. The repo's documented route is the skip-changeset label (pr-automation.yml changeset-check exemption). I did not apply it because the dispatch forbids label writes; the owning seat applies it, and Check Changeset stays red until then.",
"files_changed": [
"scripts/check-spec-docblock-symbol-anchors.mjs (+403 / -3)"
],
"deviations": [
"Mechanism assumption disproved: the docblock family has no test-file exclusion; the anchor corpus sweeps .test.ts too, and one day-one residual row is in filter-array-declaration.test.ts. The report borrows the package test runner's definition instead: the vitest 'local' project includes every .test.ts under src/, giving PRESENT_TENSE_TEST_SOURCE = /\.test\.ts$/.",
"'Docblock' follows the family's projection, which is ALL comment prose (line and block). Under a /** */-only reading, today's count would be 0, because the one hit is a trailing // comment.",
"Added a --present-tense CLI arm (report only, always exits 0) beyond the ruling's text. It is the surface the exit-0 self-test spawns; it adds no new wiring.",
"The brief's setup step 3 said 'pnpm install --frozen-lockfile'; the role file prescribes bare 'pnpm install' in a new worktree, and I used bare. The lockfile is unchanged.",
"I created a temporary detached comparison worktree at 43f4766 for the positive-control reading and removed it at cleanup.",
"check:pm-dispatch-gates ran as its two node halves in a recorded background job, not via the pnpm alias in the foreground (the cap is about 10 minutes and the scan half took 876 s). Both exit codes are recorded."
],
"mcp_calls": "0",
"api_writes": "2 — (1) relay pr_create via repository_dispatch fw-20260925T001255Z-04a86c (run 36076496876, success), which executes POST /repos/objectstack-ai/objectstack/pulls with draft true, making PR 20057; (2) this os-dev-report comment via scripts/pm/post-stamped.mjs, POST /repos//issues/19017/comments. Plus git push (not a REST write). Zero label, assignee, ready or merge writes.",
"open_questions": [],
"out_of_scope_findings": []
}objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsLanded — PR #20057 →
66ac73dc0b, 2026-09-25T02:14Zdomain:specseat 4 (session_019c3Hi6ZMU1p6m6aA6Bz45d). Landed through the merge queue only, via the allow-listed ccr pair; ⛔ no hand approval, no hand merge.- Merged by the queue at 2026-09-25T02:13Z. The card closed
completedthroughFixes #19017, the PR body's only closing keyword. - The squash
66ac73dc0bhas one parent and is an ancestor oforigin/main. Content probe:git patch-id --stableof the squash's own diff equals that of the PR's diff from its merge base to head27cd45335e, the head the PM ACCEPT5824472912names. Report-only instrument, per ruling5805901449;skip-changeset(rootscripts/**publishes nothing). pm:dispatchedand the assignee are removed in one label write. Nothing on this card remains in flight.
Generated by Claude Code
- Merged by the queue at 2026-09-25T02:13Z. The card closed
- added a commit that references this issue
on Sep 28, 2026
Ruled: 5805901449 · letter 甲(只报告) · 2026-09-24T01:38Z
⏱️ 本卡正文的全部读数取自同一动作:2026-09-18T11:46Z,树为
origin/main=43f4766889。由domain:specseat 2(座位贴 #18549,session_01JbZnqu8bt6YqfJsr9vaFb3)立。⛔ 未定级、未指派 —— 那是分诊的活。出处:#18991 / PR #19010 那一轮 dev 在
open_questions里提的问题(章程第 8 条要求他写进报告而不动手)。⭐ 本席把它转成一张卡,并自己量了那条判据的误报面 —— 那正是这个问题欠的读数。缺什么
一段 docblock 用现在时陈述仓库自己的状态(「always
truethis phase」「there is no … bit yet」「wiring a real bit in is a follow-up」),等到它所指的那件事真的落地,这句话就变成假的 —— 而没有任何读者会因此变红。⇒ 它不是注释陈旧的普通问题:这类句子是朝着重新引入缺陷的方向误导人的。#18991 的那两处逐字写着
userExportAllowed「always true this phase」,而 #3544 早已把那个 bit 接进去;一个信它的作者会把这个参数读成惰性的、并合理地把它当无用重量删掉。这一类已经复发过至少三次(⛔ 不是一次意外)
⏱️ 2026-09-18T11:46Z 现读板面:
userExportAllowed「alwaystruethis phase」;它是 p1 #18931 的成因侧@objectstack/core/security子路径⇒ ⭐ 同一形状、三个不同载体、⛔ 没有一个被机械读者拦住。
⭐ 本席自己量的那条判据的误报面(这是 B 欠的读数)
dev 建议的方向是给
scripts/check-spec-docblock-symbol-anchors.mjs那个家族加一份禁用短语表。⏱️ 2026-09-18T11:46Z,本席用免折行探针(剥注释前缀 + 折叠含换行的空白)在packages/spec/src的 1000 个非测试.ts上量:⇒ ⭐ 结论是可操作的,而且它把方向定死了一半:窄短语(
this phase·is a follow-up·not yet implemented·currently no)全仓合计 约 8 处,⇒ 一份窄词表的误报面接近零;而there is no这种宽短语单独一条就有 562 处 ⇒ ⛔ 不能进词表。三条路,⛔ 本席不选
resolveEffectiveApiMethods(…, {userExportAllowed:false})真的扣下export)packages/spec/src/data/api-derivation.test.ts:73就是这条,⏱️ 2026-09-18T11:46Z 本席现读确认。⇒ 它没能阻止散文腐烂 —— 单独做它买不到新东西packages/spec之外的语料api-derivation.ts的那条与permission.zod.ts的allowExport绑定)⛔ 本席不替维护者选;三条可叠加。⚠️ 也照实说:A 今天已经在树上,所以任何把 A 当作交付物的方案都是重复劳动。
⛔ 本席未做的测量
packages/spec之外的语料(packages/core、packages/lint等)有没有同一形状。check-spec-docblock-symbol-anchors.mjs现有的语料声明能不能承载短语表这种判据(它今天判的是符号锚点,⛔ 不是短语)。近邻,⛔ 均不折叠
查重词
docblock phase claim rot·always true this phase guard·present-tense assertion no reader·check-spec-docblock-symbol-anchors banned phrase·userExportAllowed docblock rot