Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,11 @@ deno task paren:audit # authoring-independence over redundant PAR
# (`a ?? b ?? c`) must format identically to the twin prettier rebalances it from
# (`a ?? (b ?? c)`). Zero-tolerance, no ratchet — a redundant paren carries no authoring
# signal, so every divergence is a bug. The class is invisible on every paren-free
# authoring, which is every authoring a formatted corpus holds (bug539)
# authoring, which is every authoring a formatted corpus holds (bug539). Also the
# relational `<`…`>` chain: `a < X > c` against `(a < X) > c` and `a < (X) > c`, the
# redundant shells that can move its byte-read type-argument pair. `--require-relational`
# (passed here, not by `audit:corpus`) adds a floor on relational sites, which only
# tests/fixtures holds — a narrowed run drops it
deno task fuzz:audit # seeded mutational fuzzer (fixed seed/iterations): no-panic + idempotency + structural reparse (node loss HARD, skeleton divergence soft); its token dictionary carries `// prettier-ignore`, the only standing instrument that composes a freeze with a comment or a paren shell
deno task swallow:audit # `//` line comment swallowing following output-line content (also over real code via audit:corpus)
deno task comments:audit # print-once comment ledger: DROPPED / DOUBLE-PRINTED comments
Expand Down
6 changes: 6 additions & 0 deletions benches/js/corpus_audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
* sweep below. Real code carries twice the fixture corpus's chains, and the class it gates is
* one a corpus of formatted code cannot otherwise show: the paren-nested authoring is exactly
* what tsv's own output normalizes away (docs/audits.md §Paren-Authoring Independence).
* Run WITHOUT `--require-relational`, which `deno task paren:audit` (the fixture-tree gate)
* passes: that flag is the audit's per-class vacuity floor over its relational `<`…`>` sites,
* and it is a claim about the SEED SET rather than about the audit. Nobody writes `a < b > c`
* in real code, so both relational rows are legitimately 0 here and a floor over them would
* fail a clean run. This leg still grades every relational site it finds; it holds only the
* unconditional total floor.
* - `census_audit` — every comment interior the author wrote survives formatting, compared as raw
* input-vs-output trivia multisets by the audit's own scanners. All dirs. This is the leg whose
* yield is external corpora *by its own design* — over `tests/fixtures` it is a tripwire, and its
Expand Down
46 changes: 43 additions & 3 deletions crates/tsv_debug/src/audit/vacuity.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
//! The **vacuity guard** — the two checks that stop a gate over nothing from
//! The **vacuity guard** — the checks that stop a gate over nothing from
//! reading as a green gate.
//!
//! Every audit's happy path prints a `✓` and exits 0, and so does an audit that
//! graded nothing at all: an empty walk, a corpus the parser rejects end to end,
//! a fixture tree that silently shrank. The two layers here answer that at the
//! two scopes a run can have:
//! a fixture tree that silently shrank. The layers here answer that at the
//! scopes a run can have:
//!
//! - [`check_graded_nonzero`] — **scope-relative**, called unconditionally by
//! every corpus-walking audit. Zero graded is vacuous whatever the paths, so it
//! needs no pin.
//! - [`check_formatted_min`] + [`FIXTURES_FORMATTED_MIN`] — **default-corpus**,
//! called only on a full default run. It grades a *shrink*, which only a run
//! over the committed fixtures tree can be held to.
//! - [`check_required_nonzero`] — **seed-set**, asked for by an explicit flag.
//! It grades a sub-population that only some corpora hold, so the invocation
//! that knows its seeds carry the population is the one that claims it.
//!
//! Its own module rather than [`super::sweep`]'s (where it was born) because the
//! floor is a question about an audit's DENOMINATOR, not about that loop: nine
Expand Down Expand Up @@ -132,3 +135,40 @@ pub(crate) fn check_graded_nonzero(graded: usize, subject: &str) -> Result<(), C
);
Err(CliError::Failed)
}

/// The **seed-set** layer: a floor over a SUB-population, asked for by the `flag` the
/// invocation passes. `subject` names what was counted; `flag` is the switch to drop.
///
/// [`check_graded_nonzero`] is a claim about the AUDIT — zero graded is vacuous whatever the
/// paths, so no invocation may opt out of it. This one is a claim about the SEED SET: a
/// sub-population an audit grades may be dense in one corpus and legitimately absent from
/// another (a construct real code does not write), and there zero is the correct reading, not
/// a defect. So the floor belongs to whichever invocation knows its seeds carry the
/// population, rather than to the audit — and it is spelled as an explicit flag rather than
/// inferred from the paths, because a flag is greppable and cannot silently mean the wrong
/// thing on a subtree run.
///
/// A NARROWED run under the flag fails, deliberately and like a ratchet's `:update`: the flag
/// asserts the run covers the population's corpus, which a subtree does not. The message says
/// to drop the flag rather than to widen the paths, since a narrowed run is an ordinary triage
/// run that was never entitled to the claim.
///
/// # Errors
///
/// Returns [`CliError::Failed`] (after a user-facing message) when `graded` is 0.
pub(crate) fn check_required_nonzero(
graded: usize,
subject: &str,
flag: &str,
) -> Result<(), CliError> {
if graded > 0 {
return Ok(());
}
eprintln!(
"Error: vacuous run — 0 {subject}, under {flag}. That flag asserts this run's seeds \
COVER them, so it belongs only to an invocation whose corpus holds them: a narrowed \
run, or one over a corpus without them, drops {flag} rather than being graded \
against a population it does not contain."
);
Err(CliError::Failed)
}
9 changes: 1 addition & 8 deletions crates/tsv_debug/src/cli/commands/blank_audit_known.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# deleted, the blank-DROP class every invariant above is blind to.
#
# Format: KIND<TAB>SHAPE
# shapes: 64
# shapes: 57
NON-IDEMPOTENT (){⟨⟩}).
NON-IDEMPOTENT (){⟨⟩});
NON-IDEMPOTENT (⟨⟩IDENT
Expand Down Expand Up @@ -78,10 +78,3 @@ NON-IDEMPOTENT ␣⟨⟩?
NON-IDEMPOTENT ␣⟨⟩IDENT
NON-IDEMPOTENT ␣⟨⟩NUM
NON-IDEMPOTENT ␣⟨⟩␣
NODE-LOSS >{⟨⟩IDENT
NODE-LOSS IDENT⟨⟩[
NODE-LOSS IDENT⟨⟩[.
NODE-LOSS IDENT⟨⟩[\
NODE-LOSS interface⟨⟩␣
NODE-LOSS {⟨⟩␣
NODE-LOSS ␣⟨⟩IDENT
Loading
Loading