Skip to content

Audit wave 1 - #7

Merged
ojassug merged 2 commits into
mainfrom
audit-wave-1
Aug 10, 2026
Merged

Audit wave 1#7
ojassug merged 2 commits into
mainfrom
audit-wave-1

Conversation

@ojassug

@ojassug ojassug commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

ojassug and others added 2 commits August 9, 2026 22:23
…variable is not a symbol

Closes audit C1b and §3.2. Two changes that only work together — landing
either alone is measurably worse than landing both.

The audit's proposed fix is inert. §3.2 proposed computing `R_struct` over
`extractContentMarkers`, excluding the `filepath:` marker that no content
transform can destroy, and stated it "would fix both cases at once". Measured, it
fixes neither: removing the only marker an item had leaves the before-set empty,
and an empty set defaults `R_struct` back to 1.0 — the identical free 0.40 by
another route. That change alone was byte-identical across all 586 rows of a
frozen 293-file corpus.

The free 0.40 comes from the empty-set default, not from `filepath:`. So an
unmeasured ratio is now excluded from the score rather than defaulted, with its
weight redistributed to the ratio that did measure something. For code
`S_k = 1 - R_AST`, and the maximum symbol loss that can pass the 0.40 gate falls
from 66.7% to 40%. When neither ratio measured, retention returns 1.0 and stays
silent — that case belongs to the measurement gate (§37), and having both refuse
would attribute the refusal to the wrong question. This is §33's argument applied
to the score rather than to the gate.

Applied on its own that cost 14 TypeScript files and 11.75pp, and the loss it was
guarding against turned out to be almost entirely fictitious. `extractSymbols`
matched `const|let|var` anywhere, so every `const i`, `const result`, `const msg`
inside a function body counted as a semantic symbol on par with an exported
function — and body elision is precisely the transform that removes them.
Measured at `targetReductionRatio: 0.5`:

  src/core/engine/index.ts       42 of 63 symbols "lost", 41 function-local
  src/core/hashing/tokenizer.ts   9 of 17 symbols "lost", all 9 function-local

Not one exported function, type or interface was lost in either case, because
`selectElisionRegions` retains signatures by construction. The audit's "you can
destroy two-thirds of every symbol in a file and pass" was measuring temporaries
inside bodies the caller asked to have elided.

Python is the control, and the asymmetry is what identified the defect: its
extractor never had a locals rule, its measured symbol loss under the same
elision is 0.0%, and it is untouched by either half. A safety metric should not
depend on which language's extractor happens to harvest block-scoped bindings.

Measured over the frozen corpus, 586 rows, both routes:

  arm                  TS files   TS saved   Python
  before (§37 only)          22     14.00%   14.98%
  C1b alone                   8      2.25%   14.98%
  symbol fix alone           30     25.59%   14.98%
  both (shipped)             29     23.38%   14.98%

The gate is stricter and reduction is higher, because it now measures semantic
loss instead of noise. Python, prose and every uncovered-language bucket are
unchanged.

One file regresses: `src/cli/html-reporter.ts`, whose sole content marker is
`TD_PRESERVE:` harvested from a regex literal in the file that implements syntax
highlighting for that directive. Its own pattern source is its only structural
evidence. Left in deliberately — it fails conservatively (byte-identical
fallback, no data loss), it is 1 file in 57, and special-casing it would over-fit
the metric to one file in this repository.

Two hazard-pinning tests asserted properties this abolishes, and were updated
with their findings preserved rather than overwritten: the 0.60 "ceiling for
code" (which was the symptom, not a safety property) and C1a's note that the
retention gate could never fire for markdown (it now does, and the measurement
gate remains the guard for the no-markers case).

Known residue, recorded not fixed: `extractSymbols` still harvests from comments,
because it is regex over raw content with no lexer — `fn:of` from "pure function
of its input", `type:of` from "that class of bug". After the locals fix that is
the entire remaining symbol loss on `src/core/engine/index.ts`, 1 of 22.

See DECISIONS §40.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audit C1b: a ratio that measured nothing does not vote, and a local variable is not a symbol
@ojassug
ojassug merged commit 4e60949 into main Aug 10, 2026
3 checks passed
@ojassug
ojassug deleted the audit-wave-1 branch August 10, 2026 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant