docs(6209): rulebooks, pull telemetry, lesson usage, duplicate arm, cited status, trigger shape
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m3s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 13s

Six more test files state their pinned properties without the issue and
milestone history: the pull-telemetry guard explains enumerating kinds
instead of listing two getter incidents, cited-record status explains why
a hint's id needs its status instead of recounting one misreported step,
and the trigger-shape guard keeps its reasoning about why prose heuristics
fail while dropping the dated corpus audit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 21:28:35 -04:00
co-authored by Claude Opus 5.5
parent ff08500128
commit 17e1931c0b
6 changed files with 91 additions and 112 deletions
+19 -21
View File
@@ -1,9 +1,9 @@
"""The by-name duplicate arm confirms its grep hits against the real extractor (#4227).
"""The by-name duplicate arm confirms its grep hits against the real extractor.
#4222 fixed one end of this defect: the extractors that decide what a payload
DEFINES now blank comment and string spans before any line matcher runs. This
is the other end — `scribe_local_dups`, which decides which OTHER files already
define that name — and it was a plain `git grep`.
The extractors that decide what a payload DEFINES blank comment and string
spans before any line matcher runs. This is the other end — `scribe_local_dups`,
which decides which OTHER files already define that name — and a plain
`git grep` cannot do that.
A grep sees lines, not spans. The line
@@ -13,18 +13,16 @@ is prose from a module docstring in this repo, and it matches the arm's pattern
for `name=with`. So the arm would tell a writer their genuine symbol was
already defined, and point at a docstring.
WHAT THE FIX COSTS, measured rather than guessed, over 141 payload files of
this repo: the arm removed 15 of 210 report lines, and every one was a string
literal, a comment, an import statement, or Vue's `const emit = defineEmits()`
boilerplate. No real definition was lost — where a name had both a real
definition and a phantom, the phantom was dropped and the definition kept.
Timing: mean 193ms → 222ms, worst 569ms → 572ms. The arm was already dominated
by its twelve `git grep` calls, so confirming costs about 15% rather than the
second a per-(name, file) shape would have cost.
WHAT CONFIRMATION COSTS, measured rather than guessed: it drops string
literals, comments, import statements and Vue's `const emit = defineEmits()`
boilerplate, and no real definition — where a name has both a real definition
and a phantom, the phantom goes and the definition stays. The arm is
dominated by its `git grep` calls, so confirming adds about 15% (a mean of
~30ms) rather than the second a per-(name, file) shape would cost.
These cases are written against real git repositories rather than mocks,
because what is being pinned is the interaction between `git grep`, `head` and
the extractor — which is where #4042 lived too.
the extractor — which is also where a `pipefail` + `head` interaction lives.
"""
from __future__ import annotations
@@ -77,7 +75,7 @@ def repo(tmp_path):
def test_a_sentence_about_a_definition_is_not_a_definition(repo):
"""The verify case from #4227: one real `def change`, one docstring that
"""One real `def change`, one docstring that
wraps onto a line beginning `function change`. The writer is told about
the first file and not the second."""
build, run = repo
@@ -162,15 +160,14 @@ def test_an_import_is_not_a_definition(repo):
assert "card.vue" not in out, "an import site is not a definition site"
# ── the caps, which is where #4042 lived ─────────────────────────────────────
# ── the caps ─────────────────────────────────────────────────────────────────
def test_the_candidate_cap_is_raised_above_the_display_cap():
"""Confirmation REMOVES hits, so a cap applied before it runs lets phantom
matches crowd real definitions out of the window — hits dropped before
anyone looked at them, which is #4042's bug in a new place. Asserted on
structure (rule 167) because the ordering is what matters, not the
numbers."""
anyone looked at them. Asserted on structure because the ordering is what
matters, not the numbers."""
src = DEFS.read_text()
for const in ("_SCRIBE_DUP_CANDIDATES=", "_SCRIBE_DUP_SHOWN="):
assert const in src, f"{const.rstrip(chr(61))} is gone — the two caps were folded back together"
@@ -196,7 +193,7 @@ def test_phantoms_ahead_of_the_display_cap_do_not_hide_a_real_definition(repo):
def test_the_early_exiting_head_still_keeps_its_own_output(repo):
"""#4042, re-run through the new shape: under `pipefail` a `head` that
"""Under `pipefail` a `head` that
exits while git grep is still writing must not void the hits it printed.
Every file here holds a REAL definition, so confirmation keeps them all
and only the display cap applies."""
@@ -211,7 +208,8 @@ def test_the_early_exiting_head_still_keeps_its_own_output(repo):
def test_a_selector_named_inside_a_css_comment_is_not_a_rule(repo):
"""#2990's defect, on the lookup side rather than the extraction side."""
"""A selector inside a CSS comment, on the lookup side rather than the
extraction side."""
build, run = repo
build({
"real.css": ".badge { color: red; }\n",