You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 onepathological case. For an AST-free engine, one
pathological case per language is a smoke test, not a gauntlet.
A first pass deepening just 8 languages' function-extraction coverage (still function-only,
still only 8 of 44 in-scope languages) already surfaced real, previously-undetected bugs in
under an hour of empirical testing:
javascript/typescriptfunc_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.
typescriptfunc_start false-positive-matches type Foo = (a: T) => R; (a type alias) as
if it were a real arrow-function assignment.
gofunc_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).
Out of scope (14, no relevant rules defined at all): batch, blp, csv, glsl, hlo, json,
markdown, mlir, nix, pbtxt, plaintext, proto, td, xml
Suggested order:javascript, typescript, java, go first (already have confirmed
findings to fix, not just a fresh sweep needed), then by real-world prevalence/complexity, then the
smaller/legacy long tail (cobol, fortran, assembly, abap, etc.) last.
Living checklist — update this section as sub-issues close
Each sub-issue ends with an "update the epic" step: append any newly-confirmed recurring bug class
or language-specific gotcha here (and to the methodology doc's own seed list) before closing, so
later languages start from a sharper checklist. Current confirmed classes:
Nested-generic/template flattening (Rule 11 shape) — check any rule using a flat <[^>]*> / \([^)]*\) where the language allows one level of real nesting.
Missing modern-era syntax entirely (Go 1.18+ generics, Python 3.12 PEP 695 generics, etc.) —
check the language's own version history for mainstream features added in the last ~5-8 years.
Unshielded string/comment content reaching a Mode-B rule's finditer call (_slice_by_braces
confirmed; _slice_by_indentation/_slice_by_labels/_slice_by_terminator not yet checked).
Type-alias vs. real-declaration ambiguity — any type X = .../using X = .../typedef
construct sharing a surface shape with a real function/class declaration. Confirmed real in
typescript (Extraction hardening: typescript #815): type Foo = (a: T) => R; shares the exact IDENT = (...) => ... shape as
a real arrow-function assignment.
(new, from Extraction hardening: typescript #815) Identifier-then-optional-type-annotation-then-operator. Any rule that
assumes an identifier is followed directly by the operator it cares about (=, (, etc.)
without accounting for an optional type annotation in between — common in every statically-typed
language (const Foo: React.FC<Props> = (...) => {, and the equivalent shape exists in Kotlin,
Swift, Rust, C#). Fix shape: an optional bounded skip-zone (: then bounded content excluding
the real operator's own character) before the operator check — but watch for the operator
appearing inside the type itself (e.g. a function-type annotation's own =>), which the skip
zone can't safely cross without additional care (documented as a known limitation in Extraction hardening: typescript #815 rather
than solved).
(new, from Extraction hardening: typescript #815) Rule 11 also applies to inheritance/extends clauses, not just
args/return-types.class_start's own generic step-over (between the class name and its extends/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.
(new, from Extraction hardening: typescript #815) Bare-call-vs-bare-definition ambiguity — a known, ACCEPTED limitation
class, not something to keep re-attempting. In any C-family/JS-family language, a bare call
statement at true line start (it('test', fn);, foo();) can be textually identical to a bare
method/function signature with no body shown. This is the same fundamental ambiguity csharp func_start never matches expression-bodied methods, and can hallucinate bare calls as functions with no enclosing brace #789
(csharp) hit and deliberately did NOT fix at the regex level (fixing it broke the cross-language
"extraction gauntlet" convention of testing bare fragments). Document with a dedicated
known-limitation test per language rather than spending time re-investigating whether it's
fixable — it generally isn't, without real scope-tracking this engine doesn't have.
(new, from Extraction hardening: 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).
(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.
(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.
(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.
(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.
(new, from Extraction hardening: python #818) The Rule-11 nested-delimiter bug shape isn't angle-bracket-specific — it hit
python's SQUARE-bracket PEP 695 (3.12+) generics identically.func_start/args/class_start
all shared a flat [^\]]* generic-parameter step-over that broke on any nested-bracket type
bound (def Foo[T: Sequence[int]](x: T) -> T:). Same fix idiom, square-bracket variant: \[(?:[^\[\]]|\[[^\[\]]*\])*\]. Whenever a language's generics/type-params use [...] instead
of <...> (Python, Go — see class 1's original framing was angle-bracket-biased), check for the
identical flat-negated-character-class mistake.
(new, from Extraction hardening: python #818) Mode C (_slice_by_indentation, python/yaml) ALREADY does the shield-before-
match fix that Mode B (_slice_by_braces) only has gated to js/ts. Verified empirically:
python's real pipeline shields triple-quoted strings/standard strings/comments via an
index-aligned shield BEFORE 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.
(new, from Extraction hardening: python #818) Not every vertical-split seam needs pathological-test coverage — check
against what real formatters actually produce. A vertical split between an identifier and an
immediately-following generic bracket (def Foo\n[T](...)) fails to match and was judged a
pre-existing, deliberately-undocumented-as-a-bug gap: no formatter (black, ruff format) ever
inserts a line break at that exact seam. Contrast with recurring class 2's guidance ("check the
language's own version history") — realism-triage applies to formatting seams the same way it
applies to feature coverage.
(new, from Extraction hardening: rust #819) A prior partial Rule-11 fix can leave a SIBLING rule un-fixed — always check
all four rules even when one already has a comment saying "fixed." Rust'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."
(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.
(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.
(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.
(new, from Extraction hardening: csharp #820) class_start's missing-generic-step-over bug (recurring class 1/6/9/13)
keeps recurring independently across THREE unrelated languages — java, python, and now csharp
all had it, each discovered separately. By the time csharp was reached, this should have been
checked as step one rather than rediscovered — for any future language with generics, check class_start's name-to-base-list gap FIRST, before doing anything else, given the hit rate so
far (3 of the 4 generic-capable languages checked had this exact bug). csharp's variant also
needed a companion fix no other language has needed yet: a primary-constructor parameter-list
step-over (record Foo<T>(T Value) : Base<T>, C# 9+ records / C# 12 primary constructors on
classes/structs) — the constructor's (...) was equally unconsumed between the generics and
the base-list : check, independently of the generic-parameter fix. Any language with
"primary constructor"-style class declarations (records, Kotlin/Scala primary constructors)
should check for this same shape.
(new, from Extraction hardening: csharp #820) A _dependency_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.
(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).
(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.
(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".
(new, from Extraction hardening: c #822) Recurring class 3 (unshielded content reaching a Mode-B rule) can manifest
via COMMENTS instead of strings, and some languages are structurally immune to the
string-literal variant. C has no raw-string syntax, and every C string-literal content
line necessarily starts with a literal " character (blocking ^[ \t]* from ever reaching
function-shaped text) -- so the string-literal false positive confirmed on 6 other languages
does NOT reproduce for C via strings. It DOES reproduce via un-decorated block-comment
continuation lines (/*\nint Foo() {\n*/, no leading * marker -- a common real
commented-out-code style). Check the actual line-layout of BOTH a language's string syntax
and its comment syntax independently rather than assuming "no raw strings" means "immune to
class 3" -- and record a confirmed-safe negative result explicitly (not silently) so a future
pass doesn't re-verify it from scratch.
(new, from Extraction hardening: c #822) ALWAYS grep test_language_standards_strict.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.
(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.
(new, from Extraction hardening: kotlin #823) Recurring class 3 confirmed on a SEVENTH language (kotlin, via triple-quoted
raw strings) — same shape as js/ts/java/go/rust/csharp/cpp, no new nuance, just another
confirming data point strengthening the case for the _slice_by_braces-broadening follow-up.
(new, from Extraction hardening: swift #824) The Rule-11 nested-generic-bound bug has now been a NEW confirmed finding in
7 of the 9 languages checked so far that have any generics-like syntax (java, typescript, go,
python, rust, csharp, kotlin — swift makes it 7, counting go's "generics unsupported at all"
as the same underlying gap family). The two exceptions: cpp was found to already be immune
(its func_start/class_start already carried the one-level-nesting idiom from a pass predating
this epic — only args needed it, per Extraction hardening: cpp #821), and c has no generics at all. At this point the
prior default ("assume clean until proven otherwise") should flip: assume any new language's
generic-parameter step-over has this bug until empirically disproven, and check it as literally
the first thing for any future generics-capable language. swift's variant was specifically
triggered by Swift 5.7+ primary associated type constraints
(func foo<T: Collection<Int>>(x: T) {) — a different concrete syntax shape than java's inline
bounds or python's PEP 695, but the exact same flat-<[^>]*> root cause and fix.
(new, from Extraction hardening: swift #824) Recurring class 3 confirmed on an EIGHTH language (swift, via BOTH
triple-quoted multi-line strings and #"..."# raw string literals — two distinct string forms
reproducing the same architectural gap in one language).
(new, from Extraction hardening: scala #825) The Rule-16 identifier-grammar gap (doc's "Identifier Capture Classes Must
Match the Language's Real Grammar" rule) showed up as a genuine cross-language finding, not
just a Scheme-specific curiosity. Scala'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.
(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.
(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.
(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.
(new, from Extraction hardening: powershell #834) Adding coverage for a bare, unprefixed declaration shape
(Identifier(params) { body }, no keyword, no return-type marker -- PowerShell class
constructors) WILL collide with that same language's own control-flow statement shape
(if/while/switch/for/foreach (cond) { body }), since they're textually identical to a flat
regex. A negative-lookahead keyword exclusion is required alongside the new alternative.
Caught here by hand-testing the fix's own "invalid" case immediately after writing it (not by crucible_check.py) -- the same "a new alternative can open its own blind spot" lesson as
recurring class 21, but at authoring time via manual verification rather than via a corpus diff.
Check for this collision risk BEFORE shipping any bare-identifier-plus-body alternative in a
C-family-control-flow language, not after.
(new, from Extraction hardening: powershell #834) A modifier/scope prefix attached to an identifier via a delimiter can make a
capture group swallow the PREFIX instead of the real name -- silently wrong data, not just a
non-match, and easy to miss in review. PowerShell's scope qualifiers (global:/script:/ local:/private: before a function name, e.g. function global:Foo {}) aren't in the
identifier character class, so the capture stopped at the delimiter and returned the scope
keyword itself (e.g. "global") as if it were the function name. Same root shape as Rule 16
(identifier grammar) but the failure mode -- confidently wrong output vs. a safe non-match -- is
worse and doesn't show up as a dramatic test failure the way a non-match does.
(new, from Extraction hardening: powershell #834) An "optional quote pair" idiom (['"]?...['"]?) around a capture class
that excludes whitespace is a DIFFERENT bug shape from recurring class 19 (a missing symbol) --
it truncates any quoted value containing that excluded symbol even though quoting should have
protected it. PowerShell's _dependency_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.
**(new, from Extraction hardening: powershell #834) _dependency_capture's comment-lookalike vulnerability (recurring class 3's
shape) is NOT universal -- confirmed a SECOND language (powershell, after c's Extraction hardening: c #822 finding,
recurring class 27) where the rule's own ^[ \t]* anchor structurally blocks a comment marker
(here, #) from ever reaching the keyword. But the SAME rule instance in the SAME language can
still be vulnerable via a DIFFERENT unshielded-content vector: PowerShell here-strings
(@"..."@) land their inner content at true line start with no blocking marker, so
import-shaped text inside one still produces a phantom dependency edge. Check comment- and
string-literal vectors independently per language/rule -- confirmed immunity to one vector
doesn't imply immunity to the other.
(new, from Extraction hardening: yaml #843) A "block requires an immediate newline after its header key" idiom
(with:[ \t]*\n...) breaks on a trailing same-line comment on the header itself
(with: # inputs for this action\n node-version: '18'), a real CI-YAML authoring style.
Same general shape as recurring classes 5/6 (an unaccounted-for optional element between two
required tokens) but for a block-header-to-body transition specifically, in a YAML/CI-config
context rather than a code-language declaration. Fix: allow an optional (?:#.*)? before the
newline. Check any language/rule with a "header line, then indented body" shape for the same
gap if that language's comment marker can appear on the header line.
(new, from Extraction hardening: yaml #843) A "declaration name, then immediately the thing we care about" shape can be
too strict when real usage inserts OTHER keys/statements in between -- not just a nesting
problem (Rule 11), a SEQUENCING problem. YAML'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.
(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.
(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.
(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.
(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.
(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.
(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.
(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.
(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.
(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.
(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.
(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.
(new, from Extraction hardening: sqlite #836) Rule 11's nested-delimiter shape, reconfirmed for SQL specifically: a flat \([^)]{0,N}\) inside an IN/VALUES clause truncates at the first closing paren of a nested
subquery.IN (SELECT id FROM (SELECT id FROM other)) (a real, common nested-subquery
pattern) silently ended the match one paren early instead of covering the whole clause. Same
fix as every other language in this epic: the one-level-nesting-safe idiom, bounded on both the
inner and outer repetition.
(new, from Extraction hardening: sqlite #836) An alternative's anchor can be far NARROWER than the dominant real-world
form -- not wrong in character class or nesting, but scoped to the WRONG position in the
statement. SQLite'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.
(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.
(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.
(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.
(new, from Extraction hardening: agc_assembly #857) Empirical corpus cross-validation (grep the real corpus, count matches
before/after a candidate fix) is the ONLY way to catch an "incomplete whitelist" class of bug --
self-consistent regex testing cannot, because the test cases are themselves typically derived by
observing the regex's OWN (possibly buggy) behavior, not the real language's ground truth.
Every other recurring class in this epic is a shape/structure bug findable by constructing an
adversarial payload and checking the regex's behavior in isolation; this class requires stepping
outside the regex entirely and asking "how much of the REAL corpus does this actually match, and
does that number make sense" -- a 40% miss rate against real source was invisible to 136 unit
tests that all only checked internal consistency, but obvious the moment the corpus was queried.
(new, from Extraction hardening: agc_assembly #857) AI-authored test coverage can enshrine EXISTING (buggy) behavior as
"correct" without ever validating it against the real language's grammar or corpus -- an
"invalid" test case can literally BE the bug, framed as if it were an intentional exclusion.
A prior PR's test suite (agc_assembly, claimed "zero bugs found, patterns already extremely
robust") included "MYLABEL\tTCF INTERNAL" in 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.
(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.
(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)
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) validatefunc_start,args,class_start, and_dependency_capture— the rules that isolate exact function/class/dependency identifiers usedeverywhere 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
validcases,2-3
invalidcases, and exactly onepathologicalcase. For an AST-free engine, onepathological case per language is a smoke test, not a gauntlet.
A first pass deepening just 8 languages' function-extraction coverage (still function-only,
still only 8 of 44 in-scope languages) already surfaced real, previously-undetected bugs in
under an hour of empirical testing:
javascript/typescriptfunc_startfalse-positive-matches a single-line string literalcontaining function-shaped text (
let query = "function Foo() {";). Root cause:detector.py's_slice_by_bracescomputesfunc_start.finditer(code)against the raw code,before building the string/comment-shielded
safe_codeused later for the brace search — this isan architectural gap affecting every language routed through
_slice_by_braces(Mode B), notjust JS/TS.
typescriptfunc_startfalse-positive-matchestype Foo = (a: T) => R;(a type alias) asif it were a real arrow-function assignment.
javafunc_startbreaks on one-level-nested generic bounds (<T, U extends Comparable<U>>) — the same "Rule 11" nested-delimiter bug class already fixed elsewhere inepic Epic: Strict & exact regex test coverage for all structural signatures, per language #518, just never checked for this rule.
gofunc_startdoesn't recognize Go 1.18+ generics (func Foo[T constraints.Ordered](...))at all — mainstream, ~5-year-old Go syntax, currently invisible to the engine.
None of these were hypothetical or contrived — they're realistic code an AST-free engine will
encounter constantly. Expect more like them across the remaining 36 in-scope languages.
Methodology
Full methodology lives in
tests/extraction/how_to_harden_extraction.md— read that directly rather than expecting a summary here; it covers the per-language checklist
(valid cases across syntax eras + testing-framework patterns, invalid cases covering real
lookalikes, 10-15 pathological cases per major language), the verification discipline (empirical
check before adding, full ReDoS/lint/crucible rigor for any fix), a seed recurring-bug-class list,
and the proposed per-language test file layout replacing the four monolithic dicts.
Scope: 44 languages, one sub-issue each
A sub-issue is filed for every language with at least one non-
Nonerule amongfunc_start/args/class_start/_dependency_captureinLANGUAGE_DEFINITIONS. Each sub-issue,titled "Extraction hardening:
<language>", covers all four gauntlets for that languagetogether (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,gofirst (already have confirmedfindings to fix, not just a fresh sweep needed), then by real-world prevalence/complexity, then the
smaller/legacy long tail (
cobol,fortran,assembly,abap, etc.) last.Living checklist — update this section as sub-issues close
Each sub-issue ends with an "update the epic" step: append any newly-confirmed recurring bug class
or language-specific gotcha here (and to the methodology doc's own seed list) before closing, so
later languages start from a sharper checklist. Current confirmed classes:
Nested-generic/template flattening (Rule 11 shape) — check any rule using a flat
<[^>]*>/\([^)]*\)where the language allows one level of real nesting.Missing modern-era syntax entirely (Go 1.18+ generics, Python 3.12 PEP 695 generics, etc.) —
check the language's own version history for mainstream features added in the last ~5-8 years.
Unshielded string/comment content reaching a Mode-B rule's
finditercall (_slice_by_bracesconfirmed;
_slice_by_indentation/_slice_by_labels/_slice_by_terminatornot yet checked).Type-alias vs. real-declaration ambiguity — any
type X = .../using X = .../typedefconstruct sharing a surface shape with a real function/class declaration. Confirmed real in
typescript (Extraction hardening: typescript #815):
type Foo = (a: T) => R;shares the exactIDENT = (...) => ...shape asa real arrow-function assignment.
(new, from Extraction hardening: typescript #815) Identifier-then-optional-type-annotation-then-operator. Any rule that
assumes an identifier is followed directly by the operator it cares about (
=,(, etc.)without accounting for an optional type annotation in between — common in every statically-typed
language (
const Foo: React.FC<Props> = (...) => {, and the equivalent shape exists in Kotlin,Swift, Rust, C#). Fix shape: an optional bounded skip-zone (
:then bounded content excludingthe 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 skipzone can't safely cross without additional care (documented as a known limitation in Extraction hardening: typescript #815 rather
than solved).
(new, from Extraction hardening: typescript #815) Rule 11 also applies to inheritance/extends clauses, not just
args/return-types.
class_start's own generic step-over (between the class name and itsextends/implementsclause) can have the exact same flat-<[^>]*>bug — and it's an easymiss because the class NAME still matches fine even when this breaks (only the extends/implements
capture group silently goes missing). Check class_start's generic handling explicitly for any
future language with generics, not just func_start/args.
(new, from Extraction hardening: typescript #815) Bare-call-vs-bare-definition ambiguity — a known, ACCEPTED limitation
class, not something to keep re-attempting. In any C-family/JS-family language, a bare call
statement at true line start (
it('test', fn);,foo();) can be textually identical to a baremethod/function signature with no body shown. This is the same fundamental ambiguity csharp func_start never matches expression-bodied methods, and can hallucinate bare calls as functions with no enclosing brace #789
(csharp) hit and deliberately did NOT fix at the regex level (fixing it broke the cross-language
"extraction gauntlet" convention of testing bare fragments). Document with a dedicated
known-limitation test per language rather than spending time re-investigating whether it's
fixable — it generally isn't, without real scope-tracking this engine doesn't have.
(new, from Extraction hardening: typescript #815) A "zero diff" on
crucible_check.pyafter adding a regex feature can meanthe corpus doesn't exercise it, not that the feature is wrong to add — same pattern already
seen in html attribute-value patterns assume double-quoted values only (single-quoted HTML never matches) #735. Conversely, a real per-language diff after a fix should be confirmed as confined to
that language (
grepthe diff for other language names) before blessing, not just eyeballed forplausible magnitude.
(new, from Extraction hardening: java #816)
class_start's generic step-over can be MISSING entirely, not just flat.TS's Extraction hardening: typescript #815 bug (recurring class 6 above) was a flat
<[^>]*>that needed widening. Java's versionof 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 witha subsequent extends/implements clause, extremely common real Java) silently lost the entire
inheritance capture. Same fix idiom applies (
(?:\s*<(?:[^<>]|<[^<>]*>)*>)?inserted between thename capture and the extends/implements check), but check whether the step-over exists at all
before assuming it just needs widening — two different failure shapes, same root symptom (name
capture looks fine, inheritance capture silently vanishes).
(new, from Extraction hardening: java #816)
_dependency_captureis matched against raw, unshielded file content forEVERY language, unconditionally — broader than recurring class 3. Unlike
func_start'sMode-B
_slice_by_bracespath (gated to js/ts, tracked via prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859),_dependency_captureis runvia
import_regex.finditer(content_buffer)ingalaxyscope.py, wherecontent_bufferis theraw 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+ textblock (
"""...""") at true line start still produces a phantom dependency-graph edge. Notfixed (fixing it means shielding
content_bufferbefore every language's_dependency_capture.finditer()call — a pipeline-wide change, not a per-language one) butworth checking for the same false-positive shape (string/comment content containing
import-statement-shaped text at true line start) on every future language's dependency pass.
(new, from Extraction hardening: java #816) Recurring class 3 (unshielded content reaching a Mode-B rule) reproduced on
a second, unrelated language feature. Java 15+ text blocks (
"""multi-line string""")produce the exact same
func_startfalse-positive as js/ts template literals — confirms thisis a genuine cross-language architectural gap (not a js/ts-specific quirk), strengthening the
case for the "broaden the
_slice_by_bracesshielding gate" follow-up PR noted below.(new, from Extraction hardening: go #817) The generic-step-over bug can be scoped to just ONE of the four rules even
when the language has generics everywhere. Unlike java (Extraction hardening: java #816, where
func_start/argsshared the bug and
class_starthad a different-shaped version of it) and typescript (Extraction hardening: typescript #815,where
func_start/class_startboth needed fixes), go'sclass_startandargsrulesalready had the correct
(?:[ \t\n]*\[[^\]]*\])?generic step-over — onlyfunc_start(fora parameterless-of-receiver, i.e. plain top-level generic function) was missing it. Don't
assume a generics bug found in one rule implies the same gap in the other three for a given
language — check each independently; some codebases already got it right in three out of four
places.
(new, from Extraction hardening: go #817) Recurring class 3 (unshielded content reaching a Mode-B rule) reproduced on
a THIRD, unrelated language feature. Go's raw string literals (backtick-delimited, common for
embedded SQL/templates/regex) produce the same
func_start/_dependency_capturefalse positiveas js/ts template literals and Java text blocks. Three languages, three completely different
syntax features, same architectural root cause — strong confirmation this is a real, general
gap worth the dedicated
_slice_by_braces-broadening follow-up, not a per-language curiosity.(new, from Extraction hardening: python #818) The Rule-11 nested-delimiter bug shape isn't angle-bracket-specific — it hit
python's SQUARE-bracket PEP 695 (3.12+) generics identically.
func_start/args/class_startall shared a flat
[^\]]*generic-parameter step-over that broke on any nested-bracket typebound (
def Foo[T: Sequence[int]](x: T) -> T:). Same fix idiom, square-bracket variant:\[(?:[^\[\]]|\[[^\[\]]*\])*\]. Whenever a language's generics/type-params use[...]insteadof
<...>(Python, Go — see class 1's original framing was angle-bracket-biased), check for theidentical flat-negated-character-class mistake.
(new, from Extraction hardening: python #818) Mode C (
_slice_by_indentation, python/yaml) ALREADY does the shield-before-match fix that Mode B (
_slice_by_braces) only has gated to js/ts. Verified empirically:python's real pipeline shields triple-quoted strings/standard strings/comments via an
index-aligned shield BEFORE calling
func_start.finditer(), so the same string-literal falsepositive confirmed at the regex level for python (matches recurring class 3's shape) is NOT a
live bug in the actual pipeline. This is the reference implementation the eventual
_slice_by_braces-broadening follow-up should mirror — it already exists in this codebase,just for the wrong mode.
(new, from Extraction hardening: python #818) Not every vertical-split seam needs pathological-test coverage — check
against what real formatters actually produce. A vertical split between an identifier and an
immediately-following generic bracket (
def Foo\n[T](...)) fails to match and was judged apre-existing, deliberately-undocumented-as-a-bug gap: no formatter (black, ruff format) ever
inserts a line break at that exact seam. Contrast with recurring class 2's guidance ("check the
language's own version history") — realism-triage applies to formatting seams the same way it
applies to feature coverage.
(new, from Extraction hardening: rust #819) A prior partial Rule-11 fix can leave a SIBLING rule un-fixed — always check
all four rules even when one already has a comment saying "fixed." Rust's
func_startalreadycarried an explicit "BUG FIX (Rule 11...)" comment and a two-level-nesting idiom from an earlier
pass, but
args(parsing the exact samefn <generics>(...)shape) was never updated and stillhad the flat
<[^>]*>. A rule-level fix comment is not proof the sibling rules got the sametreatment — check each of the four independently even when the language's own code comments
suggest "this was already handled."
(new, from Extraction hardening: rust #819) A
_dependency_capturecharacter class missing a single common symbol canhide 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 inre-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_capturecharacter class, explicitly check it against every symbol the language'sown import/use syntax can contain (
*,{,}, aliasing keywords, path separators) rather thanassuming the existing class is complete.
(new, from Extraction hardening: rust #819) Recurring class 3 reproduced on a FOURTH, unrelated language feature. Rust's
raw string literals (
r#"..."#, common for embedded SQL/regex/JSON) produce the samefunc_start/_dependency_capturefalse positive as js/ts template literals, Java text blocks,and Go raw strings. Four languages, four unrelated syntax features, same root cause.
(new, from Extraction hardening: javascript #814) A fix's own optional-whitespace choice can open a NEW false-positive path —
caught only by running
crucible_check.pyagainst real code, not by any hand-written testcase. Fixing javascript's
func_start/argsto recognize ES6 generator methods (*foo() {})initially used
\*?[ \t\n]*(whitespace-tolerant, matching the style of the other modifiergaps). 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 — gethallucinated 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 realformatter (Prettier included) always emits
*foo()with zero space, never* foo(). Lesson:when a fix widens a rule with a "reasonable-sounding" whitespace-tolerant character class, check
whether that specific optional character (unlike the language keywords around it) can ALSO
appear as the leading character of a comment or string in real code — if so, prefer the
strictest shape real formatted code actually produces, not the most permissive shape the
language grammar technically allows.
(new, from Extraction hardening: csharp #820)
class_start's missing-generic-step-over bug (recurring class 1/6/9/13)keeps recurring independently across THREE unrelated languages — java, python, and now csharp
all had it, each discovered separately. By the time csharp was reached, this should have been
checked as step one rather than rediscovered — for any future language with generics, check
class_start's name-to-base-list gap FIRST, before doing anything else, given the hit rate sofar (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 onclasses/structs) — the constructor's
(...)was equally unconsumed between the generics andthe base-list
:check, independently of the generic-parameter fix. Any language with"primary constructor"-style class declarations (records, Kotlin/Scala primary constructors)
should check for this same shape.
(new, from Extraction hardening: csharp #820) A
_dependency_capturerule can be missing an entire real-world statementSHAPE, not just a character. csharp's
using Alias = Target;alias directive (common forshortening 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, notjust 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.pyagainst a real Roslyn corpus file. When reviewing_dependency_capture, check not just the character class but whether the rule's overallgrammar shape actually covers every statement FORM the language's import/using syntax supports
(plain, aliased, static, global, generic-targeted), not just variations on a single form.
(new, from Extraction hardening: cpp #821) Out-of-line member definitions (
Class::member(...)) are a whole categoryworth checking explicitly for C-family languages with separate declaration/definition —
operator overloads specifically are easy to miss. cpp's
func_start/argssupportedClass::method(...)for plain identifiers but had ZERO allowance for a class-qualifier beforethe
operatorkeyword —TargetClass::operator=(...),TargetClass::operator==(...)werecompletely invisible, even though bare (non-qualified)
operator=(...)already worked. Thisis a distinct failure mode from Rule 11 (not a nesting-depth bug — the alternative branch for
operatorsimply never had the qualifier-prefix group other branches already had). Confirmedvia
crucible_check.pyagainst 4 real repos across 7 files (java/csharp/python's class_startgenerics bug recurring 3x made this pass expect ANOTHER
class_startfinding, but this onewas in
func_start/argsinstead — don't assume a recurring bug class means the SAME rulebreaks again; check all four independently every time).
(new, from Extraction hardening: cpp #821) When inspecting a
crucible_check.py --update --yesdiff for confinement,grep the raw
git difftext at your own risk — it will report false "other language" hits fromdependency-list VALUES and unrelated context lines, not just changed
Parsed Fileskeys.Naively grepping the diff for path-like strings after blessing cpp's fix surfaced dozens of
.zig,.pm, and unrelated.hpaths that looked like a confinement violation — they werejust pre-existing
#include/dependency values sitting inside OTHER unrelated files' JSONentries (or stale info from a
--updaterun whose earlier check-only pass had truncatedoutput), 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 (seeExtraction hardening: cpp #821's PR for the exact snippet) — never eyeball a raw textual
git difffor confinement on afile this large.
(new, from Extraction hardening: c #822) "Confined to the language you changed" can legitimately mean MULTIPLE repo
buckets, not one — polyglot/embedded files inside a differently-labeled repo are real,
expected hits, not a confinement violation. Fixing c's
class_startchanged files inpython/numpy,lua/redis,scheme/racket,cobol/gnucobol_internals, andcpp/godot(specifically
object.h, whose engine-assignedLanguagefield is explicitly"C"viasibling-file disambiguation, even though the repo's folder-dominant language is cpp) — repos
whose PRIMARY corpus label is a different language entirely. The structural-diff check
(recurring class 25) correctly flagged these as changed; the next step is to verify EVERY
changed file within those repos is actually a
.c/.hfile genuinely classified as C (checkthe file's own
"1. Artifact Identity" -> "Language"field, not just its extension or therepo's folder label), not a file in the repo's nominal language. A real confinement violation
would show up as a change to a
.py/.lua/.rkt/.cobfile withLanguage!="C".(new, from Extraction hardening: c #822) Recurring class 3 (unshielded content reaching a Mode-B rule) can manifest
via COMMENTS instead of strings, and some languages are structurally immune to the
string-literal variant. C has no raw-string syntax, and every C string-literal content
line necessarily starts with a literal
"character (blocking^[ \t]*from ever reachingfunction-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 realcommented-out-code style). Check the actual line-layout of BOTH a language's string syntax
and its comment syntax independently rather than assuming "no raw strings" means "immune to
class 3" -- and record a confirmed-safe negative result explicitly (not silently) so a future
pass doesn't re-verify it from scratch.
(new, from Extraction hardening: c #822) ALWAYS grep
test_language_standards_strict.pyfor the rule you're aboutto change before treating a permissive match as a bug — it may be intentional, tested, and
documented. A first version of the c
class_startfix required a trailing{to eliminatewhat looked like an obvious false positive (
struct foo_ops ops;, a variable declarationmatching 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_injectionrule's_ops-vtable-suffix heuristic. The trailing-{requirement was reverted, keeping only the(uncontested, purely additive) optional-tag-name fix for anonymous typedef structs. The
general lesson: this repo has an entire test file (
test_language_standards_strict.py)dedicated to documenting cross-rule ambiguity and intentional double-classification as
first-class, tested behavior — before "fixing" what looks like an obviously-wrong match, grep
that file for the payload shape first. The full pytest suite (already a required step) DOES
catch this, as it did here before the PR was opened — but checking proactively is cheaper than
discovering it via a red test after the fact.
(new, from Extraction hardening: kotlin #823) When adding an optional-name alternative to fix a missing declaration
shape, scope it NARROWLY to that exact shape rather than making an existing branch's name
optional broadly. kotlin's
companion object { ... }(almost always anonymous) nevermatched
class_startat all. The tempting fix — making the generalclass|interface|object|enum classbranch's name optional — would have opened a NEW falsepositive 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]+objectshape with its own optional name, leaving thegeneral branch's mandatory-name requirement untouched. When a missing-case fix would need to
make a shared branch more permissive, check whether a narrowly-scoped new alternative achieves
the same fix without loosening anything else — the same discipline as recurring class 6/22's
generic step-overs, but for optional-vs-mandatory captures instead of nesting depth.
(new, from Extraction hardening: kotlin #823) Recurring class 3 confirmed on a SEVENTH language (kotlin, via triple-quoted
raw strings) — same shape as js/ts/java/go/rust/csharp/cpp, no new nuance, just another
confirming data point strengthening the case for the
_slice_by_braces-broadening follow-up.(new, from Extraction hardening: swift #824) The Rule-11 nested-generic-bound bug has now been a NEW confirmed finding in
7 of the 9 languages checked so far that have any generics-like syntax (java, typescript, go,
python, rust, csharp, kotlin — swift makes it 7, counting go's "generics unsupported at all"
as the same underlying gap family). The two exceptions: cpp was found to already be immune
(its func_start/class_start already carried the one-level-nesting idiom from a pass predating
this epic — only args needed it, per Extraction hardening: cpp #821), and c has no generics at all. At this point the
prior default ("assume clean until proven otherwise") should flip: assume any new language's
generic-parameter step-over has this bug until empirically disproven, and check it as literally
the first thing for any future generics-capable language. swift's variant was specifically
triggered by Swift 5.7+ primary associated type constraints
(
func foo<T: Collection<Int>>(x: T) {) — a different concrete syntax shape than java's inlinebounds or python's PEP 695, but the exact same flat-
<[^>]*>root cause and fix.(new, from Extraction hardening: swift #824) Recurring class 3 confirmed on an EIGHTH language (swift, via BOTH
triple-quoted multi-line strings and
#"..."#raw string literals — two distinct string formsreproducing the same architectural gap in one language).
(new, from Extraction hardening: scala #825) The Rule-16 identifier-grammar gap (doc's "Identifier Capture Classes Must
Match the Language's Real Grammar" rule) showed up as a genuine cross-language finding, not
just a Scheme-specific curiosity. Scala's
func_start/argsname capture required a plain[a-zA-Z_]\w*, so any backtick-quoted arbitrary identifier (Scala's escape hatch forreserved-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 analternative 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 theidentical gap, missed during Extraction hardening: kotlin #823's pass (backtick wasn't on that pass's checklist yet) --
filed as a dedicated follow-up rather than reopening Extraction hardening: kotlin #823.
(new, from Extraction hardening: scala #825) A
_dependency_capturerule with NO statement-boundary logic at all (notjust a character-class gap like recurring class 19) can silently merge multiple real import
statements into one garbage capture. Scala's capture was a single flat
[\w.{}\s,]+class with no anchor stopping it at the end of one logical import -- since\smatches newlines, on a realistic multi-import file it kept consuming across the SECONDimportline and into the following unrelated statement, so the second import was neverseparately detected.
crucible_check.pyagainst the real Kafka scala corpus confirmed theseverity 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_capturerule using a bare\s(rather than a real statement boundary)for this same bleed-over risk, not just for missing symbols.
(new, from Extraction hardening: scala #825) A confirmed real bug's
crucible_check.pydiff can legitimately ripple intocompletely unrelated languages/repos, and that's NOT a confinement violation by itself --
check whether the ripple is confined to GLOBAL/cross-repo metrics. Fixing scala's
_dependency_capturebleed-over (recurring class 34) changed the shared cross-repo dependencyDAG's topology (the whole corpus is scanned as one graph, per
network_risk_sensor.py'sPageRank/blast-radius scoring and
spatial_mapper.py's 3D projection), which shiftedTopological 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-scopedrules), expect and check for this shape of ripple specifically, rather than assuming any
non-target-language diff line is automatically a confinement bug.
(new, from Extraction hardening: powershell #834) Rule 11 also manifests for a flat PARENTHESES-wrapped parameter/argument
list, not just generic type parameters. PowerShell's
argsrule (param(...)andfunction NAME(...)) used the flat\([^)]*\), truncating at the FIRST)-- breaking on adefault-value expression containing its own parens/array-subexpression syntax
(
param($Tag = @('Slow', 'Feature')), a realistic, common idiom). Confirmed severity viacrucible_check.pyagainst the real corpus: a well-known PowerShell Core file's detectedparameter 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/squaregenerics -- check any flat
\([^)]*\)parameter-list rule for this, not just generic-bracketrules.
(new, from Extraction hardening: powershell #834) Adding coverage for a bare, unprefixed declaration shape
(
Identifier(params) { body }, no keyword, no return-type marker -- PowerShell classconstructors) 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 flatregex. 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 asrecurring class 21, but at authoring time via manual verification rather than via a corpus diff.
Check for this collision risk BEFORE shipping any bare-identifier-plus-body alternative in a
C-family-control-flow language, not after.
(new, from Extraction hardening: powershell #834) A modifier/scope prefix attached to an identifier via a delimiter can make a
capture group swallow the PREFIX instead of the real name -- silently wrong data, not just a
non-match, and easy to miss in review. PowerShell's scope qualifiers (
global:/script:/local:/private:before a function name, e.g.function global:Foo {}) aren't in theidentifier character class, so the capture stopped at the delimiter and returned the scope
keyword itself (e.g. "global") as if it were the function name. Same root shape as Rule 16
(identifier grammar) but the failure mode -- confidently wrong output vs. a safe non-match -- is
worse and doesn't show up as a dramatic test failure the way a non-match does.
(new, from Extraction hardening: powershell #834) An "optional quote pair" idiom (
['"]?...['"]?) around a capture classthat excludes whitespace is a DIFFERENT bug shape from recurring class 19 (a missing symbol) --
it truncates any quoted value containing that excluded symbol even though quoting should have
protected it. PowerShell's
_dependency_captureused exactly this shape, so a quoted pathcontaining a space (
'C:\Program Files\MyModule\MyModule.psd1', an extremely common Windowsidiom) silently truncated at the first space. Fix: real per-quote-style alternatives (a quoted
branch permitting the excluded symbol inside real quotes, a separate bare/unquoted branch that
still excludes it), not just widening the shared class -- widening it would also re-break the
original over-capture problem the optional-quote shape was trying to avoid.
**(new, from Extraction hardening: powershell #834)
_dependency_capture's comment-lookalike vulnerability (recurring class 3'sshape) 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 canstill be vulnerable via a DIFFERENT unshielded-content vector: PowerShell here-strings
(
@"..."@) land their inner content at true line start with no blocking marker, soimport-shaped text inside one still produces a phantom dependency edge. Check comment- and
string-literal vectors independently per language/rule -- confirmed immunity to one vector
doesn't imply immunity to the other.
(new, from Extraction hardening: yaml #843) A "block requires an immediate newline after its header key" idiom
(
with:[ \t]*\n...) breaks on a trailing same-line comment on the header itself(
with: # inputs for this action\n node-version: '18'), a real CI-YAML authoring style.Same general shape as recurring classes 5/6 (an unaccounted-for optional element between two
required tokens) but for a block-header-to-body transition specifically, in a YAML/CI-config
context rather than a code-language declaration. Fix: allow an optional
(?:#.*)?before thenewline. Check any language/rule with a "header line, then indented body" shape for the same
gap if that language's comment marker can appear on the header line.
(new, from Extraction hardening: yaml #843) A "declaration name, then immediately the thing we care about" shape can be
too strict when real usage inserts OTHER keys/statements in between -- not just a nesting
problem (Rule 11), a SEQUENCING problem. YAML's
class_startrequireduses:/image:to bethe 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-overfor 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 differentroot shape from Rule 11 (which is about a delimiter/bracket's own CONTENT nesting) -- here the
gap is between two SIBLING lines/statements, not inside one expression. Check for this shape
whenever a rule assumes its target keyword is the immediate next line/token after an anchor,
when the real language allows other optional statements in between.
(new, from Extraction hardening: yaml #843) An "optional-quote" idiom can ALSO be missing entirely (not just shaped
wrong, per recurring class 39's finding for PowerShell) -- and the fix for two structurally
identical rules (
importand_dependency_capturesharing nearly the same pattern) only needsapplying to the one that's actually in the four-gauntlet scope. YAML's
_dependency_capturehad NO quote-tolerance at all for
uses:/image:values (unlike PowerShell's rule, which HADquote tolerance but with the wrong shape) -- a quoted value (
uses: "actions/checkout@v4", areal 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) wasdeliberately left unfixed -- out of the four-gauntlet scope for this issue, not overlooked.
(new, from Extraction hardening: shell #835) A rule scoped to "this token in its bare/simple form" can miss the
language's own DEFAULT-VALUE or FALLBACK-EXPRESSION variant of that exact same token, even
though the fallback variant is arguably the more common real-world shape. Shell's
argsrulematched a bare positional parameter (
$1) and a simple braced form (${1}/${10}) but had noallowance for bash's
:-/:=/:?/:+default-value/error-message/assign/alternate operators(
${1:-default}) -- arguably THE most common way a positional parameter actually appears inreal scripts, entirely invisible to the rule. Confirmed via
crucible_check.py's real diff (onereal 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 "anamed reference in its simple form" for the same gap if that language has a fallback/default
expression syntax built around the identical token.
(new, from Extraction hardening: shell #835) A keyword-exclusion lookahead guarding a bare-call-shaped alternative can be
INCOMPLETE relative to the language's own full reserved-word set, not just wrong in shape (a
generalization of recurring class 7's bare-call-ambiguity class specifically for the exclusion
list's own coverage). Shell's
func_startexcluded only 5 of bash's ~17 word-based reservedwords (
if/while/for/case/until) from its POSIXname()branch --done() {,elif() {,select() {,function() {, etc. all falsely matched as function definitions.None of these are valid bash (a reserved word can't legally be a POSIX function name -- the real
parser errors on it), but this is a regex-only engine scanning arbitrary/malformed text, so the
same defensive intent behind the original partial list applies equally to the rest. Fix: widen
the exclusion to the full reserved-word set. Check any keyword-exclusion lookahead for
completeness against the language's ACTUAL full reserved-word list, not just the handful that
happened to be top-of-mind when the rule was first written.
(new, from Extraction hardening: makefile #844) An assignment-operator lookalike can hide behind a rule's own declaration
delimiter when that delimiter is a PREFIX of the assignment operator's own spelling. Make's
func_starttreated any bare:/::as a real target-defining colon, with no exclusion for animmediately-following
=-- soMY_VAR := valueandMY_VAR ::= value(GNU Make's ownimmediate-expansion assignment operators, arguably THE most common modern Make idiom) were both
misidentified as target declarations, since
:=/::=both START with the exact colon shape therule 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 thatsame character as a prefix of one of its own assignment/operator tokens.
(new, from Extraction hardening: makefile #844) Widening a rule to accept a real multi-token shape (here: multiple
space-separated target names before one shared colon) can reopen an unrelated false-positive
vector purely by giving the match "more license to keep looking" past the first token --
independent of whatever the widening was actually trying to fix. Make's
func_startgainedmulti-target support (
a b c: dep), but this let a RECIPE line's later words (a URL's://, abare time value
10:30) get treated as trailing co-target tokens followed by a realtarget-defining colon. The fix wasn't to narrow the widening itself -- it was to exclude the
entire false-positive vector's PRECONDITION: recipe lines are unconditionally tab-initial in
Make's own lexical rules (never a directive, absent a custom .RECIPEPREFIX), so narrowing the
rule's leading-whitespace class from "spaces or tabs" to "spaces only" structurally blocks every
recipe line from ever reaching the widened path, without constraining the widening's own logic.
When widening a rule to accept more of a real shape, re-run the FULL invalid/pathological tier
afterward, not just the new cases being added -- a widening can regress unrelated existing
coverage in ways the new cases alone won't surface.
(new, from Extraction hardening: makefile #844) A language's own escaping convention for its trigger character can produce a
lookalike that's structurally indistinguishable from a real reference without checking what
precedes the trigger. Make's
argsrule 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 ownmacro-call mechanism (since Make's own
$expansion already happened one layer up by the timethe shell sees it). Fix: a negative lookbehind so the trigger
$can't itself be immediatelypreceded by another
$. Check any rule whose trigger character is ALSO the language's ownescape-doubling character for a lookalike this exact shape.
(new, from Extraction hardening: cobol #854) A declaration paragraph's grammar can have real, standard trailing clauses
that the rule's "name then immediately the terminator" lookahead has no allowance for at
all -- not a nesting problem (Rule 11), not a sequencing problem (recurring class 42), but a
missing OPTIONAL-SUFFIX-GRAMMAR problem. COBOL's
class_startrequired the entity name to beimmediately 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: abounded (max 6) run of additional clause words between the name and the terminator, safe
because the loop requires whitespace before each word and a bare period always stops it at the
real statement boundary. Check any name-then-terminator rule against the FULL declaration
grammar (not just the bare/minimal form) for optional trailing clauses.
(new, from Extraction hardening: cobol #854) Widening a rule's trailing-content allowance can resurrect a SPECIFIC prior
finding for a DIFFERENT keyword sharing the same alternation -- not a generic regression, a
targeted one tied to which keywords the widened rule covers. Recurring class 49's own fix
(widening COBOL's
class_startto accept trailing clause words) reopened a false-positivevector for two OTHER keywords in the SAME alternation (
FACTORY./OBJECT., standaloneOO-COBOL markers that are ALWAYS immediately followed by a division header, never a real
trailing clause) -- with the loop now wide enough to eat one extra word, "IDENTIFICATION"/
"PROCEDURE" got miscaptured as the entity name and "DIVISION" got swallowed as if it were a
clause word. Fixed by excluding "DIVISION" from the trailing-clause loop specifically (no real
PROGRAM-ID/CLASS-ID/INTERFACE-ID clause legitimately contains that word). When a rule's
alternation covers MULTIPLE distinct keywords, check whether a widening meant for SOME of them
changes behavior for the OTHERS -- caught here by a same-PR regression test written specifically
to confirm the pre-fix "this doesn't happen" assumption, which then failed once the fix landed.
(new, from Extraction hardening: cobol #854) A parameter-list rule with two clause-introducing keywords sharing the same
identifier-name alternative can have one clause's capture bleed straight through the OTHER
clause's own keyword and swallow its parameter too. COBOL's
argsrule captured USING'sparameter 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.
(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_starthad no allowancefor a schema-qualified name (
CREATE TABLE main.users (...),CREATE TRIGGER main.my_trigger ...-- standard syntax for ATTACHed databases or explicittemp.targeting). Since\wneverspans a literal
., the pattern couldn't capture "main.users" as one token and had no way toskip 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 thecapture. Check any declaration rule in a language with namespace/schema/module qualifiers
(
a.b,a::b,a->b) for this exact gap.(new, from Extraction hardening: sqlite #836) A rule scoped to bare identifiers can have ZERO allowance for the language's
OWN native identifier-quoting mechanism -- and quoting to avoid a reserved-word collision (the
single most common real reason to quote at all) means even a completely unremarkable,
special-character-free name is invisible. SQLite's
func_start/class_starthad no supportfor any of its three quoted-identifier styles (
"name",`name`,[name]) -- soCREATE VIEW "group" AS ...(quoting only because "group" collides with a keyword) failedoutright, same as a name containing a genuinely special character (a space). Fix: added the
three quoted forms as alternatives inside the SAME capture group (quotes included in the
captured text, verified harmless since the harness/consumer both do substring/membership
checks) rather than new numbered groups -- critical here because detector.py reserves capture
group 2 specifically for class_start's inheritance-parent extraction on other languages; adding
real new groups would have silently shifted that convention. Check any declaration rule in a
language with native identifier quoting for this exact gap, and prefer widening the SAME group
over adding new ones for any rule where group position carries meaning elsewhere in the engine.
(new, from Extraction hardening: sqlite #836) Rule 11's nested-delimiter shape, reconfirmed for SQL specifically: a flat
\([^)]{0,N}\)inside an IN/VALUES clause truncates at the first closing paren of a nestedsubquery.
IN (SELECT id FROM (SELECT id FROM other))(a real, common nested-subquerypattern) silently ended the match one paren early instead of covering the whole clause. Same
fix as every other language in this epic: the one-level-nesting-safe idiom, bounded on both the
inner and outer repetition.
(new, from Extraction hardening: sqlite #836) An alternative's anchor can be far NARROWER than the dominant real-world
form -- not wrong in character class or nesting, but scoped to the WRONG position in the
statement. SQLite's
argsCTE alternative required the CTE name at TRUE line start, but thesingle most common way to write a CTE is inline, immediately after the
WITHkeyword on theSAME line (
WITH cte_name (col1, col2) AS (...)) -- never matched at all. Fix: added a secondanchor alternative (immediately after
WITH/WITH RECURSIVE) alongside the original line-startone, without introducing a new capture group (this rule has zero groups by design -- every
alternative is checked via whole-match substring). Check any rule anchored to "start of
statement" for whether the dominant real-world form actually places the target token
mid-statement, right after a specific keyword, instead.
(new, from Extraction hardening: sqlite #836) A historical vertical-whitespace fix applied to one rule is not automatically
applied to a SIBLING rule sharing near-identical optional-clause structure, even in the SAME
language file. SQLite's
func_startalready has a documented "VERTICAL MODIFIER SHIELD" fixfor its own
IF NOT EXISTSclause (using[ \t\n]+throughout, including the gap right beforethe captured name).
class_start's OWN parallelIF NOT EXISTSclause (forCREATE TABLE)was never given the same fix -- its trailing gap stayed
[ \t]+(no newline), soCREATE TABLE IF NOT EXISTS\n users (...)(a real, common vertical formatting style) silently captured"IF" as the table name instead of "users". Found via this issue's OWN pathological test case,
not a pre-flagged finding. Check every rule in a language file against fixes already applied to
its OWN siblings, not just fixes documented for OTHER languages.
(new, from Extraction hardening: sqlite #836) A test that hardcodes a capture-group INDEX for a multi-alternative rule is
fragile to legitimate future restructuring, even when the real consumer never cared about the
index in the first place.
test_sqlite_dependency_capture_extracts_pathassertedm.group(2) == "json1"for load_extension specifically -- correct under the OLD numbering, butrecurring 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. Updatedthe test to match that same convention instead of re-hardcoding a new number, so the NEXT
legitimate restructuring won't break it again. Write new tests for multi-alternative,
multi-group rules the same way from the start.
(new, from Extraction hardening: agc_assembly #857) An opcode/keyword whitelist can be an unvalidated ad hoc SUBSET of the real
language's instruction set, inconsistent with what SIBLING rules in the SAME language file
already recognize as legitimate. AGC assembly's
func_startwhitelisted only 16 opcodes,missing ~25 real, common instructions this SAME file's own
branch/args/safety/state_mutationrules already recognized (CAF,TCF,XCH,LXCH,AD,MASK,INCR,RELINT, etc.) -- confirmed empirically against the real Apollo 11 corpus that the oldwhitelist missed roughly 33% of real label+opcode pairs, with
CAF(94 occurrences) among thesingle most common AGC instructions entirely absent. Check every keyword/opcode whitelist
against the UNION of what its OWN sibling rules in the same file already treat as legitimate,
not just against general outside knowledge of the language -- internal inconsistency within one
file is a strong, cheap signal of an incomplete list.
(new, from Extraction hardening: agc_assembly #857) Empirical corpus cross-validation (grep the real corpus, count matches
before/after a candidate fix) is the ONLY way to catch an "incomplete whitelist" class of bug --
self-consistent regex testing cannot, because the test cases are themselves typically derived by
observing the regex's OWN (possibly buggy) behavior, not the real language's ground truth.
Every other recurring class in this epic is a shape/structure bug findable by constructing an
adversarial payload and checking the regex's behavior in isolation; this class requires stepping
outside the regex entirely and asking "how much of the REAL corpus does this actually match, and
does that number make sense" -- a 40% miss rate against real source was invisible to 136 unit
tests that all only checked internal consistency, but obvious the moment the corpus was queried.
(new, from Extraction hardening: agc_assembly #857) AI-authored test coverage can enshrine EXISTING (buggy) behavior as
"correct" without ever validating it against the real language's grammar or corpus -- an
"invalid" test case can literally BE the bug, framed as if it were an intentional exclusion.
A prior PR's test suite (agc_assembly, claimed "zero bugs found, patterns already extremely
robust") included
"MYLABEL\tTCF INTERNAL"in itsinvalidlist with the comment "TCF is notin the opcode list" -- true of the code as written, false of real AGC assembly, where TCF is one
of the most common branch instructions. The suite was internally consistent and thorough in
breadth (136 tests, all four tiers, real whitespace/pathological variety) but never once
checked whether the thing being tested was actually correct against ground truth -- it treated
"matches the current regex's behavior" as the definition of "valid" test coverage. When
reviewing (or writing) test coverage for a language rule you have not independently corpus-
validated, do not trust that "all tests pass, zero bugs found" means the underlying rule is
correct -- it only means the tests agree with whatever the code already does. Cross-check
"invalid" cases specifically against real spec/corpus before accepting them, since those are
exactly where an existing bug hides in plain sight as a passing assertion.
(new, from Extraction hardening: assembly #856) A register/opcode alternative can simultaneously match a FICTIONAL form and
miss the REAL one, when a trailing
\bis assumed to separate a base token from a suffix that isitself a word character. Assembly's
argsrule used[er][89]intending to extendr8/r9coverage, but
e8/e9are not real x86 registers -- the pattern actually matched a phantomregister while
\bafter[89]silently prevented the REALr8d/r9d/r8w/r9w/r8b/r9bsub-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 recurringclass 60. Fixed to
r[89][dwb]?, and separately closed a real coverage gap this review alsofound: assembly's own
_meta.target_versionexplicitly states "Backwards Compatible", yetargshad 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
bootosbootloader) uses as its de facto argument-coupling convention. When a suffix-bearing alternative sits next to a bare base form in the same
alternation, check both directions empirically: does it match text that isn't a real register,
and does it fail to match the real suffixed forms it was presumably added FOR.
(new, from Extraction hardening: assembly #856) A corpus-impact quantification (
OLD.finditervsNEW.finditermatch counts,the pattern established in classes 58-59) must run against the pipeline's actual comment-stripped
code_stream(viaPrism.split_streams), not raw file text, or the "before/after" number can besubstantially inflated by matches that would never reach the rule in production. Assembly's
argsfix looked like a +391% improvement (135->663) against raw file text, but a large share ofthe 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
Prismpipeline (which strips;/#line comments for any"lexical_family": "line_exclusive"language beforedetector.pyever sees the code) gave the honest number: 84->305 (+263%), still a large genuine improvement,
concentrated in exactly the 16-bit bootloader code the fix targeted -- confirmed clean by manually
inspecting a sample of the new matches' containing lines. A large raw-text delta is a hypothesis
to verify against the real pipeline, not a number to report as-is.
Related architectural issue filed from this epic's verification work
prism.py's comment/string stripping corruptedcode_streamfor atleast two real PHP corpus files (docblock text bleeding through mangled) — root cause was a
broken
PHP_MULTILINE_STRINGextraction step, now removed entirely. Found while verifying theshared
_slice_by_bracesstring-shielding fix below, which was deliberately gated tojavascript/typescript only at the time. Now that prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859 is fixed, broadening that gate to other
Mode B languages is unblocked — worth its own follow-up PR (confirm no other language has a
similar latent
prism.pygap first viacrucible_check.py, don't just flip the gate open).Tooling built during this epic (use these, don't rebuild them)
tests/extraction/tools/verify_candidates.py— reusable empirical-verification harness(
check_case/check_many/check_redos_scaling+ a CLI) for the methodology's "verify everycandidate case before adding it" step. Replaces writing a throwaway checker script per language.
tests/tools/audit_check.py— bundlesruff format --check+ruff_audit.py --ci+mypy_audit.py --ci+dead_key_audit.py --ciinto one command, with automatic pure-line-shiftdetection (
--regenerateauto-fixes baselines whose new findings are ALL shifts; anythinggenuine is left for manual review, never silently accepted).
tests/tools/crucible_check.py --update --yesalready existed and does the full two-venv golden-master regeneration in one call — no need to hand-build/activate venvs; several early sub-issues
in this epic did that manually before this was noticed, wasting real tokens each time.
Progress
javascript— the shared string-literal false positive fixed earlier (PR Fix javascript/typescript func_start string-literal false positive #860, gated tojs/ts; broadening now unblocked by prism.py: PHP docblock/comment stripping corrupts code_stream (found via extraction-hardening epic #813) #859, see above). Extraction hardening: javascript #814 itself (this sub-issue's own
valid/invalid/pathological case expansion) closed with 1 additional real bug fixed:
func_start/argshad no allowance for ES6 generator method shorthand (*foo() {},async *foo() {},static *foo() {}) — completely invisible before the fix. The FIRSTversion of that fix introduced a NEW false positive (JSDoc comment prose hallucinated as a
generator method), caught via
crucible_check.pyagainst real corpus code and corrected —see recurring class 21 above for the full story and the general lesson.
crucible_check.pyshowed 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_captureside-effect-only imports), 2 known limitations documented (bare-call ambiguity, 2+-level
generic nesting / type-annotation-with-own-arrow)
java— closed via Extraction hardening: java #816, 3 real bugs fixed:func_start/argsshared the flat<[^>]*>Rule-11 bug (one-level-nested generic bounds, e.g.
public static <T, U extends Comparable<U>> T Foo(T a, U b) {, broke both rules identically since they share the samemodifier-alternative shape);
class_starthad no generic step-over at all before itsextends/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 realfindPluginIdForClassmethod in gradle'sDefaultPluginManager.java, the corpus's onlydiff). 2 known limitations documented, not fixed (architectural, out of scope for a single
language):
func_starttext-block false positive (recurring class 3, confirmed on a secondlanguage) and
_dependency_capture's broader unshielded-content_buffergap (new recurringclass 10).
go— closed via Extraction hardening: go #817, 1 real bug fixed:func_starthad no generic type-parameterstep-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 completelyinvisible. Notably
class_startandargsalready had the correct step-over — onlyfunc_startwas the outlier (see recurring class 13 above; don't assume a generics gap inone 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_startand_dependency_capture(recurring class 3, nowconfirmed on a third language/feature — see recurring class 14 above).
python— closed via Extraction hardening: python #818, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding):func_start/args/class_startall shared a flat[^\]]*PEP 695 (3.12+) generic-parameterstep-over, breaking any nested-bracket type bound (
def Foo[T: Sequence[int]](x: T) -> T:) --the square-bracket variant of the same Rule-11 bug class (recurring class 15 above);
class_startsilently lost its base-class capture rather than failing outright, same failureshape as java's Extraction hardening: java #816 bug.
crucible_check.pyshowed a zero diff (expected -- PEP 695 has zeroreal-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 shieldsstrings/comments before matching -- unlike Mode B, there is NO live string-literal false-
positive bug for python in the real pipeline (recurring class 16 above; this is the reference
implementation the eventual Mode-B broadening should mirror). 1 known limitation documented,
not fixed:
_dependency_capture's unshielded-content_buffergap (recurring class 10, sameas every other language).
rust— closed via Extraction hardening: rust #819, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):argsnever received the two-level-nesting Rule-11 fix thatfunc_startalready had from anearlier 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-graphedges (recurring class 19 above). Verified confined to rust via
crucible_check.py(4 realcorpus 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_starthad the same missing-generic-step-over bug already seen in java/python(recurring class 22 above) —
class Foo<T> : Base<T> {silently lost the base-list capture;also needed a companion primary-constructor-parameter-list step-over
(
record Foo<T>(T Value) : Base<T>, C# 9+/12) independently of the generic fix._dependency_capturewas entirely missing support for using-alias directives(
using Alias = Target;) — no match at all, not just a dirty capture (recurring class 23above) — 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 anewly-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 forfunc_start/_dependency_capture(recurring class 3, now confirmed on a fifth language).cpp— closed via Extraction hardening: cpp #821, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):func_start/argshad zero allowance for a class-qualifier before theoperatorkeyword,so out-of-line operator overload definitions (
TargetClass::operator=(...),TargetClass::operator==(...), mainstream C++, declared in a header/defined in a .cpp file)were completely invisible even though bare
operator=(...)already worked — a distinctfailure mode from the recurring Rule-11 nesting bug (recurring class 24 above);
argsalsoneeded the established nested-template step-over for the method's own template args
(
Foo::Bar<Baz<int>>(...)). Verified confined to cpp viacrucible_check.py— 7 real filesacross 4 repos (mlir, NVDA, powertoys, godot) gained newly-detected operator functions/
parameter counts, including NVDA's
storage.cppfunction count jumping 10 → 13 for its 3out-of-line comparison operators. A structural (not textual-grep) diff check was needed to
correctly confirm confinement here — see recurring class 25 above. 1 known limitation
documented, not fixed: raw-string-literal (
R"(...)") false positive forfunc_start(recurring class 3, now confirmed on a sixth language). class_start's lack of a base-clause
capture group was confirmed to be cpp's original, deliberate design (not a regression of the
java/python/csharp bug) — the existing test suite already only ever asserted the entity name.
c— closed via Extraction hardening: c #822, 1 real bug fixed inclass_start(a fresh sweep, not a pre-flaggedfinding): 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 alsoreject 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_injectionrule's_ops-vtable-suffix heuristic(recurring class 28 above). Verified via
crucible_check.py(structural diff, not textualgrep — recurring class 25): cpython's
dictobject.cand micropython'sobjtype.ceachgained a real anonymous/inline-struct detection. The diff also touched
python/numpy,lua/redis,scheme/racket,cobol/gnucobol_internals, andcpp/godot'sobject.h(engine-classified
Language: "C"via sibling-file disambiguation) — all confirmed genuineembedded 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 gapreproduces via un-decorated block comments (not strings — C has no raw strings, and its
per-line-quoted string layout is structurally immune to the string-literal variant, a
genuine negative result — recurring class 27 above).
kotlin— closed via Extraction hardening: kotlin #823, 2 real bugs fixed (a fresh sweep, not a pre-flagged finding):func_start/argsshared a flat<[^>]{0,100}>Rule-11 generic-parameter step-over,breaking any nested generic bound (
fun <T, U : Comparable<U>> foo(x: T, y: U): T {);class_starthad no support forcompanion object { ... }(almost always anonymous) atall — 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.pyfor intentionalkotlin 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_bugstest continues to passunmodified.
crucible_check.pyshowed a zero diff (expected — only 5 kotlin files in thecorpus, zero companion objects among them, confirmed by grep). 1 known limitation
documented:
func_start's Mode-B string-shielding gap reproduces via triple-quoted rawstrings (recurring class 3, now confirmed on a seventh language — recurring class 30 above).
swift— closed via Extraction hardening: swift #824, 1 real bug fixed (a fresh sweep, not a pre-flagged finding):func_start/argsshared a flat<[^>]*>Rule-11 generic-parameter step-over, breaking anynested 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 languageschecked (recurring class 31 above). Checked
test_language_standards_strict.pyforintentional swift behavior before finalizing (per c's Extraction hardening: c #822 lesson) — no conflicts; the
existing
test_swift_ambiguity_sweep_shared_literals_are_not_bugstest passes unmodified.crucible_check.pyshowed a zero diff (expected — only 6 swift files in the corpus, noneusing nested generic bounds, confirmed by grep). 1 known limitation documented:
func_start's Mode-B string-shielding gap reproduces via BOTH triple-quoted multi-linestrings and
#"..."#raw string literals (recurring class 3, now confirmed on an eighthlanguage — recurring class 32 above).
scala— closed via Extraction hardening: scala #825, 3 real bugs fixed (a fresh sweep, not a pre-flagged finding):func_start/argsshared the flat\[[^\]]*\]Rule-11 square-bracket generic-parameterstep-over (the same bug class already fixed for java/typescript/python/rust/csharp/kotlin/
swift, angle-bracket and square-bracket variants both now confirmed broadly);
func_start/argsalso never accepted backtick-quoted arbitrary identifiers at all (recurring class 33above -- also filed as a follow-up for kotlin, which shares this gap);
_dependency_capturehad no statement-boundary logic and silently merged multiple import statements together plus
truncated Scala 3 wildcard (
*) and=>-renamed block imports (recurring class 34 above).crucible_check.pyshowed a REAL diff this time (not a zero diff) -- confirmed genuine viathe 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.pyfor intentional scala behavior before finalizing(per c's Extraction hardening: c #822 lesson) -- no conflicts; existing scala regression tests pass unmodified. 2
known limitations documented:
func_start's Mode-B string-shielding gap reproduces viatriple-quoted strings (recurring class 3, now confirmed on a NINTH language);
_dependency_ capture's unshielded-content_buffergap reproduces via a commented-out import (recurringclass 10, same pipeline-wide, not-yet-fixed issue as every other language).
powershell— closed via Extraction hardening: powershell #834, 4 real bugs fixed (a fresh sweep, not a pre-flagged finding):args/func_startshared the flat\([^)]*\)Rule-11 paren-list step-over, breaking ondefault-value expressions containing their own parens (recurring class 36 above -- confirmed
severe via
crucible_check.py, one real corpus function's detected parameter count jumped3 -> 9); PS class constructors (
Foo([string]$name) { ... }, nofunctionkeyword, noreturn-type bracket) were entirely invisible to
args/func_start-- added as a newalternative, 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 keyworditself instead of the real name (recurring class 38 above);
_dependency_capture'soptional-quote-pair idiom truncated any quoted import path containing a space (the common
Windows
'C:\Program Files\...'shape, recurring class 39 above). Checkedtest_language_standards_strict.pyfor intentional powershell behavior before finalizing (perc's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified.
crucible_check.pyshowed a real diff, confirmed confined entirely topowershell/coreplusits own aggregate rollups (no cross-repo ripple, unlike scala's Extraction hardening: scala #825
_dependency_capturefix-- this language's fixes didn't materially change the shared dependency graph's topology).
Golden master fixtures re-blessed. 2 known limitations documented:
func_start's Mode-Bstring-shielding gap reproduces via here-strings (a TENTH language);
_dependency_capturereproduces 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). Unlikemost languages in this epic, yaml's
_meta.target_versionscopes its rules specifically toCI/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 thereusable-workflow-call/container-job shape (class_start), and an action/image reference
(_dependency_capture), not traditional function/class declarations. Bugs:
args'swith:block required an immediate newline, breaking on a trailing same-line comment on the header
(recurring class 41 above);
class_start's reusable-workflow-call/container-job detectionrequired
uses:/image:to be the literal first line after the job name, missing the commonreal pattern of
needs:/if:/permissions:appearing first (recurring class 42 above, fixedwith a bounded max-10 intervening-key step-over, verified NOT to bleed into an unrelated
subsequent job);
_dependency_capturehad no quote tolerance at all foruses:/image:values, missing a real yamllint-driven quoted-scalar authoring style (recurring class 43
above).
crucible_check.pyshowed a zero diff -- confirmed expected (not "feature is wrong",per recurring class 8) by grepping the actual corpus for all three trigger shapes and
confirming none appear anywhere in it. Checked
test_language_standards_strict.pyforintentional 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 toorisky 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 gauntletsapplied. Bugs:
args's braced form (${1}/${10}) had no allowance for bash'sdefault-value/error-message/assign/alternate expansion operators (
:-/:=/:?/:+), so${1:-default}-- arguably the single most common real-world shape a positional parametertakes -- was entirely invisible (recurring class 44 above);
func_start's POSIXname()keyword-exclusion lookahead only listed 5 of bash's ~17 word-based reserved words, so
done() {,elif() {,select() {,function() {, etc. all falsely matched as functiondefinitions (recurring class 45 above).
crucible_check.pyshowed a real diff, confirmedconfined entirely to
shell/brew(one real Homebrew script's detected parameter count jumped6 -> 10, from the
argsfix) -- no cross-language ripple. Golden master fixtures re-blessed.Checked
test_language_standards_strict.pyfor intentional shell behavior before finalizing(per c's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified. 2 known
limitations documented, both the same pipeline-wide
_dependency_captureunshielded-contentgap as every other language (recurring class 10/11) but confirmed via two INDEPENDENT
vectors this time: a commented-out
# source .envline still matches (the space after#satisfies the rule's own mid-statement boundary requirement, regardless of the
#itself),and a quoted string containing
sourcewith a leading space (echo " source .env") alsostill 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 thefour gauntlets applied. Bugs:
func_start's colon lookahead had no exclusion for animmediately-following
=, soMY_VAR := value/MY_VAR ::= value(arguably THE most commonmodern Make idiom) were misidentified as target declarations (recurring class 46 above);
func_startalso didn't detect multi-target rules (a b c: dep) at all (recurring class 47above) -- fixing this the naive way reopened a NEW false-positive vector (recipe lines with a
URL or time-shaped colon misparsed as co-target tokens), caught before shipping and fixed by
excluding tab-initial lines from the target-declaration path entirely (same recurring class
47, second half);
argshad no awareness of Make's own$$escape convention, so$$1/$$(1)(passing a literal shell positional param through a recipe) were misidentified asreal macro-call references (recurring class 48 above);
_dependency_capturesharedfunc_start's same tab-initial-line vulnerability, letting a recipe command literally named"include"/"sinclude" be misidentified as a real include directive.
crucible_check.pyshoweda real diff, confirmed confined to exactly two real Makefiles embedded in unrelated
repos' corpora (
c/cpython/Makefile.pre.in,lua/redis/Makefile) -- both showing theexpected DECREASE in false-positive function-declaration counts (redis: 42 -> 25). Golden
master fixtures re-blessed. Checked
test_language_standards_strict.pyfor intentionalmakefile behavior before finalizing (per c's Extraction hardening: c #822 lesson) -- caught a real conflict this
time:
test_makefile_func_start_and_macros_no_false_collisiondeliberately locks in that$(1): $(2)(adefine...endefmacro-placeholder shape) must NOT satisfy func_start, whichruled out an initially-planned char-class widening to support variable-referenced target
names (
$(TARGET): $(OBJECTS)) -- documented as a deliberately-NOT-fixed known limitationinstead of overriding the existing test.
import(a sibling, non-gauntlet-scoped rulesharing
_dependency_capture's pattern) deliberately left unfixed, out of scope -- sameprecedent 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 oneinclude 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); allfour gauntlets applied (cobol has a real
class_start, unlike shell/makefile). Bugs:class_starthad no allowance for standard trailing clauses on PROGRAM-ID/CLASS-ID/INTERFACE-ID (
IS INITIAL PROGRAM,IS COMMON PROGRAM,FINAL,INHERITS Base) --recurring class 49 above; fixing that reopened a false-positive vector for the SAME rule's
FACTORY/OBJECT keywords (standalone markers always followed by a division header) --
recurring class 50 above, caught by a same-PR regression test written to confirm the
pre-fix "this doesn't happen" assumption, which then failed once the widening landed;
args's USING capture had no exclusion for the literal word "RETURNING", soPROCEDURE DIVISION USING WS-A RETURNING WS-B.(declaring a parameter AND a return value inone 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 acceptedby modern compilers for legacy support.
crucible_check.pyshowed a zero diff for allfour fixes -- verified this was legitimately because the corpus's real
.cbl/.cob/.cpyfiles contain none of these constructs (grepped directly for segment numbers, INHERITS,
IS INITIAL/COMMON PROGRAM, RETURNING -- zero hits), per recurring class 8's own caution,
not evidence the fixes are no-ops. No golden-master regeneration needed. Checked
test_language_standards_strict.pyfor intentional cobol behavior before finalizing (perc's Extraction hardening: c #822 lesson) -- no conflicts; existing regression tests pass unmodified.
argsandclass_starthad zero prior test coverage in the old monolithic dict files before thisissue. 1 known limitation documented: a multi-line
PERFORM\n TargetFunc.statement (areal paragraph invocation split across two lines) is structurally indistinguishable from a
genuinely new paragraph declaration -- no cross-line statement-context tracking exists (or
is architecturally feasible) for a regex-only engine to resolve this.
sqlite— closed via Extraction hardening: sqlite #836, 8 real bugs fixed (a fresh sweep, not a pre-flagged finding);all four gauntlets applied. Bugs:
func_start/class_startboth had no allowance forschema-qualified names (
main.users, recurring class 52 above) or any of SQLite's threequoted-identifier styles (
"name"/`name`/[name], recurring class 53 above -- addedinside 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 clausetruncated on a nested subquery (Rule 11, reconfirmed for SQL -- recurring class 54 above);
args's CTE alternative required true line start, missing the dominant inlineWITH cte_name (...) AS (...)form entirely (recurring class 55 above);class_start's ownIF NOT EXISTSclause 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 pathcontaining a space, a worse variant of recurring class 39 (PowerShell) confirmed on a third
language.
crucible_check.pyshowed a REAL diff this time (not zero), confirmed confinedentirely to
sql/sqlite files (e.g. a WITH-statement's detected parameter count correctlygrew from 3 to 5 once the CTE/IN fixes landed) -- no cross-language ripple. Golden master
fixtures re-blessed. Checked
test_language_standards_strict.pyfor intentional sqlitebehavior before finalizing (per c's Extraction hardening: c #822 lesson) -- found a real conflict: an existing test
hardcoded a capture-group INDEX for load_extension that the ATTACH quoted-path fix's own
group restructuring shifted (recurring class 57 above) -- updated the test to match
galaxyscope.py's actual "any non-None group" consumption convention instead of re-hardcoding
a new index.
argsandclass_starthad zero prior test coverage in the old monolithic dictfiles 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 adifferent 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 16of 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 mostcommon AGC instructions -- entirely absent; also
TCF/XCH/LXCH/AD/MASK/INCR/RELINT/etc.);args's register-coupling opcode list was missingAUG/DIM/INCR. Theoriginal suite's own
invalidlist literally asserted"MYLABEL\tTCF INTERNAL"must NOTmatch, with the comment "TCF is not in the opcode list" -- true of the code, false of real
AGC assembly, where TCF is one of the most common branch instructions; this is the clearest
concrete instance yet of recurring class 60. Confirmed the fix's real-world impact directly
against the Apollo 11 (Luminary/Comanche) source corpus in language-crucible: total
func_startmatches rose from 609 to 812 (+33%) with zero new false positives against data/constant pseudo-ops (
OCT/OCTAL/DEC/2DEC/ADRES/EQUALSall correctly stay excluded).crucible_check.pyshowed a real diff -- confirmed the only CONTENT changes (not just global-aggregate/topological-coordinate ripple, which touched several unrelated files/languages as an
expected side effect of agc_assembly's structural mass shifting) were in
agc_assemblyitself;real Apollo 11 subroutines like
SPVAC/NEXTCORE/JOBWAKE3/SUPDXCHZ/VACFOUNDthat werepreviously 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 adifferent contributor, not this session) found no bugs across all four gauntlets. Independently
reviewed given the pattern from
agc_assemblyabove;func_start's "neutralize a dead negativelookahead" 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-prefixedlocal data labels).
class_startand_dependency_capturewere independently audited and foundclean (zero false positives against real corpus text containing lookalike prose/C-
structmentions; a real
.incbin APE_LOADERbare-identifier form correctly captured). 1 real bug foundin
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/e9while failing to match the realr8d/r9d/r8w/r9w/r8b/r9bforms (recurring class 61 above); also closed a genuine coverage gap thisreview found independently -- zero support for the legacy 8/16-bit x86 register set despite
the language's own
_meta.target_versiondeclaring it "Backwards Compatible". A first raw-textcorpus quantification looked like +391% (135->663) but turned out to be substantially inflated
by matches inside
;-prefixed prose comments; re-run against the realPrism-strippedcode_streamgave the honest, still-substantial number: 84->305 (+263%), concentrated in thebootos16-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.pyconfirmed 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
validcasesand add dedicated regression tests for both the phantom-vs-real-suffix bug and the legacy-
register gap.