Repository navigation
Epic: Harden the four extraction gauntlets (function/args/class/dependency) per language #813
Description
Why
The four extraction gauntlets in tests/extraction/ (test_function_extraction_strict.py,
test_args_extraction_strict.py, test_class_extraction_strict.py,
test_dependency_extraction_strict.py) validate func_start, args, class_start, and
_dependency_capture — the rules that isolate exact function/class/dependency identifiers used
everywhere downstream (RAG mapping, 3D visualization, risk scoring). An audit (2026-07-30) found
them structurally excellent but dangerously sparse: most languages carry only 2-3 valid cases,
2-3 invalid cases, and exactly one pathological case. For an AST-free engine, one
pathological case per language is a smoke test, not a gauntlet.
A first pass deepening just 8 languages' function-extraction coverage (still function-only,
still only 8 of 44 in-scope languages) already surfaced real, previously-undetected bugs in
under an hour of empirical testing:
javascript/typescriptfunc_startfalse-positive-matches a single-line string literal
containing function-shaped text (let query = "function Foo() {";). Root cause:
detector.py's_slice_by_bracescomputesfunc_start.finditer(code)against the raw code,
before building the string/comment-shieldedsafe_codeused later for the brace search — this is
an architectural gap affecting every language routed through_slice_by_braces(Mode B), not
just JS/TS.typescriptfunc_startfalse-positive-matchestype Foo = (a: T) => R;(a type alias) as
if it were a real arrow-function assignment.javafunc_startbreaks on one-level-nested generic bounds (<T, U extends Comparable<U>>) — the same "Rule 11" nested-delimiter bug class already fixed elsewhere in
epic Epic: Strict & exact regex test coverage for all structural signatures, per language #518, just never checked for this rule.gofunc_startdoesn't recognize Go 1.18+ generics (func Foo[T constraints.Ordered](...))
at all — mainstream, ~5-year-old Go syntax, currently invisible to the engine.
None of these were hypothetical or contrived — they're realistic code an AST-free engine will
encounter constantly. Expect more like them across the remaining 36 in-scope languages.
Methodology
Full methodology lives in
tests/extraction/how_to_harden_extraction.md
— read that directly rather than expecting a summary here; it covers the per-language checklist
(valid cases across syntax eras + testing-framework patterns, invalid cases covering real
lookalikes, 10-15 pathological cases per major language), the verification discipline (empirical
check before adding, full ReDoS/lint/crucible rigor for any fix), a seed recurring-bug-class list,
and the proposed per-language test file layout replacing the four monolithic dicts.
Scope: 44 languages, one sub-issue each
A sub-issue is filed for every language with at least one non-None rule among
func_start/args/class_start/_dependency_capture in LANGUAGE_DEFINITIONS. Each sub-issue,
titled "Extraction hardening: <language>", covers all four gauntlets for that language
together (see the methodology doc's "work language-by-language, not gauntlet-by-gauntlet"
rationale).
In scope (44): abap, agc_assembly, apex, assembly, c, cobol, cpp, csharp, css, dart,
dockerfile, embedded_python, fortran, go, groovy, haskell, html, java, javascript, jcl, kotlin,
livecode, lua, m4, makefile, matlab, objective-c, perl, php, powershell, python, ruby, rust, scala,
scheme, shell, solidity, sqlite, swift, tcl, typescript, yacc, yaml, zig
Out of scope (14, no relevant rules defined at all): batch, blp, csv, glsl, hlo, json,
markdown, mlir, nix, pbtxt, plaintext, proto, td, xml
Suggested order: javascript, typescript, java, go first (already have confirmed
findings to fix, not just a fresh sweep needed), then by real-world prevalence/complexity, then the
smaller/legacy long tail (cobol, fortran, assembly, abap, etc.) last.
Living checklist — update this section as sub-issues close
Each sub-issue ends with an "update the epic" step: append any newly-confirmed recurring bug class
or language-specific gotcha here (and to the methodology doc's own seed list) before closing, so
later languages start from a sharper checklist. Current confirmed classes:
-
Nested-generic/template flattening (Rule 11 shape) — check any rule using a flat
<[^>]*>/
\([^)]*\)where the language allows one level of real nesting. -
Missing modern-era syntax entirely (Go 1.18+ generics, Python 3.12 PEP 695 generics, etc.) —
check the language's own version history for mainstream features added in the last ~5-8 years. -
Unshielded string/comment content reaching a Mode-B rule's
finditercall (_slice_by_braces
confirmed;_slice_by_indentation/_slice_by_labels/_slice_by_terminatornot yet checked). -
Type-alias vs. real-declaration ambiguity — any
type X = .../using X = .../typedef
construct sharing a surface shape with a real function/class declaration. Confirmed real in
typescript (Extraction hardening: typescript #815):type Foo = (a: T) => R;shares the exactIDENT = (...) => ...shape as
a real arrow-function assignment. -
(new, from Extraction hardening: typescript #815) Identifier-then-optional-type-annotation-then-operator. Any rule that
assumes an identifier is followed directly by the operator it cares about (=,(, etc.)
without accounting for an optional type annotation in between — common in every statically-typed
language (const Foo: React.FC<Props> = (...) => {, and the equivalent shape exists in Kotlin,
Swift, Rust, C#). Fix shape: an optional bounded skip-zone (:then bounded content excluding
the real operator's own character) before the operator check — but watch for the operator
appearing inside the type itself (e.g. a function-type annotation's own=>), which the skip
zone can't safely cross without additional care (documented as a known limitation in Extraction hardening: typescript #815 rather
than solved). -
(new, from Extraction hardening: typescript #815) Rule 11 also applies to inheritance/extends clauses, not just
args/return-types.class_start's own generic step-over (between the class name and its
extends/implementsclause) can have the exact same flat-<[^>]*>bug — and it's an easy
miss because the class NAME still matches fine even when this breaks (only the extends/implements
capture group silently goes missing). Check class_start's generic handling explicitly for any
future language with generics, not just func_start/args. -
(new, from Extraction hardening: typescript #815) Bare-call-vs-bare-definition ambiguity — a known, ACCEPTED limitation
class, not something to keep re-attempting. In any C-family/JS-family language, a bare call
statement at true line start (it('test', fn);,foo();) can be textually identical to a bare
method/function signature with no body shown. This is the same fundamental ambiguity csharp func_start never matches expression-bodied methods, and can hallucinate bare calls as functions with no enclosing brace #789
(csharp) hit and deliberately did NOT fix at the regex level (fixing it broke the cross-language
"extraction gauntlet" convention of testing bare fragments). Document with a dedicated
known-limitation test per language rather than spending time re-investigating whether it's
fixable — it generally isn't, without real scope-tracking this engine doesn't have. -
(new, from Extraction hardening: typescript #815) A "zero diff" on
crucible_check.pyafter adding a regex feature can mean
the corpus doesn't exercise it, not that the feature is wrong to add — same pattern already
seen in html attribute-value patterns assume double-quoted values only (single-quoted HTML never matches) #735. Conversely, a real per-language diff after a fix should be confirmed as confined to
that language (grepthe diff for other language names) before blessing, not just eyeballed for
plausible magnitude. -
(new, from Extraction hardening: java #816)
class_start's generic step-over can be MISSING entirely, not just flat.
TS's Extraction hardening: typescript #815 bug (recurring class 6 above) was a flat<[^>]*>that needed widening. Java's version
of the same bug was worse: there was no generic-parameter step-over between the class name and
the extends/implements check AT ALL, soclass Foo<T> extends Base<T> {(any generic class with
a subsequent extends/implements clause, extremely common real Java) silently lost the entire
inheritance capture. Same fix idiom applies ((?:\s*<(?:[^<>]|<[^<>]*>)*>)?inserted between the
name capture and the extends/implements check), but check whether the step-over exists at all
before assuming it just needs widening — two different failure shapes, same root symptom (name
capture looks fine, inheritance capture silently vanishes). -
(new, from Extraction hardening: java #816)
_dependency_captureis matched against raw, unshielded file content for
EVERY language, unconditionally — broader than recurring class 3. Unlikefunc_start's
Mode-B_slice_by_bracespath (gated to js/ts, tracked via prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859),_dependency_captureis run
viaimport_regex.finditer(content_buffer)ingalaxyscope.py, wherecontent_bufferis the
raw file content read straight off disk — there is no shielding gate here at all, for any
language. Confirmed reproducible for java: animport ...;-shaped line inside a Java 15+ text
block ("""...""") at true line start still produces a phantom dependency-graph edge. Not
fixed (fixing it means shieldingcontent_bufferbefore every language's
_dependency_capture.finditer()call — a pipeline-wide change, not a per-language one) but
worth checking for the same false-positive shape (string/comment content containing
import-statement-shaped text at true line start) on every future language's dependency pass. -
(new, from Extraction hardening: java #816) Recurring class 3 (unshielded content reaching a Mode-B rule) reproduced on
a second, unrelated language feature. Java 15+ text blocks ("""multi-line string""")
produce the exact samefunc_startfalse-positive as js/ts template literals — confirms this
is a genuine cross-language architectural gap (not a js/ts-specific quirk), strengthening the
case for the "broaden the_slice_by_bracesshielding gate" follow-up PR noted below. -
(new, from Extraction hardening: go #817) The generic-step-over bug can be scoped to just ONE of the four rules even
when the language has generics everywhere. Unlike java (Extraction hardening: java #816, wherefunc_start/args
shared the bug andclass_starthad a different-shaped version of it) and typescript (Extraction hardening: typescript #815,
wherefunc_start/class_startboth needed fixes), go'sclass_startandargsrules
already had the correct(?:[ \t\n]*\[[^\]]*\])?generic step-over — onlyfunc_start(for
a parameterless-of-receiver, i.e. plain top-level generic function) was missing it. Don't
assume a generics bug found in one rule implies the same gap in the other three for a given
language — check each independently; some codebases already got it right in three out of four
places. -
(new, from Extraction hardening: go #817) Recurring class 3 (unshielded content reaching a Mode-B rule) reproduced on
a THIRD, unrelated language feature. Go's raw string literals (backtick-delimited, common for
embedded SQL/templates/regex) produce the samefunc_start/_dependency_capturefalse positive
as js/ts template literals and Java text blocks. Three languages, three completely different
syntax features, same architectural root cause — strong confirmation this is a real, general
gap worth the dedicated_slice_by_braces-broadening follow-up, not a per-language curiosity. -
(new, from Extraction hardening: python #818) The Rule-11 nested-delimiter bug shape isn't angle-bracket-specific — it hit
python's SQUARE-bracket PEP 695 (3.12+) generics identically.func_start/args/class_start
all shared a flat[^\]]*generic-parameter step-over that broke on any nested-bracket type
bound (def Foo[T: Sequence[int]](x: T) -> T:). Same fix idiom, square-bracket variant:
\[(?:[^\[\]]|\[[^\[\]]*\])*\]. Whenever a language's generics/type-params use[...]instead
of<...>(Python, Go — see class 1's original framing was angle-bracket-biased), check for the
identical flat-negated-character-class mistake. -
(new, from Extraction hardening: python #818) Mode C (
_slice_by_indentation, python/yaml) ALREADY does the shield-before-
match fix that Mode B (_slice_by_braces) only has gated to js/ts. Verified empirically:
python's real pipeline shields triple-quoted strings/standard strings/comments via an
index-aligned shield BEFORE callingfunc_start.finditer(), so the same string-literal false
positive confirmed at the regex level for python (matches recurring class 3's shape) is NOT a
live bug in the actual pipeline. This is the reference implementation the eventual
_slice_by_braces-broadening follow-up should mirror — it already exists in this codebase,
just for the wrong mode. -
(new, from Extraction hardening: python #818) Not every vertical-split seam needs pathological-test coverage — check
against what real formatters actually produce. A vertical split between an identifier and an
immediately-following generic bracket (def Foo\n[T](...)) fails to match and was judged a
pre-existing, deliberately-undocumented-as-a-bug gap: no formatter (black, ruff format) ever
inserts a line break at that exact seam. Contrast with recurring class 2's guidance ("check the
language's own version history") — realism-triage applies to formatting seams the same way it
applies to feature coverage. -
(new, from Extraction hardening: rust #819) A prior partial Rule-11 fix can leave a SIBLING rule un-fixed — always check
all four rules even when one already has a comment saying "fixed." Rust'sfunc_startalready
carried an explicit "BUG FIX (Rule 11...)" comment and a two-level-nesting idiom from an earlier
pass, butargs(parsing the exact samefn <generics>(...)shape) was never updated and still
had the flat<[^>]*>. A rule-level fix comment is not proof the sibling rules got the same
treatment — check each of the four independently even when the language's own code comments
suggest "this was already handled." -
(new, from Extraction hardening: rust #819) A
_dependency_capturecharacter class missing a single common symbol can
hide an entire common statement shape. Rust's capture char class
([a-zA-Z0-9_:{},\s]) was missing*, so EVERY glob import (use std::io::*;,
use super::*;— extremely common, appears in nearly every Rust test submodule and in
re-export-heavy crates) produced zero dependency-graph edges. Confirmed viacrucible_check.py:
a real corpus file's detected-dependency count jumped from 1 to 5 once fixed. When reviewing a
_dependency_capturecharacter class, explicitly check it against every symbol the language's
own import/use syntax can contain (*,{,}, aliasing keywords, path separators) rather than
assuming the existing class is complete. -
(new, from Extraction hardening: rust #819) Recurring class 3 reproduced on a FOURTH, unrelated language feature. Rust's
raw string literals (r#"..."#, common for embedded SQL/regex/JSON) produce the same
func_start/_dependency_capturefalse positive as js/ts template literals, Java text blocks,
and Go raw strings. Four languages, four unrelated syntax features, same root cause. -
(new, from Extraction hardening: javascript #814) A fix's own optional-whitespace choice can open a NEW false-positive path —
caught only by runningcrucible_check.pyagainst real code, not by any hand-written test
case. Fixing javascript'sfunc_start/argsto recognize ES6 generator methods (*foo() {})
initially used\*?[ \t\n]*(whitespace-tolerant, matching the style of the other modifier
gaps). This let a JSDoc comment continuation line —* A (storage) buffer attribute..., where
*is the comment's own marker and "A" is the first word of a plain-English sentence — get
hallucinated as a generator method namedA, confirmed against a real corpus file
(threejs/BufferGeometry.js). No hand-written pathological test case would have caught this
(it requires exactly the right prose shape); only running the real ~80-repo corpus surfaced it.
Fix: require the star to hug the name with zero intervening whitespace
(\*?with no trailing[ \t\n]*) — this is also strictly more accurate, since every real
formatter (Prettier included) always emits*foo()with zero space, never* foo(). Lesson:
when a fix widens a rule with a "reasonable-sounding" whitespace-tolerant character class, check
whether that specific optional character (unlike the language keywords around it) can ALSO
appear as the leading character of a comment or string in real code — if so, prefer the
strictest shape real formatted code actually produces, not the most permissive shape the
language grammar technically allows. -
(new, from Extraction hardening: csharp #820)
class_start's missing-generic-step-over bug (recurring class 1/6/9/13)
keeps recurring independently across THREE unrelated languages — java, python, and now csharp
all had it, each discovered separately. By the time csharp was reached, this should have been
checked as step one rather than rediscovered — for any future language with generics, check
class_start's name-to-base-list gap FIRST, before doing anything else, given the hit rate so
far (3 of the 4 generic-capable languages checked had this exact bug). csharp's variant also
needed a companion fix no other language has needed yet: a primary-constructor parameter-list
step-over (record Foo<T>(T Value) : Base<T>, C# 9+ records / C# 12 primary constructors on
classes/structs) — the constructor's(...)was equally unconsumed between the generics and
the base-list:check, independently of the generic-parameter fix. Any language with
"primary constructor"-style class declarations (records, Kotlin/Scala primary constructors)
should check for this same shape. -
(new, from Extraction hardening: csharp #820) A
_dependency_capturerule can be missing an entire real-world statement
SHAPE, not just a character. csharp'susing Alias = Target;alias directive (common for
shortening long generic types or disambiguating identically-named types from different
namespaces) didn't match AT ALL — there was no allowance for theIDENT =prefix at all, not
just a missing character in an existing class (contrast with rust's Extraction hardening: rust #819 glob-import finding,
which WAS just a missing*). The alias TARGET itself also commonly needed its own step-over
(using StringList = List<string>;— the primary real-world reason alias directives exist),
confirmed viacrucible_check.pyagainst a real Roslyn corpus file. When reviewing
_dependency_capture, check not just the character class but whether the rule's overall
grammar shape actually covers every statement FORM the language's import/using syntax supports
(plain, aliased, static, global, generic-targeted), not just variations on a single form. -
(new, from Extraction hardening: cpp #821) Out-of-line member definitions (
Class::member(...)) are a whole category
worth checking explicitly for C-family languages with separate declaration/definition —
operator overloads specifically are easy to miss. cpp'sfunc_start/argssupported
Class::method(...)for plain identifiers but had ZERO allowance for a class-qualifier before
theoperatorkeyword —TargetClass::operator=(...),TargetClass::operator==(...)were
completely invisible, even though bare (non-qualified)operator=(...)already worked. This
is a distinct failure mode from Rule 11 (not a nesting-depth bug — the alternative branch for
operatorsimply never had the qualifier-prefix group other branches already had). Confirmed
viacrucible_check.pyagainst 4 real repos across 7 files (java/csharp/python's class_start
generics bug recurring 3x made this pass expect ANOTHERclass_startfinding, but this one
was infunc_start/argsinstead — don't assume a recurring bug class means the SAME rule
breaks again; check all four independently every time). -
(new, from Extraction hardening: cpp #821) When inspecting a
crucible_check.py --update --yesdiff for confinement,
grep the rawgit difftext at your own risk — it will report false "other language" hits from
dependency-list VALUES and unrelated context lines, not just changedParsed Fileskeys.
Naively grepping the diff for path-like strings after blessing cpp's fix surfaced dozens of
.zig,.pm, and unrelated.hpaths that looked like a confinement violation — they were
just pre-existing#include/dependency values sitting inside OTHER unrelated files' JSON
entries (or stale info from a--updaterun whose earlier check-only pass had truncated
output), not actually-changed entries. The reliable check is a structural diff: load both
the pre- and post-update golden master JSON, and diff only the top-level
"6. Parsed Files (Scanned Artifacts)" -> "<repo>" -> "Files"keys against each other (see
Extraction hardening: cpp #821's PR for the exact snippet) — never eyeball a raw textualgit difffor confinement on a
file this large. -
(new, from Extraction hardening: c #822) "Confined to the language you changed" can legitimately mean MULTIPLE repo
buckets, not one — polyglot/embedded files inside a differently-labeled repo are real,
expected hits, not a confinement violation. Fixing c'sclass_startchanged files in
python/numpy,lua/redis,scheme/racket,cobol/gnucobol_internals, andcpp/godot
(specificallyobject.h, whose engine-assignedLanguagefield is explicitly"C"via
sibling-file disambiguation, even though the repo's folder-dominant language is cpp) — repos
whose PRIMARY corpus label is a different language entirely. The structural-diff check
(recurring class 25) correctly flagged these as changed; the next step is to verify EVERY
changed file within those repos is actually a.c/.hfile genuinely classified as C (check
the file's own"1. Artifact Identity" -> "Language"field, not just its extension or the
repo's folder label), not a file in the repo's nominal language. A real confinement violation
would show up as a change to a.py/.lua/.rkt/.cobfile withLanguage!="C". -
(new, from Extraction hardening: c #822) Recurring class 3 (unshielded content reaching a Mode-B rule) can manifest
via COMMENTS instead of strings, and some languages are structurally immune to the
string-literal variant. C has no raw-string syntax, and every C string-literal content
line necessarily starts with a literal"character (blocking^[ \t]*from ever reaching
function-shaped text) -- so the string-literal false positive confirmed on 6 other languages
does NOT reproduce for C via strings. It DOES reproduce via un-decorated block-comment
continuation lines (/*\nint Foo() {\n*/, no leading*marker -- a common real
commented-out-code style). Check the actual line-layout of BOTH a language's string syntax
and its comment syntax independently rather than assuming "no raw strings" means "immune to
class 3" -- and record a confirmed-safe negative result explicitly (not silently) so a future
pass doesn't re-verify it from scratch. -
(new, from Extraction hardening: c #822) ALWAYS grep
test_language_standards_strict.pyfor the rule you're about
to change before treating a permissive match as a bug — it may be intentional, tested, and
documented. A first version of the cclass_startfix required a trailing{to eliminate
what looked like an obvious false positive (struct foo_ops ops;, a variable declaration
matching as a "class start"). This broketest_c_intentional_double_classification_sweep,
which explicitly documents that exact payload matching class_start ("any struct declaration")
as DELIBERATE — it's designed to co-fire with thedependency_injectionrule's
_ops-vtable-suffix heuristic. The trailing-{requirement was reverted, keeping only the
(uncontested, purely additive) optional-tag-name fix for anonymous typedef structs. The
general lesson: this repo has an entire test file (test_language_standards_strict.py)
dedicated to documenting cross-rule ambiguity and intentional double-classification as
first-class, tested behavior — before "fixing" what looks like an obviously-wrong match, grep
that file for the payload shape first. The full pytest suite (already a required step) DOES
catch this, as it did here before the PR was opened — but checking proactively is cheaper than
discovering it via a red test after the fact. -
(new, from Extraction hardening: kotlin #823) When adding an optional-name alternative to fix a missing declaration
shape, scope it NARROWLY to that exact shape rather than making an existing branch's name
optional broadly. kotlin'scompanion object { ... }(almost always anonymous) never
matchedclass_startat all. The tempting fix — making the general
class|interface|object|enum classbranch's name optional — would have opened a NEW false
positive on object EXPRESSIONS (object : Base() {, an anonymous object literal used inline,
a different construct from an object declaration). Instead, added a dedicated alternative
scoped to the literalcompanion[ \t\n]+objectshape with its own optional name, leaving the
general branch's mandatory-name requirement untouched. When a missing-case fix would need to
make a shared branch more permissive, check whether a narrowly-scoped new alternative achieves
the same fix without loosening anything else — the same discipline as recurring class 6/22's
generic step-overs, but for optional-vs-mandatory captures instead of nesting depth. -
(new, from Extraction hardening: kotlin #823) Recurring class 3 confirmed on a SEVENTH language (kotlin, via triple-quoted
raw strings) — same shape as js/ts/java/go/rust/csharp/cpp, no new nuance, just another
confirming data point strengthening the case for the_slice_by_braces-broadening follow-up. -
(new, from Extraction hardening: swift #824) The Rule-11 nested-generic-bound bug has now been a NEW confirmed finding in
7 of the 9 languages checked so far that have any generics-like syntax (java, typescript, go,
python, rust, csharp, kotlin — swift makes it 7, counting go's "generics unsupported at all"
as the same underlying gap family). The two exceptions: cpp was found to already be immune
(its func_start/class_start already carried the one-level-nesting idiom from a pass predating
this epic — only args needed it, per Extraction hardening: cpp #821), and c has no generics at all. At this point the
prior default ("assume clean until proven otherwise") should flip: assume any new language's
generic-parameter step-over has this bug until empirically disproven, and check it as literally
the first thing for any future generics-capable language. swift's variant was specifically
triggered by Swift 5.7+ primary associated type constraints
(func foo<T: Collection<Int>>(x: T) {) — a different concrete syntax shape than java's inline
bounds or python's PEP 695, but the exact same flat-<[^>]*>root cause and fix. -
(new, from Extraction hardening: swift #824) Recurring class 3 confirmed on an EIGHTH language (swift, via BOTH
triple-quoted multi-line strings and#"..."#raw string literals — two distinct string forms
reproducing the same architectural gap in one language). -
(new, from Extraction hardening: scala #825) The Rule-16 identifier-grammar gap (doc's "Identifier Capture Classes Must
Match the Language's Real Grammar" rule) showed up as a genuine cross-language finding, not
just a Scheme-specific curiosity. Scala'sfunc_start/argsname capture required a plain
[a-zA-Z_]\w*, so any backtick-quoted arbitrary identifier (Scala's escape hatch for
reserved-word/space-containing method names, e.g. Java-interop or ScalaTest-style spec names
likedef `should handle edge cases`(): Unit = {}) never matched at all. Fixed as an
alternative capture group (not a widened class), resolved downstream viamatch.lastindex--
infrastructure the pipeline already had for exactly this shape (see java's(init)| (constructor)groups). Kotlin has the identical backtick-identifier grammar and the
identical gap, missed during Extraction hardening: kotlin #823's pass (backtick wasn't on that pass's checklist yet) --
filed as a dedicated follow-up rather than reopening Extraction hardening: kotlin #823. -
(new, from Extraction hardening: scala #825) A
_dependency_capturerule with NO statement-boundary logic at all (not
just a character-class gap like recurring class 19) can silently merge multiple real import
statements into one garbage capture. Scala's capture was a single flat
[\w.{}\s,]+class with no anchor stopping it at the end of one logical import -- since
\smatches newlines, on a realistic multi-import file it kept consuming across the SECOND
importline and into the following unrelated statement, so the second import was never
separately detected.crucible_check.pyagainst the real Kafka scala corpus confirmed the
severity empirically: several files' detected upstream-dependency counts roughly DOUBLED once
fixed (e.g. one file's direct-upstream count jumped 24 -> 53). Fixed via a properly bounded
segmented-dotted-path grammar (repeatidentifier.segments, then end on either a{...}
block or a bare trailing identifier/wildcard) instead of widening the flat class further --
check any_dependency_capturerule using a bare\s(rather than a real statement boundary)
for this same bleed-over risk, not just for missing symbols. -
(new, from Extraction hardening: scala #825) A confirmed real bug's
crucible_check.pydiff can legitimately ripple into
completely unrelated languages/repos, and that's NOT a confinement violation by itself --
check whether the ripple is confined to GLOBAL/cross-repo metrics. Fixing scala's
_dependency_capturebleed-over (recurring class 34) changed the shared cross-repo dependency
DAG's topology (the whole corpus is scanned as one graph, pernetwork_risk_sensor.py's
PageRank/blast-radius scoring andspatial_mapper.py's 3D projection), which shifted
Topological Coordinates, PageRank-derived blast-radius counts, and corpus-relative percentile
metrics for files in 9 completely unrelated language/repo pairs (php/laravel_core,
zig/zls, ruby/rails, yaml/ansible, rust/wasmtime, python/cython, assembly/hellosilicon,
css/odoo, css/element) plus global ecosystem-summary aggregates (network_macro modularity/
assortativity/articulation_points, ecosystem composition/health). Verified genuine (not a
confinement violation) by confirming EVERY one of those other-language diffs was one of these
global/derived metric types -- never a raw per-file signature count (function/args/class/
dependency detection) for a file in a language whose rules weren't touched. When a fix touches
_dependency_capture(which feeds the cross-repo graph, unlike the other three per-file-scoped
rules), expect and check for this shape of ripple specifically, rather than assuming any
non-target-language diff line is automatically a confinement bug. -
(new, from Extraction hardening: powershell #834) Rule 11 also manifests for a flat PARENTHESES-wrapped parameter/argument
list, not just generic type parameters. PowerShell'sargsrule (param(...)andfunction NAME(...)) used the flat\([^)]*\), truncating at the FIRST)-- breaking on a
default-value expression containing its own parens/array-subexpression syntax
(param($Tag = @('Slow', 'Feature')), a realistic, common idiom). Confirmed severity via
crucible_check.pyagainst the real corpus: a well-known PowerShell Core file's detected
parameter count for one function jumped 3 -> 9 once fixed. Same fix idiom as every other Rule-11
instance (\((?:[^()]|\([^()]*\))*\)), just the paren-list variant instead of angle/square
generics -- check any flat\([^)]*\)parameter-list rule for this, not just generic-bracket
rules. -
(new, from Extraction hardening: powershell #834) Adding coverage for a bare, unprefixed declaration shape
(Identifier(params) { body }, no keyword, no return-type marker -- PowerShell class
constructors) WILL collide with that same language's own control-flow statement shape
(if/while/switch/for/foreach (cond) { body }), since they're textually identical to a flat
regex. A negative-lookahead keyword exclusion is required alongside the new alternative.
Caught here by hand-testing the fix's own "invalid" case immediately after writing it (not by
crucible_check.py) -- the same "a new alternative can open its own blind spot" lesson as
recurring class 21, but at authoring time via manual verification rather than via a corpus diff.
Check for this collision risk BEFORE shipping any bare-identifier-plus-body alternative in a
C-family-control-flow language, not after. -
(new, from Extraction hardening: powershell #834) A modifier/scope prefix attached to an identifier via a delimiter can make a
capture group swallow the PREFIX instead of the real name -- silently wrong data, not just a
non-match, and easy to miss in review. PowerShell's scope qualifiers (global:/script:/
local:/private:before a function name, e.g.function global:Foo {}) aren't in the
identifier character class, so the capture stopped at the delimiter and returned the scope
keyword itself (e.g. "global") as if it were the function name. Same root shape as Rule 16
(identifier grammar) but the failure mode -- confidently wrong output vs. a safe non-match -- is
worse and doesn't show up as a dramatic test failure the way a non-match does. -
(new, from Extraction hardening: powershell #834) An "optional quote pair" idiom (
['"]?...['"]?) around a capture class
that excludes whitespace is a DIFFERENT bug shape from recurring class 19 (a missing symbol) --
it truncates any quoted value containing that excluded symbol even though quoting should have
protected it. PowerShell's_dependency_captureused exactly this shape, so a quoted path
containing a space ('C:\Program Files\MyModule\MyModule.psd1', an extremely common Windows
idiom) silently truncated at the first space. Fix: real per-quote-style alternatives (a quoted
branch permitting the excluded symbol inside real quotes, a separate bare/unquoted branch that
still excludes it), not just widening the shared class -- widening it would also re-break the
original over-capture problem the optional-quote shape was trying to avoid. -
**(new, from Extraction hardening: powershell #834)
_dependency_capture's comment-lookalike vulnerability (recurring class 3's
shape) is NOT universal -- confirmed a SECOND language (powershell, after c's Extraction hardening: c #822 finding,
recurring class 27) where the rule's own^[ \t]*anchor structurally blocks a comment marker
(here,#) from ever reaching the keyword. But the SAME rule instance in the SAME language can
still be vulnerable via a DIFFERENT unshielded-content vector: PowerShell here-strings
(@"..."@) land their inner content at true line start with no blocking marker, so
import-shaped text inside one still produces a phantom dependency edge. Check comment- and
string-literal vectors independently per language/rule -- confirmed immunity to one vector
doesn't imply immunity to the other. -
(new, from Extraction hardening: yaml #843) A "block requires an immediate newline after its header key" idiom
(with:[ \t]*\n...) breaks on a trailing same-line comment on the header itself
(with: # inputs for this action\n node-version: '18'), a real CI-YAML authoring style.
Same general shape as recurring classes 5/6 (an unaccounted-for optional element between two
required tokens) but for a block-header-to-body transition specifically, in a YAML/CI-config
context rather than a code-language declaration. Fix: allow an optional(?:#.*)?before the
newline. Check any language/rule with a "header line, then indented body" shape for the same
gap if that language's comment marker can appear on the header line. -
(new, from Extraction hardening: yaml #843) A "declaration name, then immediately the thing we care about" shape can be
too strict when real usage inserts OTHER keys/statements in between -- not just a nesting
problem (Rule 11), a SEQUENCING problem. YAML'sclass_startrequireduses:/image:to be
the LITERAL FIRST line after a job name, but real reusable-workflow-call/container jobs
routinely haveneeds:/if:/permissions:etc. first. Fixed with a BOUNDED (max 10) step-over
for intervening key:value lines -- bounded specifically so it can't bleed across into an
unrelated subsequent job's own content once nouses:/image:is found. This is a different
root shape from Rule 11 (which is about a delimiter/bracket's own CONTENT nesting) -- here the
gap is between two SIBLING lines/statements, not inside one expression. Check for this shape
whenever a rule assumes its target keyword is the immediate next line/token after an anchor,
when the real language allows other optional statements in between. -
(new, from Extraction hardening: yaml #843) An "optional-quote" idiom can ALSO be missing entirely (not just shaped
wrong, per recurring class 39's finding for PowerShell) -- and the fix for two structurally
identical rules (importand_dependency_capturesharing nearly the same pattern) only needs
applying to the one that's actually in the four-gauntlet scope. YAML's_dependency_capture
had NO quote-tolerance at all foruses:/image:values (unlike PowerShell's rule, which HAD
quote tolerance but with the wrong shape) -- a quoted value (uses: "actions/checkout@v4", a
real yamllint-driven authoring style) never matched. Fixed with the same real
per-quote-style-alternative idiom as Extraction hardening: powershell #834's fix, applied fresh here rather than adapted from a
broken shape.import(a sibling, non-gauntlet-scoped rule with nearly the same pattern) was
deliberately left unfixed -- out of the four-gauntlet scope for this issue, not overlooked. -
(new, from Extraction hardening: shell #835) A rule scoped to "this token in its bare/simple form" can miss the
language's own DEFAULT-VALUE or FALLBACK-EXPRESSION variant of that exact same token, even
though the fallback variant is arguably the more common real-world shape. Shell'sargsrule
matched a bare positional parameter ($1) and a simple braced form (${1}/${10}) but had no
allowance for bash's:-/:=/:?/:+default-value/error-message/assign/alternate operators
(${1:-default}) -- arguably THE most common way a positional parameter actually appears in
real scripts, entirely invisible to the rule. Confirmed viacrucible_check.py's real diff (one
real Homebrew script's detected parameter count jumped 6 -> 10). Fix: an optional
:[-=?+](?:[^{}]|\{[^{}]*\})*suffix using the established one-level-nesting-safe idiom
(recurring class 1's paren/bracket/angle-bracket idiom, here applied to braces), so a nested
default (${1:-${DEFAULT:-x}}) is captured in full. Check any language/rule whose scope is "a
named reference in its simple form" for the same gap if that language has a fallback/default
expression syntax built around the identical token. -
(new, from Extraction hardening: shell #835) A keyword-exclusion lookahead guarding a bare-call-shaped alternative can be
INCOMPLETE relative to the language's own full reserved-word set, not just wrong in shape (a
generalization of recurring class 7's bare-call-ambiguity class specifically for the exclusion
list's own coverage). Shell'sfunc_startexcluded only 5 of bash's ~17 word-based reserved
words (if/while/for/case/until) from its POSIXname()branch --done() {,
elif() {,select() {,function() {, etc. all falsely matched as function definitions.
None of these are valid bash (a reserved word can't legally be a POSIX function name -- the real
parser errors on it), but this is a regex-only engine scanning arbitrary/malformed text, so the
same defensive intent behind the original partial list applies equally to the rest. Fix: widen
the exclusion to the full reserved-word set. Check any keyword-exclusion lookahead for
completeness against the language's ACTUAL full reserved-word list, not just the handful that
happened to be top-of-mind when the rule was first written. -
(new, from Extraction hardening: makefile #844) An assignment-operator lookalike can hide behind a rule's own declaration
delimiter when that delimiter is a PREFIX of the assignment operator's own spelling. Make's
func_starttreated any bare:/::as a real target-defining colon, with no exclusion for an
immediately-following=-- soMY_VAR := valueandMY_VAR ::= value(GNU Make's own
immediate-expansion assignment operators, arguably THE most common modern Make idiom) were both
misidentified as target declarations, since:=/::=both START with the exact colon shape the
rule was watching for. Fix: a negative lookahead so the colon(s) can't be immediately followed by
=. Check any declaration-boundary rule (:,::, or similar) in a language that ALSO uses that
same character as a prefix of one of its own assignment/operator tokens. -
(new, from Extraction hardening: makefile #844) Widening a rule to accept a real multi-token shape (here: multiple
space-separated target names before one shared colon) can reopen an unrelated false-positive
vector purely by giving the match "more license to keep looking" past the first token --
independent of whatever the widening was actually trying to fix. Make'sfunc_startgained
multi-target support (a b c: dep), but this let a RECIPE line's later words (a URL's://, a
bare time value10:30) get treated as trailing co-target tokens followed by a real
target-defining colon. The fix wasn't to narrow the widening itself -- it was to exclude the
entire false-positive vector's PRECONDITION: recipe lines are unconditionally tab-initial in
Make's own lexical rules (never a directive, absent a custom .RECIPEPREFIX), so narrowing the
rule's leading-whitespace class from "spaces or tabs" to "spaces only" structurally blocks every
recipe line from ever reaching the widened path, without constraining the widening's own logic.
When widening a rule to accept more of a real shape, re-run the FULL invalid/pathological tier
afterward, not just the new cases being added -- a widening can regress unrelated existing
coverage in ways the new cases alone won't surface. -
(new, from Extraction hardening: makefile #844) A language's own escaping convention for its trigger character can produce a
lookalike that's structurally indistinguishable from a real reference without checking what
precedes the trigger. Make'sargsrule matched any$followed by a digit/(digit)/call,
but Make's$$(a doubled$) is the language's OWN escape sequence for "a literal$,
unescaped, for whatever consumes this text next" -- extremely common in recipe lines
specifically to pass a literal$1/$@/etc. through to the SHELL, unrelated to Make's own
macro-call mechanism (since Make's own$expansion already happened one layer up by the time
the shell sees it). Fix: a negative lookbehind so the trigger$can't itself be immediately
preceded by another$. Check any rule whose trigger character is ALSO the language's own
escape-doubling character for a lookalike this exact shape. -
(new, from Extraction hardening: cobol #854) A declaration paragraph's grammar can have real, standard trailing clauses
that the rule's "name then immediately the terminator" lookahead has no allowance for at
all -- not a nesting problem (Rule 11), not a sequencing problem (recurring class 42), but a
missing OPTIONAL-SUFFIX-GRAMMAR problem. COBOL'sclass_startrequired the entity name to be
immediately followed by a period/newline/EOS, with zero allowance forPROGRAM-ID. Foo IS INITIAL PROGRAM.,CLASS-ID. Foo FINAL.,CLASS-ID. Foo INHERITS Base.,INTERFACE-ID. Foo INHERITS Base.-- all real, standard Enterprise COBOL syntax, entirely invisible. Fix: a
bounded (max 6) run of additional clause words between the name and the terminator, safe
because the loop requires whitespace before each word and a bare period always stops it at the
real statement boundary. Check any name-then-terminator rule against the FULL declaration
grammar (not just the bare/minimal form) for optional trailing clauses. -
(new, from Extraction hardening: cobol #854) Widening a rule's trailing-content allowance can resurrect a SPECIFIC prior
finding for a DIFFERENT keyword sharing the same alternation -- not a generic regression, a
targeted one tied to which keywords the widened rule covers. Recurring class 49's own fix
(widening COBOL'sclass_startto accept trailing clause words) reopened a false-positive
vector for two OTHER keywords in the SAME alternation (FACTORY./OBJECT., standalone
OO-COBOL markers that are ALWAYS immediately followed by a division header, never a real
trailing clause) -- with the loop now wide enough to eat one extra word, "IDENTIFICATION"/
"PROCEDURE" got miscaptured as the entity name and "DIVISION" got swallowed as if it were a
clause word. Fixed by excluding "DIVISION" from the trailing-clause loop specifically (no real
PROGRAM-ID/CLASS-ID/INTERFACE-ID clause legitimately contains that word). When a rule's
alternation covers MULTIPLE distinct keywords, check whether a widening meant for SOME of them
changes behavior for the OTHERS -- caught here by a same-PR regression test written specifically
to confirm the pre-fix "this doesn't happen" assumption, which then failed once the fix landed. -
(new, from Extraction hardening: cobol #854) A parameter-list rule with two clause-introducing keywords sharing the same
identifier-name alternative can have one clause's capture bleed straight through the OTHER
clause's own keyword and swallow its parameter too. COBOL'sargsrule captured USING's
parameter list as(?:[A-Z0-9_-]+...)*, with no exclusion for the literal word "RETURNING" --
since "RETURNING" is itself composed of uppercase letters, it satisfied the SAME identifier
alternative used for real parameter names, soPROCEDURE DIVISION USING WS-A RETURNING WS-B.
(declaring both a parameter AND a return value in one header, extremely common) had USING's own
match swallow "RETURNING WS-B" whole instead of stopping at the clause boundary. Fix: a
negative lookahead excluding the OTHER clause-introducing keyword from the parameter-name
alternative. Check any rule with two-or-more sibling clause keywords sharing one identifier-
capture alternative for this exact bleed-through shape. -
(new, from Extraction hardening: sqlite #836) A qualifier/namespace prefix using a delimiter OUTSIDE the identifier's own
character class makes the qualified form invisible, with no partial/fallback capture --
distinct from Rule 11 (that's about NESTING within one delimiter pair, this is about a PREFIX
using a different delimiter entirely). SQLite'sfunc_start/class_starthad no allowance
for a schema-qualified name (CREATE TABLE main.users (...),CREATE TRIGGER main.my_trigger ...-- standard syntax for ATTACHed databases or explicittemp.targeting). Since\wnever
spans a literal., the pattern couldn't capture "main.users" as one token and had no way to
skip the qualifier and capture just the real name -- the whole match failed outright, not even a
truncated capture. Fix: an optional(?:[a-zA-Z_]\w*\.)?qualifier-skip immediately before the
capture. Check any declaration rule in a language with namespace/schema/module qualifiers
(a.b,a::b,a->b) for this exact gap. -
(new, from Extraction hardening: sqlite #836) A rule scoped to bare identifiers can have ZERO allowance for the language's
OWN native identifier-quoting mechanism -- and quoting to avoid a reserved-word collision (the
single most common real reason to quote at all) means even a completely unremarkable,
special-character-free name is invisible. SQLite'sfunc_start/class_starthad no support
for any of its three quoted-identifier styles ("name",`name`,[name]) -- so
CREATE VIEW "group" AS ...(quoting only because "group" collides with a keyword) failed
outright, same as a name containing a genuinely special character (a space). Fix: added the
three quoted forms as alternatives inside the SAME capture group (quotes included in the
captured text, verified harmless since the harness/consumer both do substring/membership
checks) rather than new numbered groups -- critical here because detector.py reserves capture
group 2 specifically for class_start's inheritance-parent extraction on other languages; adding
real new groups would have silently shifted that convention. Check any declaration rule in a
language with native identifier quoting for this exact gap, and prefer widening the SAME group
over adding new ones for any rule where group position carries meaning elsewhere in the engine. -
(new, from Extraction hardening: sqlite #836) Rule 11's nested-delimiter shape, reconfirmed for SQL specifically: a flat
\([^)]{0,N}\)inside an IN/VALUES clause truncates at the first closing paren of a nested
subquery.IN (SELECT id FROM (SELECT id FROM other))(a real, common nested-subquery
pattern) silently ended the match one paren early instead of covering the whole clause. Same
fix as every other language in this epic: the one-level-nesting-safe idiom, bounded on both the
inner and outer repetition. -
(new, from Extraction hardening: sqlite #836) An alternative's anchor can be far NARROWER than the dominant real-world
form -- not wrong in character class or nesting, but scoped to the WRONG position in the
statement. SQLite'sargsCTE alternative required the CTE name at TRUE line start, but the
single most common way to write a CTE is inline, immediately after theWITHkeyword on the
SAME line (WITH cte_name (col1, col2) AS (...)) -- never matched at all. Fix: added a second
anchor alternative (immediately afterWITH/WITH RECURSIVE) alongside the original line-start
one, without introducing a new capture group (this rule has zero groups by design -- every
alternative is checked via whole-match substring). Check any rule anchored to "start of
statement" for whether the dominant real-world form actually places the target token
mid-statement, right after a specific keyword, instead. -
(new, from Extraction hardening: sqlite #836) A historical vertical-whitespace fix applied to one rule is not automatically
applied to a SIBLING rule sharing near-identical optional-clause structure, even in the SAME
language file. SQLite'sfunc_startalready has a documented "VERTICAL MODIFIER SHIELD" fix
for its ownIF NOT EXISTSclause (using[ \t\n]+throughout, including the gap right before
the captured name).class_start's OWN parallelIF NOT EXISTSclause (forCREATE TABLE)
was never given the same fix -- its trailing gap stayed[ \t]+(no newline), soCREATE TABLE IF NOT EXISTS\n users (...)(a real, common vertical formatting style) silently captured
"IF" as the table name instead of "users". Found via this issue's OWN pathological test case,
not a pre-flagged finding. Check every rule in a language file against fixes already applied to
its OWN siblings, not just fixes documented for OTHER languages. -
(new, from Extraction hardening: sqlite #836) A test that hardcodes a capture-group INDEX for a multi-alternative rule is
fragile to legitimate future restructuring, even when the real consumer never cared about the
index in the first place.test_sqlite_dependency_capture_extracts_pathasserted
m.group(2) == "json1"for load_extension specifically -- correct under the OLD numbering, but
recurring class 53's fix (splitting ATTACH's own capture into 3 quote-style sub-groups) shifted
load_extension's group from 2 to 4, breaking the test even though the actual dependency-path
extraction was completely correct. galaxyscope.py's own consumer already readsnext((g for g in match.groups() if g), None)-- "the path is in SOME group" -- not a hardcoded index. Updated
the test to match that same convention instead of re-hardcoding a new number, so the NEXT
legitimate restructuring won't break it again. Write new tests for multi-alternative,
multi-group rules the same way from the start. -
(new, from Extraction hardening: agc_assembly #857) An opcode/keyword whitelist can be an unvalidated ad hoc SUBSET of the real
language's instruction set, inconsistent with what SIBLING rules in the SAME language file
already recognize as legitimate. AGC assembly'sfunc_startwhitelisted only 16 opcodes,
missing ~25 real, common instructions this SAME file's ownbranch/args/safety/
state_mutationrules already recognized (CAF,TCF,XCH,LXCH,AD,MASK,INCR,
RELINT, etc.) -- confirmed empirically against the real Apollo 11 corpus that the old
whitelist missed roughly 33% of real label+opcode pairs, withCAF(94 occurrences) among the
single most common AGC instructions entirely absent. Check every keyword/opcode whitelist
against the UNION of what its OWN sibling rules in the same file already treat as legitimate,
not just against general outside knowledge of the language -- internal inconsistency within one
file is a strong, cheap signal of an incomplete list. -
(new, from Extraction hardening: agc_assembly #857) Empirical corpus cross-validation (grep the real corpus, count matches
before/after a candidate fix) is the ONLY way to catch an "incomplete whitelist" class of bug --
self-consistent regex testing cannot, because the test cases are themselves typically derived by
observing the regex's OWN (possibly buggy) behavior, not the real language's ground truth.
Every other recurring class in this epic is a shape/structure bug findable by constructing an
adversarial payload and checking the regex's behavior in isolation; this class requires stepping
outside the regex entirely and asking "how much of the REAL corpus does this actually match, and
does that number make sense" -- a 40% miss rate against real source was invisible to 136 unit
tests that all only checked internal consistency, but obvious the moment the corpus was queried. -
(new, from Extraction hardening: agc_assembly #857) AI-authored test coverage can enshrine EXISTING (buggy) behavior as
"correct" without ever validating it against the real language's grammar or corpus -- an
"invalid" test case can literally BE the bug, framed as if it were an intentional exclusion.
A prior PR's test suite (agc_assembly, claimed "zero bugs found, patterns already extremely
robust") included"MYLABEL\tTCF INTERNAL"in itsinvalidlist with the comment "TCF is not
in the opcode list" -- true of the code as written, false of real AGC assembly, where TCF is one
of the most common branch instructions. The suite was internally consistent and thorough in
breadth (136 tests, all four tiers, real whitespace/pathological variety) but never once
checked whether the thing being tested was actually correct against ground truth -- it treated
"matches the current regex's behavior" as the definition of "valid" test coverage. When
reviewing (or writing) test coverage for a language rule you have not independently corpus-
validated, do not trust that "all tests pass, zero bugs found" means the underlying rule is
correct -- it only means the tests agree with whatever the code already does. Cross-check
"invalid" cases specifically against real spec/corpus before accepting them, since those are
exactly where an existing bug hides in plain sight as a passing assertion. -
(new, from Extraction hardening: assembly #856) A register/opcode alternative can simultaneously match a FICTIONAL form and
miss the REAL one, when a trailing\bis assumed to separate a base token from a suffix that is
itself a word character. Assembly'sargsrule used[er][89]intending to extendr8/r9
coverage, bute8/e9are not real x86 registers -- the pattern actually matched a phantom
register while\bafter[89]silently prevented the REALr8d/r9d/r8w/r9w/r8b/r9b
sub-register forms from ever matching (the digit and the following size-suffix letter are both
word characters, so no boundary exists between them). The original PR's own test suite enshrined
the phantom form asvalid(("mov e8, 5", "e8")) -- another concrete instance of recurring
class 60. Fixed tor[89][dwb]?, and separately closed a real coverage gap this review also
found: assembly's own_meta.target_versionexplicitly states "Backwards Compatible", yetargs
had zero support for the legacy 8/16-bit x86 register set (ax/al/ah/bx/bl/bh/etc.)
that real 16-bit real-mode code (the corpus'sbootosbootloader) uses as its de facto argument-
coupling convention. When a suffix-bearing alternative sits next to a bare base form in the same
alternation, check both directions empirically: does it match text that isn't a real register,
and does it fail to match the real suffixed forms it was presumably added FOR. -
(new, from Extraction hardening: assembly #856) A corpus-impact quantification (
OLD.finditervsNEW.finditermatch counts,
the pattern established in classes 58-59) must run against the pipeline's actual comment-stripped
code_stream(viaPrism.split_streams), not raw file text, or the "before/after" number can be
substantially inflated by matches that would never reach the rule in production. Assembly's
argsfix looked like a +391% improvement (135->663) against raw file text, but a large share of
the new matches were inside;-prefixed prose comments describing ABI/BIOS calling conventions
(e.g. "AL = ASCII key pressed", "Affects: AH/BX/BP") -- English technical prose naturally contains
short register-name-shaped tokens at a much higher rate than, say, SQL or COBOL comments contain
SQL/COBOL-keyword-shaped tokens, so this risk is language-dependent and easy to miss if it hasn't
bitten you yet. Re-running the same quantification through the realPrismpipeline (which strips
;/#line comments for any"lexical_family": "line_exclusive"language beforedetector.py
ever sees the code) gave the honest number: 84->305 (+263%), still a large genuine improvement,
concentrated in exactly the 16-bit bootloader code the fix targeted -- confirmed clean by manually
inspecting a sample of the new matches' containing lines. A large raw-text delta is a hypothesis
to verify against the real pipeline, not a number to report as-is.
Related architectural issue filed from this epic's verification work
- prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859 (FIXED, PR Fix/859 php docblock corruption #864):
prism.py's comment/string stripping corruptedcode_streamfor at
least two real PHP corpus files (docblock text bleeding through mangled) — root cause was a
brokenPHP_MULTILINE_STRINGextraction step, now removed entirely. Found while verifying the
shared_slice_by_bracesstring-shielding fix below, which was deliberately gated to
javascript/typescript only at the time. Now that prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859 is fixed, broadening that gate to other
Mode B languages is unblocked — worth its own follow-up PR (confirm no other language has a
similar latentprism.pygap first viacrucible_check.py, don't just flip the gate open).
Tooling built during this epic (use these, don't rebuild them)
tests/extraction/tools/verify_candidates.py— reusable empirical-verification harness
(check_case/check_many/check_redos_scaling+ a CLI) for the methodology's "verify every
candidate case before adding it" step. Replaces writing a throwaway checker script per language.tests/tools/audit_check.py— bundlesruff format --check+ruff_audit.py --ci+
mypy_audit.py --ci+dead_key_audit.py --ciinto one command, with automatic pure-line-shift
detection (--regenerateauto-fixes baselines whose new findings are ALL shifts; anything
genuine is left for manual review, never silently accepted).tests/tools/crucible_check.py --update --yesalready existed and does the full two-venv golden-
master regeneration in one call — no need to hand-build/activate venvs; several early sub-issues
in this epic did that manually before this was noticed, wasting real tokens each time.
Progress
-
javascript— the shared string-literal false positive fixed earlier (PR Fix javascript/typescript func_start string-literal false positive #860, gated to
js/ts; broadening now unblocked by prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859, see above). Extraction hardening: javascript #814 itself (this sub-issue's own
valid/invalid/pathological case expansion) closed with 1 additional real bug fixed:
func_start/argshad no allowance for ES6 generator method shorthand (*foo() {},
async *foo() {},static *foo() {}) — completely invisible before the fix. The FIRST
version of that fix introduced a NEW false positive (JSDoc comment prose hallucinated as a
generator method), caught viacrucible_check.pyagainst real corpus code and corrected —
see recurring class 21 above for the full story and the general lesson.crucible_check.py
showed a zero diff after the corrected fix (expected — zero generator-method usage anywhere
in the ~80-repo JS corpus, confirmed by grep). 2 known limitations documented, not fixed:
bare-call ambiguity (same as every C-family/JS-family language) and the star-to-name
whitespace intolerance (deliberate, not a gap — see recurring class 21). -
typescript— closed via Extraction hardening: typescript #815, 3 real bugs fixed (type-alias false positive, typed-arrow-
assignment gap, class_start nested-generic-extends bug), 1 gap fixed (_dependency_capture
side-effect-only imports), 2 known limitations documented (bare-call ambiguity, 2+-level
generic nesting / type-annotation-with-own-arrow) -
java— closed via Extraction hardening: java #816, 3 real bugs fixed:func_start/argsshared the flat<[^>]*>
Rule-11 bug (one-level-nested generic bounds, e.g.public static <T, U extends Comparable<U>> T Foo(T a, U b) {, broke both rules identically since they share the same
modifier-alternative shape);class_starthad no generic step-over at all before its
extends/implements check (worse variant of the same bug class, see recurring class 9 above).
Verified confined to java viacrucible_check.py(restored detection of a real
findPluginIdForClassmethod in gradle'sDefaultPluginManager.java, the corpus's only
diff). 2 known limitations documented, not fixed (architectural, out of scope for a single
language):func_starttext-block false positive (recurring class 3, confirmed on a second
language) and_dependency_capture's broader unshielded-content_buffergap (new recurring
class 10). -
go— closed via Extraction hardening: go #817, 1 real bug fixed:func_starthad no generic type-parameter
step-over for plain (receiverless) top-level functions, so Go 1.18+ generics
(func Foo[T constraints.Ordered](a, b T) T {, mainstream since 2022) were completely
invisible. Notablyclass_startandargsalready had the correct step-over — only
func_startwas the outlier (see recurring class 13 above; don't assume a generics gap in
one rule implies the same gap in all four). Verified confined to go viacrucible_check.py
(restored detection of a realTypeAssert[T any]generic function in a corpus file,
the only diff). 2 known limitations documented, not fixed (architectural): raw-string-literal
false positive for bothfunc_startand_dependency_capture(recurring class 3, now
confirmed on a third language/feature — see recurring class 14 above). -
python— closed via Extraction hardening: python #818, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding):
func_start/args/class_startall shared a flat[^\]]*PEP 695 (3.12+) generic-parameter
step-over, breaking any nested-bracket type bound (def Foo[T: Sequence[int]](x: T) -> T:) --
the square-bracket variant of the same Rule-11 bug class (recurring class 15 above);
class_startsilently lost its base-class capture rather than failing outright, same failure
shape as java's Extraction hardening: java #816 bug.crucible_check.pyshowed a zero diff (expected -- PEP 695 has zero
real-world adoption in the ~80-repo corpus yet, confirmed by grep), so verification relied
entirely on the regex-level empirical checks + ReDoS sweeps. Also confirmed a genuinely
positive finding: python's Mode C (_slice_by_indentation) already shields
strings/comments before matching -- unlike Mode B, there is NO live string-literal false-
positive bug for python in the real pipeline (recurring class 16 above; this is the reference
implementation the eventual Mode-B broadening should mirror). 1 known limitation documented,
not fixed:_dependency_capture's unshielded-content_buffergap (recurring class 10, same
as every other language). -
rust— closed via Extraction hardening: rust #819, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):
argsnever received the two-level-nesting Rule-11 fix thatfunc_startalready had from an
earlier pass (see recurring class 18 above) — broke on any nested trait bound
(fn Foo<T: Into<String>>(x: T) {);_dependency_capture's character class was missing*,
so every glob import (use std::io::*;,use super::*;) produced zero dependency-graph
edges (recurring class 19 above). Verified confined to rust viacrucible_check.py(4 real
corpus files across 2 repos gained newly-detected glob-import dependency edges, e.g. one
file's detected-dependency count jumped 1 → 5; no other language/file affected). 1 known
limitation documented, not fixed: raw-string-literal false positive forfunc_start/
_dependency_capture(recurring class 3, now confirmed on a fourth language/feature —
recurring class 20 above). -
csharp— closed via Extraction hardening: csharp #820, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding):
class_starthad the same missing-generic-step-over bug already seen in java/python
(recurring class 22 above) —class Foo<T> : Base<T> {silently lost the base-list capture;
also needed a companion primary-constructor-parameter-list step-over
(record Foo<T>(T Value) : Base<T>, C# 9+/12) independently of the generic fix.
_dependency_capturewas entirely missing support for using-alias directives
(using Alias = Target;) — no match at all, not just a dirty capture (recurring class 23
above) — plus the alias target itself needed its own generic-suffix step-over
(using StringList = List<string>;, the primary real-world motivation for alias directives).
Verified confined to csharp viacrucible_check.py(a real Roslyn corpus file gained a
newly-detectedusing InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
alias-directive dependency edge, the only diff). 1 known limitation documented, not fixed:
verbatim-string (@"...") and C# 11+ raw-string-literal false positive for
func_start/_dependency_capture(recurring class 3, now confirmed on a fifth language). -
cpp— closed via Extraction hardening: cpp #821, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):
func_start/argshad zero allowance for a class-qualifier before theoperatorkeyword,
so out-of-line operator overload definitions (TargetClass::operator=(...),
TargetClass::operator==(...), mainstream C++, declared in a header/defined in a .cpp file)
were completely invisible even though bareoperator=(...)already worked — a distinct
failure mode from the recurring Rule-11 nesting bug (recurring class 24 above);argsalso
needed the established nested-template step-over for the method's own template args
(Foo::Bar<Baz<int>>(...)). Verified confined to cpp viacrucible_check.py— 7 real files
across 4 repos (mlir, NVDA, powertoys, godot) gained newly-detected operator functions/
parameter counts, including NVDA'sstorage.cppfunction count jumping 10 → 13 for its 3
out-of-line comparison operators. A structural (not textual-grep) diff check was needed to
correctly confirm confinement here — see recurring class 25 above. 1 known limitation
documented, not fixed: raw-string-literal (R"(...)") false positive forfunc_start
(recurring class 3, now confirmed on a sixth language). class_start's lack of a base-clause
capture group was confirmed to be cpp's original, deliberate design (not a regression of the
java/python/csharp bug) — the existing test suite already only ever asserted the entity name. -
c— closed via Extraction hardening: c #822, 1 real bug fixed inclass_start(a fresh sweep, not a pre-flagged
finding): the struct/union/enum tag name was mandatory, so anonymous typedef'd structs
(typedef struct { ... } Name;, an extremely common real C idiom) never matched at all.
Made the tag name optional. A second, broader change (requiring a trailing{to also
reject bare variable declarations of an existing struct type, e.g.struct Foo instance;)
was tried and reverted — it broketest_c_intentional_double_classification_sweep
(test_language_standards_strict.py), which documents that exact match as deliberate,
intended to co-fire with thedependency_injectionrule's_ops-vtable-suffix heuristic
(recurring class 28 above). Verified viacrucible_check.py(structural diff, not textual
grep — recurring class 25): cpython'sdictobject.cand micropython'sobjtype.ceach
gained a real anonymous/inline-struct detection. The diff also touchedpython/numpy,
lua/redis,scheme/racket,cobol/gnucobol_internals, andcpp/godot'sobject.h
(engine-classifiedLanguage: "C"via sibling-file disambiguation) — all confirmed genuine
embedded C files inside differently-labeled repos, not a confinement violation (recurring
class 26 above). 1 known limitation documented:func_start's Mode-B string-shielding gap
reproduces via un-decorated block comments (not strings — C has no raw strings, and its
per-line-quoted string layout is structurally immune to the string-literal variant, a
genuine negative result — recurring class 27 above). -
kotlin— closed via Extraction hardening: kotlin #823, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):
func_start/argsshared a flat<[^>]{0,100}>Rule-11 generic-parameter step-over,
breaking any nested generic bound (fun <T, U : Comparable<U>> foo(x: T, y: U): T {);
class_starthad no support forcompanion object { ... }(almost always anonymous) at
all — fixed with a narrowly-scoped dedicated alternative rather than loosening the general
branch's mandatory name, which would have opened a new false positive on object expressions
(recurring class 29 above). Checkedtest_language_standards_strict.pyfor intentional
kotlin behavior before finalizing (per c's Extraction hardening: c #822 lesson) — no conflicts found, and the
existingtest_kotlin_ambiguity_sweep_shared_literals_are_not_bugstest continues to pass
unmodified.crucible_check.pyshowed a zero diff (expected — only 5 kotlin files in the
corpus, zero companion objects among them, confirmed by grep). 1 known limitation
documented:func_start's Mode-B string-shielding gap reproduces via triple-quoted raw
strings (recurring class 3, now confirmed on a seventh language — recurring class 30 above). -
swift— closed via Extraction hardening: swift #824, 1 real bug fixed (a fresh sweep, not a pre-flagged finding):
func_start/argsshared a flat<[^>]*>Rule-11 generic-parameter step-over, breaking any
nested generic bound via a Swift 5.7+ primary associated type constraint (func foo<T: Collection<Int>>(x: T) {) — the same bug class now confirmed in 7 of 9 languages
checked (recurring class 31 above). Checkedtest_language_standards_strict.pyfor
intentional swift behavior before finalizing (per c's Extraction hardening: c #822 lesson) — no conflicts; the
existingtest_swift_ambiguity_sweep_shared_literals_are_not_bugstest passes unmodified.
crucible_check.pyshowed a zero diff (expected — only 6 swift files in the corpus, none
using nested generic bounds, confirmed by grep). 1 known limitation documented:
func_start's Mode-B string-shielding gap reproduces via BOTH triple-quoted multi-line
strings and#"..."#raw string literals (recurring class 3, now confirmed on an eighth
language — recurring class 32 above). -
scala— closed via Extraction hardening: scala #825, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding):
func_start/argsshared the flat\[[^\]]*\]Rule-11 square-bracket generic-parameter
step-over (the same bug class already fixed for java/typescript/python/rust/csharp/kotlin/
swift, angle-bracket and square-bracket variants both now confirmed broadly);func_start/
argsalso never accepted backtick-quoted arbitrary identifiers at all (recurring class 33
above -- also filed as a follow-up for kotlin, which shares this gap);_dependency_capture
had no statement-boundary logic and silently merged multiple import statements together plus
truncated Scala 3 wildcard (*) and=>-renamed block imports (recurring class 34 above).
crucible_check.pyshowed a REAL diff this time (not a zero diff) -- confirmed genuine via
the real Kafka scala corpus (several files' detected dependency counts roughly doubled) and
confirmed the ripple into 9 unrelated language/repo pairs was purely global/derived metrics,
not a confinement violation (recurring class 35 above). Golden master fixtures re-blessed.
Checkedtest_language_standards_strict.pyfor intentional scala behavior before finalizing
(per c's Extraction hardening: c #822 lesson) -- no conflicts; existing scala regression tests pass unmodified. 2
known limitations documented:func_start's Mode-B string-shielding gap reproduces via
triple-quoted strings (recurring class 3, now confirmed on a NINTH language);_dependency_ capture's unshielded-content_buffergap reproduces via a commented-out import (recurring
class 10, same pipeline-wide, not-yet-fixed issue as every other language). -
powershell— closed via Extraction hardening: powershell #834, 4 real bugs fixed (a fresh sweep, not a pre-flagged finding):
args/func_startshared the flat\([^)]*\)Rule-11 paren-list step-over, breaking on
default-value expressions containing their own parens (recurring class 36 above -- confirmed
severe viacrucible_check.py, one real corpus function's detected parameter count jumped
3 -> 9); PS class constructors (Foo([string]$name) { ... }, nofunctionkeyword, no
return-type bracket) were entirely invisible toargs/func_start-- added as a new
alternative, which in turn collided with PowerShell's own control-flow statement shape until
a keyword exclusion was added (recurring class 37 above); PowerShell scope-qualified function
names (function global:Foo {}) caused the name capture to silently return the scope keyword
itself instead of the real name (recurring class 38 above);_dependency_capture's
optional-quote-pair idiom truncated any quoted import path containing a space (the common
Windows'C:\Program Files\...'shape, recurring class 39 above). Checked
test_language_standards_strict.pyfor intentional powershell behavior before finalizing (per
c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified.
crucible_check.pyshowed a real diff, confirmed confined entirely topowershell/coreplus
its own aggregate rollups (no cross-repo ripple, unlike scala's Extraction hardening: scala #825_dependency_capturefix
-- this language's fixes didn't materially change the shared dependency graph's topology).
Golden master fixtures re-blessed. 2 known limitations documented:func_start's Mode-B
string-shielding gap reproduces via here-strings (a TENTH language);_dependency_capture
reproduces the same here-string vector independently, while being confirmed STRUCTURALLY
IMMUNE to the comment-lookalike variant (recurring class 40 above -- second language with
this specific negative result, after c). -
yaml— closed via Extraction hardening: yaml #843, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding). Unlike
most languages in this epic, yaml's_meta.target_versionscopes its rules specifically to
CI/CD YAML (GitHub Actions/GitLab CI) -- the four gauntlets map onto a step's run/script block
(func_start), a step'swith:input block (args), a job-block boundary including the
reusable-workflow-call/container-job shape (class_start), and an action/image reference
(_dependency_capture), not traditional function/class declarations. Bugs:args'swith:
block required an immediate newline, breaking on a trailing same-line comment on the header
(recurring class 41 above);class_start's reusable-workflow-call/container-job detection
requireduses:/image:to be the literal first line after the job name, missing the common
real pattern ofneeds:/if:/permissions:appearing first (recurring class 42 above, fixed
with a bounded max-10 intervening-key step-over, verified NOT to bleed into an unrelated
subsequent job);_dependency_capturehad no quote tolerance at all foruses:/image:
values, missing a real yamllint-driven quoted-scalar authoring style (recurring class 43
above).crucible_check.pyshowed a zero diff -- confirmed expected (not "feature is wrong",
per recurring class 8) by grepping the actual corpus for all three trigger shapes and
confirming none appear anywhere in it. Checkedtest_language_standards_strict.pyfor
intentional yaml behavior before finalizing (per c's Extraction hardening: c #822 lesson) -- no conflicts; existing
regression tests (including the class_start<->import ambiguity-sweep test) pass unmodified. 1
known limitation documented: a GitHub Actions expression used as an entire templated image
reference (image: ${{ vars.REGISTRY }}/myimage:latest) still doesn't match -- judged too
risky to broaden the character class for a comparatively rare pattern. -
shell— closed via Extraction hardening: shell #835, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding).
shell has noclass_start(strictly procedural), so only three of the four gauntlets
applied. Bugs:args's braced form (${1}/${10}) had no allowance for bash's
default-value/error-message/assign/alternate expansion operators (:-/:=/:?/:+), so
${1:-default}-- arguably the single most common real-world shape a positional parameter
takes -- was entirely invisible (recurring class 44 above);func_start's POSIXname()
keyword-exclusion lookahead only listed 5 of bash's ~17 word-based reserved words, so
done() {,elif() {,select() {,function() {, etc. all falsely matched as function
definitions (recurring class 45 above).crucible_check.pyshowed a real diff, confirmed
confined entirely toshell/brew(one real Homebrew script's detected parameter count jumped
6 -> 10, from theargsfix) -- no cross-language ripple. Golden master fixtures re-blessed.
Checkedtest_language_standards_strict.pyfor intentional shell behavior before finalizing
(per c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified. 2 known
limitations documented, both the same pipeline-wide_dependency_captureunshielded-content
gap as every other language (recurring class 10/11) but confirmed via two INDEPENDENT
vectors this time: a commented-out# source .envline still matches (the space after#
satisfies the rule's own mid-statement boundary requirement, regardless of the#itself),
and a quoted string containingsourcewith a leading space (echo " source .env") also
still matches -- the earlier no-space case's apparent immunity is incidental (the opening
quote character isn't in the boundary set), not real string-awareness, and disappears the
moment natural spacing is present. -
makefile— closed via Extraction hardening: makefile #844, 4 real bugs fixed (a fresh sweep, not a pre-flagged finding).
makefile has noclass_start(strictly declarative, no OO constructs), so only three of the
four gauntlets applied. Bugs:func_start's colon lookahead had no exclusion for an
immediately-following=, soMY_VAR := value/MY_VAR ::= value(arguably THE most common
modern Make idiom) were misidentified as target declarations (recurring class 46 above);
func_startalso didn't detect multi-target rules (a b c: dep) at all (recurring class 47
above) -- fixing this the naive way reopened a NEW false-positive vector (recipe lines with a
URL or time-shaped colon misparsed as co-target tokens), caught before shipping and fixed by
excluding tab-initial lines from the target-declaration path entirely (same recurring class
47, second half);argshad no awareness of Make's own$$escape convention, so$$1/
$$(1)(passing a literal shell positional param through a recipe) were misidentified as
real macro-call references (recurring class 48 above);_dependency_captureshared
func_start's same tab-initial-line vulnerability, letting a recipe command literally named
"include"/"sinclude" be misidentified as a real include directive.crucible_check.pyshowed
a real diff, confirmed confined to exactly two real Makefiles embedded in unrelated
repos' corpora (c/cpython/Makefile.pre.in,lua/redis/Makefile) -- both showing the
expected DECREASE in false-positive function-declaration counts (redis: 42 -> 25). Golden
master fixtures re-blessed. Checkedtest_language_standards_strict.pyfor intentional
makefile behavior before finalizing (per c's Extraction hardening: c #822 lesson) -- caught a real conflict this
time:test_makefile_func_start_and_macros_no_false_collisiondeliberately locks in that
$(1): $(2)(adefine...endefmacro-placeholder shape) must NOT satisfy func_start, which
ruled out an initially-planned char-class widening to support variable-referenced target
names ($(TARGET): $(OBJECTS)) -- documented as a deliberately-NOT-fixed known limitation
instead of overriding the existing test.import(a sibling, non-gauntlet-scoped rule
sharing_dependency_capture's pattern) deliberately left unfixed, out of scope -- same
precedent as Extraction hardening: yaml #843's identical call for yaml. 2 known limitations documented: the
variable-referenced-target case above, andinclude a.mk b.mk c.mk(multiple files on one
include line) only capturing the first file. -
cobol— closed via Extraction hardening: cobol #854, 4 real bugs fixed (a fresh sweep, not a pre-flagged finding); all
four gauntlets applied (cobol has a realclass_start, unlike shell/makefile). Bugs:
class_starthad no allowance for standard trailing clauses on PROGRAM-ID/CLASS-ID/
INTERFACE-ID (IS INITIAL PROGRAM,IS COMMON PROGRAM,FINAL,INHERITS Base) --
recurring class 49 above; fixing that reopened a false-positive vector for the SAME rule's
FACTORY/OBJECT keywords (standalone markers always followed by a division header) --
recurring class 50 above, caught by a same-PR regression test written to confirm the
pre-fix "this doesn't happen" assumption, which then failed once the widening landed;
args's USING capture had no exclusion for the literal word "RETURNING", so
PROCEDURE DIVISION USING WS-A RETURNING WS-B.(declaring a parameter AND a return value in
one header) had USING's capture bleed through and swallow WS-B too -- recurring class 51
above;func_start's SECTION lookahead had no allowance for a trailing SEGMENT-NUMBER
(MAIN-PARA SECTION 10.), a real COBOL-68/74-era program-segmentation feature still accepted
by modern compilers for legacy support.crucible_check.pyshowed a zero diff for all
four fixes -- verified this was legitimately because the corpus's real.cbl/.cob/.cpy
files contain none of these constructs (grepped directly for segment numbers, INHERITS,
IS INITIAL/COMMON PROGRAM, RETURNING -- zero hits), per recurring class 8's own caution,
not evidence the fixes are no-ops. No golden-master regeneration needed. Checked
test_language_standards_strict.pyfor intentional cobol behavior before finalizing (per
c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified.argsand
class_starthad zero prior test coverage in the old monolithic dict files before this
issue. 1 known limitation documented: a multi-linePERFORM\n TargetFunc.statement (a
real paragraph invocation split across two lines) is structurally indistinguishable from a
genuinely new paragraph declaration -- no cross-line statement-context tracking exists (or
is architecturally feasible) for a regex-only engine to resolve this. -
sqlite— closed via Extraction hardening: sqlite #836, 8 real bugs fixed (a fresh sweep, not a pre-flagged finding);
all four gauntlets applied. Bugs:func_start/class_startboth had no allowance for
schema-qualified names (main.users, recurring class 52 above) or any of SQLite's three
quoted-identifier styles ("name"/`name`/[name], recurring class 53 above -- added
inside the SAME capture group rather than new numbered ones, since detector.py reserves group
2 for class_start's inheritance-parent extraction elsewhere);args's IN/VALUES clause
truncated on a nested subquery (Rule 11, reconfirmed for SQL -- recurring class 54 above);
args's CTE alternative required true line start, missing the dominant inlineWITH cte_name (...) AS (...)form entirely (recurring class 55 above);class_start's ownIF NOT EXISTS
clause never got the vertical-whitespace fixfunc_start's parallel clause already has,
caught by this issue's own pathological test, not pre-flagged (recurring class 56 above);
_dependency_capture's ATTACH clause failed OUTRIGHT (not just truncated) on a quoted path
containing a space, a worse variant of recurring class 39 (PowerShell) confirmed on a third
language.crucible_check.pyshowed a REAL diff this time (not zero), confirmed confined
entirely tosql/sqlite files (e.g. a WITH-statement's detected parameter count correctly
grew from 3 to 5 once the CTE/IN fixes landed) -- no cross-language ripple. Golden master
fixtures re-blessed. Checkedtest_language_standards_strict.pyfor intentional sqlite
behavior before finalizing (per c's Extraction hardening: c #822 lesson) -- found a real conflict: an existing test
hardcoded a capture-group INDEX for load_extension that the ATTACH quoted-path fix's own
group restructuring shifted (recurring class 57 above) -- updated the test to match
galaxyscope.py's actual "any non-None group" consumption convention instead of re-hardcoding
a new index.argsandclass_starthad zero prior test coverage in the old monolithic dict
files before this issue. -
agc_assembly— closed via Extraction hardening: agc_assembly #857 (PR test(extraction): harden agc_assembly extraction coverage (#857) #931). Original test-authoring pass (a fresh sweep by a
different contributor, not this session) found no bugs and claimed the existing regexes were
"already extremely robust" -- this was independently reviewed given every other language in
this epic had found real bugs, and 2 real, significant bugs WERE found on review, both missed
by the original 136-test suite because it only checked self-consistency, never real-corpus
ground truth (recurring classes 58-60 above):func_start's opcode whitelist covered only 16
of the real AGC instruction set, missing ~25 opcodes this SAME file's own sibling rules
already recognized as legitimate (CAF-- 94 corpus occurrences, one of the single most
common AGC instructions -- entirely absent; alsoTCF/XCH/LXCH/AD/MASK/INCR/
RELINT/etc.);args's register-coupling opcode list was missingAUG/DIM/INCR. The
original suite's owninvalidlist literally asserted"MYLABEL\tTCF INTERNAL"must NOT
match, with the comment "TCF is not in the opcode list" -- true of the code, false of real
AGC assembly, where TCF is one of the most common branch instructions; this is the clearest
concrete instance yet of recurring class 60. Confirmed the fix's real-world impact directly
against the Apollo 11 (Luminary/Comanche) source corpus in language-crucible: total
func_startmatches rose from 609 to 812 (+33%) with zero new false positives against data/
constant pseudo-ops (OCT/OCTAL/DEC/2DEC/ADRES/EQUALSall correctly stay excluded).
crucible_check.pyshowed a real diff -- confirmed the only CONTENT changes (not just global-
aggregate/topological-coordinate ripple, which touched several unrelated files/languages as an
expected side effect of agc_assembly's structural mass shifting) were inagc_assemblyitself;
real Apollo 11 subroutines likeSPVAC/NEXTCORE/JOBWAKE3/SUPDXCHZ/VACFOUNDthat were
previously silently merged into a PRECEDING function's body (inflating its own LOC/impact
numbers) now correctly resolve as their own function boundaries. Golden master fixtures
re-blessed. Also fixed the original PR's test file to add regression tests for both bugs, move
the wrongly-invalid TCF case to valid, and cleaned up a stale rebase artifact (the branch had
accidentally bundled an already-separately-merged, unrelated kotlin fix -- kotlin func_start/args missing backtick-identifier support (found during #825) #899/fix(kotlin): support backtick-quoted identifiers in func_start, args, class_start (fixes #899) #929 -- from
before it was cleanly split out; rebased onto latest main to drop the now-redundant commits). -
assembly— closed via Extraction hardening: assembly #856 (PR fix: harden assembly extraction rules #936). Original test-authoring pass (a fresh sweep by a
different contributor, not this session) found no bugs across all four gauntlets. Independently
reviewed given the pattern fromagc_assemblyabove;func_start's "neutralize a dead negative
lookahead" fix (the PR's own headline finding) was confirmed genuinely correct against the real
corpus (153/155 label lines matched, 98.7%, with the 2 misses correctly-excluded.L-prefixed
local data labels).class_startand_dependency_capturewere independently audited and found
clean (zero false positives against real corpus text containing lookalike prose/C-struct
mentions; a real.incbin APE_LOADERbare-identifier form correctly captured). 1 real bug found
inargs, missed by the original suite because its own tests validated the regex's existing
(buggy) behavior rather than real x86 ground truth (recurring class 60 again):[er][89]
matched the fictional registerse8/e9while failing to match the realr8d/r9d/r8w/
r9w/r8b/r9bforms (recurring class 61 above); also closed a genuine coverage gap this
review found independently -- zero support for the legacy 8/16-bit x86 register set despite
the language's own_meta.target_versiondeclaring it "Backwards Compatible". A first raw-text
corpus quantification looked like +391% (135->663) but turned out to be substantially inflated
by matches inside;-prefixed prose comments; re-run against the realPrism-stripped
code_streamgave the honest, still-substantial number: 84->305 (+263%), concentrated in the
bootos16-bit bootloader corpus file the fix specifically targeted (recurring class 62 above,
a new methodological lesson for this epic's corpus-quantification pattern).crucible_check.py
confirmed the diff confined to assembly with no cross-language ripple; golden master fixtures
re-blessed. Fixed the original PR's test file to remove the two phantom-registervalidcases
and add dedicated regression tests for both the phantom-vs-real-suffix bug and the legacy-
register gap. - (remaining 23 languages — sub-issues filed, tracked individually)
Activity
docs: update recurring-bug-class list with #815's findings
Extraction hardening: typescript (#815) (#862)
Fix/859 php docblock corruption (#864)
Fix #816: Extraction hardening for java (epic #813) (#868)
Fix #817: Extraction hardening for go (epic #813) (#870)
Fix #818: Extraction hardening for python (epic #813) (#872)
Fix #819: Extraction hardening for rust (epic #813) (#874)
ci: split smoke-test's full pytest run out of the 12-way OS/Python ma…
Fix #814: Extraction hardening for javascript (epic #813) (#878)
Fix #820: Extraction hardening for csharp (epic #813) (#880)
Fix #821: Extraction hardening for cpp (epic #813) (#882)
Fix #822: Extraction hardening for c (epic #813) (#884)
Fix #823: Extraction hardening for kotlin (epic #813) (#886)
Fix #824: Extraction hardening for swift (epic #813) (#888)
Fix #825: Extraction hardening for scala (epic #813) (#898)
15 remaining items
Add harden-language-extraction skill, cross-reference it in CLAUDE.md
Split test_language_standards_strict.py into per-language files (#1057)
docs: add language-status skill and docs/language_status/ (Python wor…
fix(testing): tree-sitter accuracy audit still mis-measured C++ names…
fix(testing): tree-sitter accuracy audit couldn't name C/C++ functions (
fix(core): C++ func_start missed pointer/reference returns and mishan…
fix(core): C args regex never recognized custom typedef'd parameter t…
chore(tooling): scaffold epic #1295 -- diff script, checklist doc, sk…
chore(tooling): scaffold epic #1295 -- diff script, checklist doc, sk…
fix(objc): recognize untyped keyword-message args, stop body leak int…
fix(c): wire c into class_start named-entity extraction (#1295) (#1378)
sqlite tri-comparison validation: class extraction to 100%, both ledg…
feat(markdown): capture relative links as dependency edges (closes #2638
fix(core-engine): yaml args reads declared inputs: and counts paramet…