Skip to content

Epic: Harden the four extraction gauntlets (function/args/class/dependency) per language #813

Description

@squid-protocol

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/typescript func_start false-positive-matches a single-line string literal
    containing function-shaped text (let query = "function Foo() {";). Root cause:
    detector.py's _slice_by_braces computes func_start.finditer(code) against the raw code,
    before building the string/comment-shielded safe_code used later for the brace search — this is
    an architectural gap affecting every language routed through _slice_by_braces (Mode B), not
    just JS/TS.
  • typescript func_start false-positive-matches type Foo = (a: T) => R; (a type alias) as
    if it were a real arrow-function assignment.
  • java func_start breaks 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.
  • go func_start doesn'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:

  1. Nested-generic/template flattening (Rule 11 shape) — check any rule using a flat <[^>]*> /
    \([^)]*\) where the language allows one level of real nesting.

  2. 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.

  3. Unshielded string/comment content reaching a Mode-B rule's finditer call (_slice_by_braces
    confirmed; _slice_by_indentation/_slice_by_labels/_slice_by_terminator not yet checked).

  4. 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 exact IDENT = (...) => ... shape as
    a real arrow-function assignment.

  5. (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).

  6. (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/implements clause) 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.

  7. (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.

  8. (new, from Extraction hardening: typescript #815) A "zero diff" on crucible_check.py after 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 (grep the diff for other language names) before blessing, not just eyeballed for
    plausible magnitude.

  9. (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, so class 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).

  10. (new, from Extraction hardening: java #816) _dependency_capture is matched against raw, unshielded file content for
    EVERY language, unconditionally — broader than recurring class 3.
    Unlike func_start's
    Mode-B _slice_by_braces path (gated to js/ts, tracked via prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859), _dependency_capture is run
    via import_regex.finditer(content_buffer) in galaxyscope.py, where content_buffer is the
    raw file content read straight off disk — there is no shielding gate here at all, for any
    language. Confirmed reproducible for java: an import ...;-shaped line inside a Java 15+ text
    block ("""...""") at true line start still produces a phantom dependency-graph edge. Not
    fixed (fixing it means shielding content_buffer before 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.

  11. (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 same func_start false-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_braces shielding gate" follow-up PR noted below.

  12. (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, where func_start/args
    shared the bug and class_start had a different-shaped version of it) and typescript (Extraction hardening: typescript #815,
    where func_start/class_start both needed fixes), go's class_start and args rules
    already had the correct (?:[ \t\n]*\[[^\]]*\])? generic step-over — only func_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.

  13. (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 same func_start/_dependency_capture false 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.

  14. (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.

  15. (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 calling func_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.

  16. (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.

  17. (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's func_start already
    carried an explicit "BUG FIX (Rule 11...)" comment and a two-level-nesting idiom from an earlier
    pass, but args (parsing the exact same fn <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."

  18. (new, from Extraction hardening: rust #819) A _dependency_capture character 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 via crucible_check.py:
    a real corpus file's detected-dependency count jumped from 1 to 5 once fixed. When reviewing a
    _dependency_capture character 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.

  19. (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_capture false positive as js/ts template literals, Java text blocks,
    and Go raw strings. Four languages, four unrelated syntax features, same root cause.

  20. (new, from Extraction hardening: javascript #814) A fix's own optional-whitespace choice can open a NEW false-positive path —
    caught only by running crucible_check.py against real code, not by any hand-written test
    case.
    Fixing javascript's func_start/args to 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 named A, 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.

  21. (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.

  22. (new, from Extraction hardening: csharp #820) A _dependency_capture rule can be missing an entire real-world statement
    SHAPE, not just a character.
    csharp's using 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 the IDENT = 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 via crucible_check.py against 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.

  23. (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's func_start/args supported
    Class::method(...) for plain identifiers but had ZERO allowance for a class-qualifier before
    the operator keyword — 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
    operator simply never had the qualifier-prefix group other branches already had). Confirmed
    via crucible_check.py against 4 real repos across 7 files (java/csharp/python's class_start
    generics bug recurring 3x made this pass expect ANOTHER class_start finding, but this one
    was in func_start/args instead — don't assume a recurring bug class means the SAME rule
    breaks again; check all four independently every time
    ).

  24. (new, from Extraction hardening: cpp #821) When inspecting a crucible_check.py --update --yes diff for confinement,
    grep the raw git diff text at your own risk — it will report false "other language" hits from
    dependency-list VALUES and unrelated context lines, not just changed Parsed Files keys.

    Naively grepping the diff for path-like strings after blessing cpp's fix surfaced dozens of
    .zig, .pm, and unrelated .h paths 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 --update run 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 textual git diff for confinement on a
    file this large.

  25. (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's class_start changed files in
    python/numpy, lua/redis, scheme/racket, cobol/gnucobol_internals, and cpp/godot
    (specifically object.h, whose engine-assigned Language field 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/.h file 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/.cob file with Language != "C".

  26. (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.

  27. (new, from Extraction hardening: c #822) ALWAYS grep test_language_standards_strict.py for 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 c class_start fix 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 broke test_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 the dependency_injection rule'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.

  28. (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's companion object { ... } (almost always anonymous) never
    matched class_start at all. The tempting fix — making the general
    class|interface|object|enum class branch'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 literal companion[ \t\n]+object shape 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.

  29. (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.

  30. (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.

  31. (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).

  32. (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's func_start/args name 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
    like def `should handle edge cases`(): Unit = {}) never matched at all. Fixed as an
    alternative capture group (not a widened class), resolved downstream via match.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.

  33. (new, from Extraction hardening: scala #825) A _dependency_capture rule 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
    \s matches newlines, on a realistic multi-import file it kept consuming across the SECOND
    import line and into the following unrelated statement, so the second import was never
    separately detected. crucible_check.py against 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 (repeat identifier. segments, then end on either a {...}
    block or a bare trailing identifier/wildcard) instead of widening the flat class further --
    check any _dependency_capture rule using a bare \s (rather than a real statement boundary)
    for this same bleed-over risk, not just for missing symbols.

  34. (new, from Extraction hardening: scala #825) A confirmed real bug's crucible_check.py diff 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_capture bleed-over (recurring class 34) changed the shared cross-repo dependency
    DAG's topology (the whole corpus is scanned as one graph, per network_risk_sensor.py's
    PageRank/blast-radius scoring and spatial_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.

  35. (new, from Extraction hardening: powershell #834) Rule 11 also manifests for a flat PARENTHESES-wrapped parameter/argument
    list, not just generic type parameters.
    PowerShell's args rule (param(...) and function 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.py against 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.

  36. (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.

  37. (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.

  38. (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_capture used 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.

  39. **(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.

  40. (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.

  41. (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's class_start required uses:/image: to be
    the LITERAL FIRST line after a job name, but real reusable-workflow-call/container jobs
    routinely have needs:/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 no uses:/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.

  42. (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 (import and _dependency_capture sharing 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 for uses:/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.

  43. (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's args rule
    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 via crucible_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.

  44. (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's func_start excluded only 5 of bash's ~17 word-based reserved
    words (if/while/for/case/until) from its POSIX name() 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.

  45. (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_start treated any bare :/:: as a real target-defining colon, with no exclusion for an
    immediately-following = -- so MY_VAR := value and MY_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.

  46. (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's func_start gained
    multi-target support (a b c: dep), but this let a RECIPE line's later words (a URL's ://, a
    bare time value 10: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.

  47. (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's args rule 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.

  48. (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's class_start required the entity name to be
    immediately followed by a period/newline/EOS, with zero allowance for PROGRAM-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.

  49. (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's class_start to 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.

  50. (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's args rule 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, so PROCEDURE 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.

  51. (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's func_start/class_start had no allowance
    for a schema-qualified name (CREATE TABLE main.users (...), CREATE TRIGGER main.my_trigger ... -- standard syntax for ATTACHed databases or explicit temp. targeting). Since \w never
    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.

  52. (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's func_start/class_start had 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.

  53. (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.

  54. (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's args CTE alternative required the CTE name at TRUE line start, but the
    single most common way to write a CTE is inline, immediately after the WITH keyword on the
    SAME line (WITH cte_name (col1, col2) AS (...)) -- never matched at all. Fix: added a second
    anchor alternative (immediately after WITH/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.

  55. (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's func_start already has a documented "VERTICAL MODIFIER SHIELD" fix
    for its own IF NOT EXISTS clause (using [ \t\n]+ throughout, including the gap right before
    the captured name). class_start's OWN parallel IF NOT EXISTS clause (for CREATE TABLE)
    was never given the same fix -- its trailing gap stayed [ \t]+ (no newline), so CREATE 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.

  56. (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_path asserted
    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 reads next((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.

  57. (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's func_start whitelisted only 16 opcodes,
    missing ~25 real, common instructions this SAME file's own branch/args/safety/
    state_mutation rules 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, with CAF (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.

  58. (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.

  59. (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 its invalid list 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.

  60. (new, from Extraction hardening: assembly #856) A register/opcode alternative can simultaneously match a FICTIONAL form and
    miss the REAL one, when a trailing \b is assumed to separate a base token from a suffix that is
    itself a word character.
    Assembly's args rule used [er][89] intending to extend r8/r9
    coverage, but e8/e9 are not real x86 registers -- the pattern actually matched a phantom
    register while \b after [89] silently prevented the REAL r8d/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 as valid (("mov e8, 5", "e8")) -- another concrete instance of recurring
    class 60. Fixed to r[89][dwb]?, and separately closed a real coverage gap this review also
    found: assembly's own _meta.target_version explicitly states "Backwards Compatible", yet args
    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's bootos bootloader) 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.

  61. (new, from Extraction hardening: assembly #856) A corpus-impact quantification (OLD.finditer vs NEW.finditer match counts,
    the pattern established in classes 58-59) must run against the pipeline's actual comment-stripped
    code_stream (via Prism.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
    args fix 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 real Prism pipeline (which strips
    ;/# line comments for any "lexical_family": "line_exclusive" language before detector.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

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 — bundles ruff format --check + ruff_audit.py --ci +
    mypy_audit.py --ci + dead_key_audit.py --ci into one command, with automatic pure-line-shift
    detection (--regenerate auto-fixes baselines whose new findings are ALL shifts; anything
    genuine is left for manual review, never silently accepted).
  • tests/tools/crucible_check.py --update --yes already 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/args had 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 via crucible_check.py against 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/args shared 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_start had 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 via crucible_check.py (restored detection of a real
    findPluginIdForClass method in gradle's DefaultPluginManager.java, the corpus's only
    diff). 2 known limitations documented, not fixed (architectural, out of scope for a single
    language): func_start text-block false positive (recurring class 3, confirmed on a second
    language) and _dependency_capture's broader unshielded-content_buffer gap (new recurring
    class 10).
  • go — closed via Extraction hardening: go #817, 1 real bug fixed: func_start had 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. Notably class_start and args already had the correct step-over — only
    func_start was 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 via crucible_check.py
    (restored detection of a real TypeAssert[T any] generic function in a corpus file,
    the only diff). 2 known limitations documented, not fixed (architectural): raw-string-literal
    false positive for both func_start and _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_start all 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_start silently lost its base-class capture rather than failing outright, same failure
    shape as java's Extraction hardening: java #816 bug. crucible_check.py showed 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_buffer gap (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):
    args never received the two-level-nesting Rule-11 fix that func_start already 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 via crucible_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 for func_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_start had 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_capture was 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 via crucible_check.py (a real Roslyn corpus file gained a
    newly-detected using 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/args had zero allowance for a class-qualifier before the operator keyword,
    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 bare operator=(...) already worked — a distinct
    failure mode from the recurring Rule-11 nesting bug (recurring class 24 above); args also
    needed the established nested-template step-over for the method's own template args
    (Foo::Bar<Baz<int>>(...)). Verified confined to cpp via crucible_check.py — 7 real files
    across 4 repos (mlir, NVDA, powertoys, godot) gained newly-detected operator functions/
    parameter counts, including NVDA's storage.cpp function 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 for func_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 in class_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 broke test_c_intentional_double_classification_sweep
    (test_language_standards_strict.py), which documents that exact match as deliberate,
    intended to co-fire with the dependency_injection rule's _ops-vtable-suffix heuristic
    (recurring class 28 above). Verified via crucible_check.py (structural diff, not textual
    grep — recurring class 25): cpython's dictobject.c and micropython's objtype.c each
    gained a real anonymous/inline-struct detection. The diff also touched python/numpy,
    lua/redis, scheme/racket, cobol/gnucobol_internals, and cpp/godot's object.h
    (engine-classified Language: "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/args shared 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_start had no support for companion 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). Checked test_language_standards_strict.py for intentional
    kotlin behavior before finalizing (per c's Extraction hardening: c #822 lesson) — no conflicts found, and the
    existing test_kotlin_ambiguity_sweep_shared_literals_are_not_bugs test continues to pass
    unmodified. crucible_check.py showed 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/args shared 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). Checked test_language_standards_strict.py for
    intentional swift behavior before finalizing (per c's Extraction hardening: c #822 lesson) — no conflicts; the
    existing test_swift_ambiguity_sweep_shared_literals_are_not_bugs test passes unmodified.
    crucible_check.py showed 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/args shared 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/
    args also 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.py showed 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.
    Checked test_language_standards_strict.py for 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_buffer gap 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_start shared the flat \([^)]*\) Rule-11 paren-list step-over, breaking on
    default-value expressions containing their own parens (recurring class 36 above -- confirmed
    severe via crucible_check.py, one real corpus function's detected parameter count jumped
    3 -> 9); PS class constructors (Foo([string]$name) { ... }, no function keyword, no
    return-type bracket) were entirely invisible to args/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.py for intentional powershell behavior before finalizing (per
    c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified.
    crucible_check.py showed a real diff, confirmed confined entirely to powershell/core plus
    its own aggregate rollups (no cross-repo ripple, unlike scala's Extraction hardening: scala #825 _dependency_capture fix
    -- 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_version scopes 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's with: 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's with:
    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
    required uses:/image: to be the literal first line after the job name, missing the common
    real pattern of needs:/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_capture had no quote tolerance at all for uses:/image:
    values, missing a real yamllint-driven quoted-scalar authoring style (recurring class 43
    above). crucible_check.py showed 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. Checked test_language_standards_strict.py for
    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 no class_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 POSIX name()
    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.py showed a real diff, confirmed
    confined entirely to shell/brew (one real Homebrew script's detected parameter count jumped
    6 -> 10, from the args fix) -- no cross-language ripple. Golden master fixtures re-blessed.
    Checked test_language_standards_strict.py for 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_capture unshielded-content
    gap as every other language (recurring class 10/11) but confirmed via two INDEPENDENT
    vectors this time: a commented-out # source .env line still matches (the space after #
    satisfies the rule's own mid-statement boundary requirement, regardless of the # itself),
    and a quoted string containing source with 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 no class_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 =, so MY_VAR := value/MY_VAR ::= value (arguably THE most common
    modern Make idiom) were misidentified as target declarations (recurring class 46 above);
    func_start also 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); args had 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_capture shared
    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.py showed
    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. Checked test_language_standards_strict.py for 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_collision deliberately locks in that
    $(1): $(2) (a define...endef macro-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, and include 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 real class_start, unlike shell/makefile). Bugs:
    class_start had 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.py showed 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.py for intentional cobol behavior before finalizing (per
    c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified. args and
    class_start had zero prior test coverage in the old monolithic dict files before this
    issue. 1 known limitation documented: a multi-line PERFORM\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_start both 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 inline WITH cte_name (...) AS (...) form entirely (recurring class 55 above); class_start's own IF NOT EXISTS
    clause never got the vertical-whitespace fix func_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.py showed a REAL diff this time (not zero), confirmed confined
    entirely to sql/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. Checked test_language_standards_strict.py for 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. args and class_start had 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; also TCF/XCH/LXCH/AD/MASK/INCR/
    RELINT/etc.); args's register-coupling opcode list was missing AUG/DIM/INCR. The
    original suite's own invalid list 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_start matches rose from 609 to 812 (+33%) with zero new false positives against data/
    constant pseudo-ops (OCT/OCTAL/DEC/2DEC/ADRES/EQUALS all correctly stay excluded).
    crucible_check.py showed 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 in agc_assembly itself;
    real Apollo 11 subroutines like SPVAC/NEXTCORE/JOBWAKE3/SUPDXCHZ/VACFOUND that 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 from agc_assembly above; 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_start and _dependency_capture were independently audited and found
    clean (zero false positives against real corpus text containing lookalike prose/C-struct
    mentions; a real .incbin APE_LOADER bare-identifier form correctly captured). 1 real bug found
    in args, 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 registers e8/e9 while failing to match the real r8d/r9d/r8w/
    r9w/r8b/r9b forms (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_version declaring 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 real Prism-stripped
    code_stream gave the honest, still-substantial number: 84->305 (+263%), concentrated in the
    bootos 16-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-register valid cases
    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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions