Skip to content

test(daemon): kill 38 surviving mutants across three pure helpers - #81

Merged
acamarata merged 1 commit into
mainfrom
test/pure-helpers-coverage
Sep 16, 2026
Merged

acamarata merged 1 commit into
mainfrom
test/pure-helpers-coverage

Conversation

@acamarata

Copy link
Copy Markdown
Contributor

Targets the exact surviving-mutant lists the mutation gate produced at b697493 for three pure, in-scope helpers.

file mutants listed killed equivalent
agents/capabilities.rs 12 10 2
policy/tester.rs 12 12 0
intelligence/context.rs 19 16 3

Every mutant was hand-applied and the suite confirmed to fail. A green test proves nothing about whether it kills anything, so each one was patched into the source one at a time, the suite run, and the source restored — 28 of 28 killed on tester.rs + context.rs, 10 of 12 on capabilities.rs, with the 2 survivors matching the pair predicted to be equivalent.

Fixtures are built so the right answer is not an accident

The arithmetic mutations (+*, -=+=, <<=) only die if the correct value differs from what the mutation produces, which rules out the obvious round numbers. Some of what that forced:

  • optimize_context's budget walk uses a per-message cost of 16 against a budget of 80, so remaining steps 80 → 64 → 48 → 32 → 16 → 0 and lands on exactly 16. That is the only input separating remaining < 16 (5 messages survive) from <= 16 and == 16 (4 survive).
  • The pinned-cost sum uses a 2-token role and a 9-token body: 2+9+4 = 15 leaves room for 4 regular messages, 2*9+4 = 22 leaves room for 3, and 2+9*4 = 38 leaves room for 2 — three different answers, so both +* mutations are separable.
  • truncate_to_tokens(40 chars, max_tokens=4) is asserted to be exactly 12 x plus an ellipsis. Under max_tokens + 4 it is 4; under <= it is 13; under == and > the take_while predicate fails on the very first index, the iterator is empty, and unwrap_or(0) yields a bare ellipsis.
  • run_all_policy_tests gets a directory holding a 3-case .yaml, a 2-case .yml and a 4-case .txt. The sizes are picked so no wrong subset sums to the right answer of 5: mutating the first == collects .yml + .txt = 6, the second collects .yaml + .txt = 7, and && collects nothing.

Equivalent mutants, documented rather than chased

  • Deleting the ("planner", "high") or ("implementer", _) arms of recommend_provider — both fall through to _ => Provider::Claude, so no input can observe the difference. Confirmed empirically: these are the 2 that survived the hand-application run.
  • The full_cost > budget comparison in optimize_context's trailing truncation guard is unreachable. The guard only fires for a message that is neither pinned nor a system message, and such a message reaches the result only by being selected — which required role_tokens + full_cost + 4 <= remaining <= budget. So full_cost is always strictly below budget and the branch is dead code. Its <, == and >= mutations are therefore indistinguishable.

The guard's other three mutations are not equivalent and are killed: &&|| and the delete ! both make the condition true for a pinned message, and !=== makes it true for an unpinned system message. Two tests pin that an oversized pinned message and an oversized system prompt are each returned at their full 200 characters, because silently trimming a system prompt is the actual bug hiding behind that operator.

Layout

Inline mod tests blocks move to <module>/tests.rs with existing cases kept verbatim, matching the other suites in this series. No production code changesgit show --stat is test files plus the mod tests; declarations.

cargo fmt --check, cargo clippy --all-targets -- -D warnings and the full 832-test lib suite are clean.

Targets the exact surviving-mutant lists the mutation gate produced at
b697493 for agents/capabilities.rs (12), policy/tester.rs (12) and
intelligence/context.rs (19).

Each new test is written against a specific mutation and asserts a value
that only the unmutated code produces, rather than a value that merely
happens to be right. Fixtures are chosen so the correct answer differs
from what the arithmetic mutations would give: for example
optimize_context's budget walk uses a cost of 16 against a budget of 80
so that `remaining` lands on exactly 16, which is the only input that
separates `< 16` from `<= 16` and `== 16`.

Every mutant was hand-applied and the suite confirmed to fail:
  capabilities.rs   10 of 12 killed
  policy/tester.rs  12 of 12 killed
  context.rs        16 of 16 killed

The four not counted above are equivalent mutants, documented in place
rather than chased:
  - deleting the ("planner","high") or ("implementer",_) arms of
    recommend_provider: both fall through to `_ => Provider::Claude`,
    so no input can observe the difference.
  - the `full_cost > budget` comparison in optimize_context's trailing
    truncation guard is unreachable. The guard only fires for a message
    that is neither pinned nor a system message, and such a message
    reaches the result only by being selected, which required
    role_tokens + full_cost + 4 <= remaining <= budget. So full_cost is
    always strictly below budget and the branch is dead.

Inline `mod tests` blocks move to `<module>/tests.rs` with the existing
cases kept verbatim, matching the layout used by the other suites added
in this series. No production code changes.
@acamarata
acamarata merged commit 30f8913 into main Sep 16, 2026
12 checks passed
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