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
88 changes: 88 additions & 0 deletions .claude/skills/ci-gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11595,3 +11595,91 @@ always -- the number was implausible for the size of the tree.
**The finding survives; the tool does not.** One of the fourteen was the 30-line
window, and it was found by reading a short list rather than by shipping a
check that would cry wolf 50 times.

## 453. A cap that decides nothing about the number, and everything about termination

The sweep in §452 produced fourteen candidates and about five that looked like
decisions. Read by hand, priced one at a time:

**`quant.rs` `depth > 8`** -- the recursion cap in `size_of`, which feeds the
walkable-clause census. Instrumented over the live corpus:

calls to size_of 2078
maximum depth reached 1
guard taken 0

and the census reads `119 / 308 / 472` with the cap at **1, 2, 4, 6, 8, 12, 16,
32 or 64**. Flat everywhere. So by the §450 test it is not load-bearing, and by
the §426 rule -- *a guard clause you have not executed is a comment* -- it looks
deletable.

**It is not.** Remove it and the suite does not fail; it **stack-overflows**, on
a struct whose field is itself. #2949 established one in real code
(`BTreeNode** children` inside `BTreeNode`), and this corpus simply has none
today.

So the treatment is neither deletion nor silence: **make the unreached branch
reachable.** `a_self_referential_struct_terminates` plants the cycle and asserts
`Unbounded`; `a_chain_shallower_than_the_cap_is_still_measured` plants a
four-deep finite chain and asserts a real size, or the cap would be
indistinguishable from *give up on anything nested*. Both mutations bite.

**The general shape.** Two questions look alike and are not:

* *does this constant change a published number?* -- sweep it and read the table;
* *does this constant prevent a failure?* -- remove it and see what happens.

A constant can answer **no** to the first and **yes** to the second, and only
the second question distinguishes a dead guard from an unexercised one.

## 454. Two literals that must agree, linked only by prose

`tri gates red` asks GitHub for `per_page=30` runs and prints a streak that
fills the page as `30+`, because a full page is a lower bound. The marker was
`n >= 30` -- a *second* literal, two hundred lines from the first, with a
comment explaining why they match.

Raising the query alone would have kept printing `+` on streaks that are exact:
**a truncation marker that has stopped marking truncation**, in the command
whose whole subject is silent truncation.

One constant now, and the test does not assert the constant against itself --
which is where the first version went wrong:

```rust
assert!(PAGE >= PAGE); // a control that cannot fail
assert!(!(PAGE - 1 >= PAGE)); // and its twin
```

The real check reads the page size back **out of the URL the command sends**
and compares it to the count at which the marker flips. Hard-coding `100` into
the URL turns it red; moving the marker to `n > PAGE` turns it red. Two
literals cannot pass it; one constant does.

**Where two numbers must be equal, a comment is not the mechanism.** Give them
one definition, and let the test read one of them from the artefact the other
produces.

## 455. A mutation run over a file that was never mutated

Three mutants "passed" in a row, all green, all meaningless: the rewrite that
was supposed to change the source had aborted on a failed anchor assertion
**before writing the file**, so every mutant ran against the original.

This is §440 wearing different clothes -- there the sample was empty, here the
*treatment* was. Both print a clean table.

The guard is the same one line, moved: the mutation helper now **exits
non-zero and says so** when the anchor is not found exactly once, instead of
letting the caller read a green.

```python
if s.count(old) != 1:
print(f"ANCHOR NOT FOUND ({s.count(old)}) -- mutation NOT applied"); sys.exit(9)
```

**A harness that cannot tell "the mutant survived" from "the mutant was never
built" is not a harness.** The repository already learned this for mutants the
compiler rejected (§382, three arms: killed, survived, never built); a mutant
the *editor* never wrote is the fourth arm, and it looks exactly like the
second.
51 changes: 50 additions & 1 deletion cli/tri/src/quant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,22 @@ fn scan_structs(specs: &[(PathBuf, String)]) -> Structs {
Structs { fields, conflicted }
}

/// How deep `size_of` will follow a type before calling it unbounded.
const MAX_TYPE_DEPTH: usize = 8;

fn size_of(ty: &str, s: &Structs, depth: usize) -> Size {
let ty = ty.trim().trim_end_matches(',').trim();
if depth > 8 {
// A recursion cap, and it has never fired here. Instrumented over the live
// corpus: 2078 calls to this function, maximum depth reached **1**, guard
// taken **0** times -- and the census is identical with the cap at 1, 2, 4,
// 6, 8, 12, 16, 32 or 64. So it decides nothing about any published number.
//
// It is kept because what it guards is real and simply absent from this
// corpus: a struct that contains itself. #2949 established one in C
// (`BTreeNode** children` inside `BTreeNode`), and a walk of that without a
// cap does not terminate. A guard clause nobody has executed is a comment,
// so `a_self_referential_struct_terminates` executes this one.
if depth > MAX_TYPE_DEPTH {
return Size::Unbounded;
}
if let Some(n) = primitive(ty) {
Expand Down Expand Up @@ -1623,6 +1636,42 @@ mod tests {
}
}

/// The recursion cap, executed on purpose.
///
/// Instrumented over the live corpus: **2078** calls to `size_of`, maximum
/// depth reached **1**, cap taken **0** times -- and the census is identical
/// with it at 1, 2, 4, 6, 8, 12, 16, 32 or 64. Nothing in this repository
/// exercises it, and a guard clause nobody has run is a comment. This runs
/// it: a struct whose field is itself, which #2949 established exists in
/// real code (`BTreeNode** children` inside `BTreeNode`) and which without
/// the cap does not terminate.
#[test]
fn a_self_referential_struct_terminates() {
let mut fields = std::collections::BTreeMap::new();
fields.insert("Node".to_string(), vec!["Node".to_string()]);
let st = Structs {
fields,
conflicted: Default::default(),
};
assert_eq!(size_of("Node", &st, 0), Size::Unbounded);
}

/// And a chain that is deep but FINITE must still be measured, or the cap
/// would be indistinguishable from "give up on anything nested".
#[test]
fn a_chain_shallower_than_the_cap_is_still_measured() {
let mut fields = std::collections::BTreeMap::new();
fields.insert("L0".to_string(), vec!["Trit".to_string()]);
for i in 1..=3 {
fields.insert(format!("L{i}"), vec![format!("L{}", i - 1)]);
}
let st = Structs {
fields,
conflicted: Default::default(),
};
assert_eq!(size_of("L3", &st, 0), Size::Finite(3));
}

#[test]
fn a_trit_is_three_and_a_struct_is_the_product() {
assert_eq!(size_of("Trit", &s(), 0), Size::Finite(3));
Expand Down
55 changes: 53 additions & 2 deletions cli/tri/src/red.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,29 @@ struct Red {

/// How many of the most recent runs, newest first, share the failing verdict.
/// A single red is noise; nine in a row is an outage nobody is reading.
/// How many runs one page of the API returns.
///
/// A constant because TWO places need the same number and only prose linked
/// them: the query asks for a page this size, and a streak that FILLS the page
/// is a lower bound, printed as `30+`. Raising the query alone would have kept
/// printing `+` on streaks that are exact -- a truncation marker that has
/// stopped marking truncation, which is this command's own subject.
const PAGE: usize = 30;

/// The query, built from `PAGE` so the URL and the marker cannot disagree.
fn runs_url(repo: &str, id: &str, branch: &str) -> String {
format!("repos/{repo}/actions/workflows/{id}/runs?branch={branch}&per_page={PAGE}")
}

/// Is a streak of `n` a LOWER BOUND rather than an exact count?
fn is_lower_bound(n: usize) -> bool {
n >= PAGE
}

fn streak(repo: &str, id: &str, branch: &str) -> Result<(usize, String)> {
let raw = gh(&[
"api",
&format!("repos/{repo}/actions/workflows/{id}/runs?branch={branch}&per_page=30"),
&runs_url(repo, id, branch),
"--jq",
r#".workflow_runs[]|"\(.conclusion)\t\(.created_at)""#,
])?;
Expand Down Expand Up @@ -146,7 +165,7 @@ fn now(repos: &[String], include_cancelled: bool) -> Result<()> {
name: name.to_string(),
since: since.chars().take(16).collect(),
consecutive: n,
at_least: n >= 30,
at_least: is_lower_bound(n),
});
}
}
Expand Down Expand Up @@ -200,3 +219,35 @@ mod tests {
);
}
}

#[cfg(test)]
mod page_tests {
use super::*;

/// The query and the truncation marker must be the same number.
///
/// They were two literals, both `30`, linked only by a comment. A raise of
/// the query alone would have kept printing `+` on streaks that are exact
/// -- a truncation marker that has stopped marking truncation, which is
/// what this command exists to surface.
#[test]
fn the_query_and_the_marker_read_one_constant() {
// Read the page size back OUT of the URL the command sends and check
// it against the count at which the marker flips. Two literals cannot
// pass this; one constant does.
let url = runs_url("o/r", "wf.yml", "master");
let sent: usize = url
.rsplit("per_page=")
.next()
.and_then(|v| v.parse().ok())
.expect("the query states a page size");
assert!(
!is_lower_bound(sent - 1),
"one short of a full page is an exact count"
);
assert!(
is_lower_bound(sent),
"a full page is a lower bound and must print as `{sent}+`"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# NOW -- Four thresholds priced: one guards a hazard, three were not the class (2026-09-03)

## Four thresholds priced: one guards a hazard, three were not the class (Refs #2994)

- quant.rs depth>8: instrumented over the live corpus -- 2078 calls, maximum depth reached 1, guard taken 0 times, and the census is identical at 1/2/4/6/8/12/16/32/64. It decides nothing about any published number.
- It is kept because removing it STACK-OVERFLOWS on a struct whose field is itself, which #2949 established exists. A guard nobody had run is now run by a test, plus a finite-chain counter-example so the cap is not 'give up on anything nested'.
- red.rs at_least: n>=30 and per_page=30 were two literals linked only by prose. One constant now, with a test that reads the page size back OUT of the URL and checks the count at which the marker flips.
Loading