Skip to content

Commit 66ac73d

Browse files
feat(scripts): report-only present-tense phrase reading on the spec docblock corpus (#20057)
Fixes #19017 Clause-②: no Executes ruling `5805901449` on #19017 (batch #219 item 2, letter 甲, 「只报告」; maintainer 「同意」): the spec docblock gate family gains a narrow present-tense phrase reading, report-only. ## What changed One file: `scripts/check-spec-docblock-symbol-anchors.mjs` (+403 / -3). - `PRESENT_TENSE_PHRASES` is exactly the ruled list: `this phase`, `is a follow-up`, `not yet implemented`, `currently no`. Matching is case-insensitive and whole-word (`currently no` does not match `currently none`). Comment delimiters and the JSDoc gutter are blanked and whitespace is folded across lines, so a phrase wrapped over two lines is one hit, reported at the line where it starts. - **Population and projection are the anchor corpus's own**: the files `sweepCorpus` walked (its `byDoc`), read through `commentProse`. So "docblock" means what it means for this gate: every comment, line or block, and never code or a string literal. Test sources are skipped. - **Report-only by construction.** `reportPresentTense` has no exit path and sets no exit code. It turns any throw into a `NOT MEASURED` line. It runs before the anchor verdict, so it also prints on a red run and cannot move the verdict. Each hit prints as a `📝 [present-tense] FILE:LINE "phrase"` line, followed by one summary line. - A new `--present-tense` arm prints the reading alone and always exits 0. It is also what the exit-0 self-test spawns. - The header records the list and its growth rule: a phrase joins only with its own measured reading in `PRESENT_TENSE_CENSUS`, and the self-test goes red on a listed phrase that has no reading. The header also records today's count per phrase. `PRESENT_TENSE_REFUSED_WIDE` records why `there is no` stays out. - ⛔ No workflow edit, no `package.json` edit, no required check, and no docblock edited. ## Extend vs sibling: extended, and why I extended the existing script instead of adding a sibling script. It is the smaller change: 1. **The reading is taken where it will be read.** `lint.yml` already runs this script's default arm and `--self-test` on every PR, so the report lands in that step's log with no new wiring. A sibling would need either a workflow edit (out of scope for this claim) or nothing to run it at all. An instrument no one runs takes no reading. 2. **One population, not two.** The report reuses the sweep the gate already makes (`byDoc`), so the corpus definition is the family's and cannot drift from it. A sibling would need its own walker, or would have to import this one's internals. 3. **The existing verdict is left alone.** It stays byte-identical apart from the added report lines (proof below). The new self-test cases are a separate battery, so the existing battery still registers exactly 124 cases. ## Today's reading, and the judgement on each hit `origin/main` at `5581d3000f27daa19991cf9d13d5ad1ed8cf8913`: 1,046 non-test sources read and 504 test sources skipped. | phrase | hits | file, line | judgement | |---|---|---|---| | `this phase` | 0 | | | | `is a follow-up` | 0 | | | | `not yet implemented` | 1 | `packages/spec/src/api/errors.zod.ts` line 114 | **still true.** A trailing line comment that glosses what the `NOT_IMPLEMENTED` error code means. It defines the code and makes no claim about the repository's state. | | `currently no` | 0 | | | **Positive control.** I also ran the same instrument on the card's own tree, `43f4766889e39d7a4590c5787d38e5956d0b4cb6`. It reads 2, 1, 1 and 0 for the four phrases. The first three are the `packages/spec/src/data/api-derivation.ts` sites that #18991 repaired (lines 129, 130 and 196, all **rotted**). I checked on that tree that `plugin-hono-server`'s `current-user-endpoints.ts` already passed a real `allowExport`-derived `userExportAllowed`. The fourth is the same `errors.zod.ts` gloss. The card's probe also counted one `currently no`. That one is in a string literal (`packages/spec/src/data/driver/common.zod.ts`), outside this projection. **The wide phrase, measured with this instrument.** `there is no` gets 320 comment-prose hits in 149 files today, and 286 on the card's tree. It stays out. ## Proof the existing gate is unchanged apart from the report lines I ran the default arm on `5581d3000f` before any edit and again on `27cd45335e` after the edit: - The exit code is 0 before and 0 after, and stderr is empty both times. - Stdout gains exactly three lines, inserted after the last day-one residual row and before the unchanged final line: one `📝 [present-tense]` hit line, its excerpt line, and the summary line. Every other line is byte-identical: `diff` reports a single `34a35,37` hunk. - `--self-test` still exits 0 and gains one line (the new battery's success line). The existing verdict line is unchanged. The existing battery was probed at exactly 124 cases, and the new battery registers 38. **The exit-0-with-hits case lives in the self-test.** It spawns `--present-tense` over a fixture tree with one planted hit per phrase, then asserts exit 0 and each printed `FILE:LINE "phrase"` line. It also asserts the following: - The wide phrase, the near misses (`currently none`, `this phased`, `follow-upper`) and a string literal print nothing. - A `.test.ts` that carries all four phrases is in the population but skipped. - The instrument does find `there is no` when asked directly, so it is kept out by the list and not by a blind matcher. - In-process calls with hits, an unreadable source and a population with only test files each leave `process.exitCode` untouched and print `NOT MEASURED` instead of throwing. **Ablations** (one-time, run through `scripts/ablation-replace.mjs`, which checks the mutation landed on disk and proves the restore: blob equals HEAD and `git diff HEAD` is empty; no permanent test file): - A1: `process.exit(1)` when the report has hits. Red at `the report arm must exit 0 WITH hits, got 1`. My first A1 attempt was a no-op, because the replacement still contained the anchor and the tool refused (anchor count 1 to 1, restored). I discarded it and re-ran with a different anchor. - 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`. ## Gates (on `27cd45335e`) `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 31 commands. Results: - **30 of 31 exit 0**, including `check-spec-docblock-symbol-anchors` (both arms), `check-scripts-symbol-anchors` (both), `check-self-test-wired` (both), `check-self-test-workflow-commands` (both), `check-comment-mask-corpus`, `check:nul-bytes`, `check:entry-guard`, `check:parse-guard` and `check:watch-hint-literal`. - `pnpm check:pm-dispatch-gates` is longer than the foreground cap on this shared box, so I ran its two halves separately. The `--self-test` half exits 0. The scan half also exits 0 (`dispatch-gates self-test: 1925 cases pass`; it took 876 s). - `--ran` reconciliation: `31 derived famil(ies) accounted for — 31 run, 0 NOT-MEASURED`, with every exit code recorded before any pipe. - **Roster families under `scripts/`** that the derivation flagged: `check-published-list-mirrors` (both), `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). These are NOT MEASURED, and this diff touches no package. - **eslint**, narrowed to the one changed file and measured: ① it is in the population of eslint's own config object `files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']`, and `--print-config` resolves 2 rules for it; ② `--format json` reports 1 file, 0 errors and 0 warnings; ③ the config never enables type-aware linting (the resolved `parserOptions` carry only `ecmaVersion` and `sourceType`), so this diff cannot move any other file's verdict. - **Changeset: none.** This is a root `scripts/**` change and the root package is `"private": true`, so nothing publishes. The repo's documented route is the `skip-changeset` label. This dispatch forbids me any label write, so the owning seat applies it, and `Check Changeset` stays red until it does. ## Acceptance notes - **Mechanism check: this family had no test-file exclusion.** The anchor corpus sweeps `.test.ts` files too; one of its day-one residual rows is in `filter-array-declaration.test.ts`. The report's exclusion is borrowed from the package's own test runner: the `local` project in `packages/spec/vitest.config.ts` includes every `.test.ts` under `src/`. I did not invent a new definition. - **"Docblock" follows the family, which means all comment prose.** If it were read as `/** */` blocks only, today's count would be 0, because the one hit is a trailing `//` comment. - `for now` gets 4 comment-prose hits today and is not on the ruled list. Adding it would need its own measured reading, so I recorded it here and did not add it. - #17487 and #16208 (the card's other two instances) are not addressed here. They remain open under their own cards. --- _Generated by [Claude Code](https://claude.ai/code/session_019c3Hi6ZMU1p6m6aA6Bz45d)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6696056 commit 66ac73d

1 file changed

Lines changed: 403 additions & 3 deletions

File tree

0 commit comments

Comments
 (0)