Skip to content

Feat/phase 2 evaluation readiness - #19

Merged
rwilliamspbg-ops merged 4 commits into
mainfrom
feat/phase-2-evaluation-readiness
Oct 14, 2026
Merged

rwilliamspbg-ops merged 4 commits into
mainfrom
feat/phase-2-evaluation-readiness

Conversation

@rwilliamspbg-ops

Copy link
Copy Markdown
Owner

What and why

Checklist

  • cargo fmt --all --check passes
  • cargo clippy --workspace --all-targets --all-features -- -D warnings passes
  • cargo test --workspace --all-features passes
  • cargo test -p syntax-tests --features compile-fail passes on stable, if syntax-tests' UI fixtures changed
  • New optional tooling is behind a Cargo feature and MSRV-pinned if needed (see README's "MSRV" section)
  • README.md / docs/adoption.md updated if this adds or changes a category, feature flag, or CI job
  • CHANGELOG.md updated under [Unreleased]

Phase 2.1 of docs/roadmap-production-ready.md: drop in an external
implementation (a library under validation, an AI-generated candidate, a
rewrite) and evaluate it against a fixed contract with a fixed suite,
without touching the code under test.

- examples/eval-harness/ (new, standalone workspace — empty [workspace]
  table, the fuzz/ detachment pattern, so the default
  'cargo test --workspace' is untouched): the Candidate contract (pinned
  to reference semantics), the FnCandidate adapter, the GOLDEN_CASES
  table, and the three-part suite — golden cases, proptest properties,
  and a trybuild compile-fail check (a candidate that doesn't implement
  the contract fails to build loudly instead of at test time).
- examples/sample-candidate/ (new): reference candidate — a hand-rolled
  digit-loop parser deliberately different from the reference semantics,
  so equivalence is checked, not assumed.
- just eval <path> / scripts/eval-harness.sh: copies both crates into a
  scratch workspace, substitutes the __HARNESS_PATH__/__CANDIDATE_PATH__
  placeholders, runs the suite; keeps the scratch workspace (with its
  path printed) on failure. Guards: clear errors for a missing
  Cargo.toml and for a candidate not named 'candidate' (the name is part
  of the contract).
- CI's adoption job gained a third step evaluating the sample candidate
  end-to-end, catching harness rot the same way the two adoption legs
  catch adoption rot.
- The dependency cycle (harness dev-depends on the candidate) is
  deliberate and legal in Cargo — it's what lets the suite test the
  candidate while the candidate implements the harness's trait.
- .gitignore: standalone example targets and the Phase 1.3 report
  outputs (nextest.json, lcov.info, clippy.json, deny.json, mutants.json,
  mutants.out/) — previously running those recipes littered the repo.
- New doc docs/evaluation-harness.md; examples/README.md documents the
  standalone-example-workspace pattern.

Verified against real execution: the sample candidate passes the full
suite (golden 1/1, properties 4/4, compile-fail 1/1, doc-test 1/1); a
deliberately broken candidate (accepts '-') fails the golden cases with
a discriminating message and exit 101, scratch workspace kept. Two bugs
caught pre-commit: cargo won't match an underscore dependency key
against a hyphenated package for path deps, and a rustdoc link to
../../justfile would break doc-check.
…se 2.2)

Phase 2.2 of docs/roadmap-production-ready.md: the "I rewrote the hot
path — prove it still behaves identically" primitive, as code.

- crates/core-tests/src/differential.rs (new, ungated, std-only):
  assert_impls_agree(reference, candidate, inputs) asserts two
  implementations of the same function agree on every fixed input,
  naming the input and both results on disagreement. Worked examples
  ship as real tests — closed-form sum vs loop sum, naive trial-division
  primality vs sqrt-bounded optimization.
- crates/fuzz-tests/src/differential.rs (new, behind the existing 'fuzz'
  feature — no new dependency): the property-based companion, same
  agreement check over proptest-generated inputs with automatic
  shrinking, plus the same two worked pairs over generated inputs.
- Docs: best-practices.md gains the differential bullet under "Match
  the test to the failure mode"; docs/fuzzing.md's differential-fuzzing
  section now points at the in-crate helpers as the first step before
  escalating to a continuous cargo-fuzz target; README module
  responsibilities updated.

Verified against real execution: both helpers pass agreeing pairs
(10 unit + 1 doc-test with the fuzz feature) and both *catch* a
deliberately disagreeing pair — the fixed-input form with a
discriminating panic message, the property form with a shrunk minimal
input. Miri covers the new core-tests module (8 + 5 tests interpreted,
~24s for the primality test's naive loop — acceptable for the
nightly-only job). Three compile errors caught pre-commit:
prop_assert_eq! can't capture locals in its format string (macro
expansion), TestRunner isn't in proptest's prelude, and the macro moves
the compared values so they can't be reused as format args.
Phase 2.3 of docs/roadmap-production-ready.md — mutation polish that
stays exploratory by design.

- New justfile recipes: 'mutants-crate <crate>' (cargo mutants -p),
  'mutants-file <glob>' (--file), 'mutants-diff <diff>' (--in-diff) —
  each variadic, so they compose with extra cargo-mutants arguments and
  the --json/-o machine-readable output from Phase 1.3.
- docs/best-practices.md: the mutation section gains "Scoping it to
  what changed" (the three recipes, what each flag does) and a
  documented *soft* reporting pattern — a complete opt-in workflow that
  runs mutants scoped to a PR's diff and posts the kill rate as a PR
  comment, with continue-on-error: true on every step so nothing can
  block a merge. Deliberately NOT added to RustForge's own CI: a fresh
  copy of the template gets no failing jobs it didn't ask for, and the
  exploratory stance is unchanged.
- docs/machine-readable-outputs.md points at the scoped recipes;
  README recipe list updated.

Verified against real execution: 'cargo mutants -p core-tests' runs
scoped (23 mutants, 42s — exit 2 is cargo-mutants' missed-mutants
signal, same as the existing 'mutants' recipe; informational), and
'cargo mutants --file <path>' filters the list to exactly that file's
mutants.
@rwilliamspbg-ops

Copy link
Copy Markdown
Owner Author

Added

  • Phase 2.1 of docs/roadmap-production-ready.md: code-under-test
    evaluation harness.
    New standalone example workspaces
    examples/eval-harness/ (fixed Candidate contract + golden/property/
    compile-fail suite) and examples/sample-candidate/ (reference
    candidate, a hand-rolled parser deliberately different from the
    reference semantics), wired together by just eval <path> /
    scripts/eval-harness.sh: copies both crates into a scratch workspace,
    substitutes the __HARNESS_PATH__/__CANDIDATE_PATH__ placeholders,
    and runs the suite — keeping the scratch workspace on failure for
    inspection. Both crates are detached from the main workspace (empty
    [workspace] tables, the fuzz/ pattern), so the default
    cargo test --workspace is untouched; the dependency cycle (harness
    dev-depends on the candidate) is deliberate and legal in Cargo. CI's
    adoption job gained a third step that evaluates the sample candidate
    end-to-end. New doc docs/evaluation-harness.md.
  • examples/README.md: documents the standalone-example-workspace
    pattern the eval harness establishes.
  • Phase 2.2 of docs/roadmap-production-ready.md: differential-testing
    helpers as code.
    core_tests::differential::assert_impls_agree
    (new, ungated, std-only) checks two implementations of the same
    function against each other over fixed inputs — the "I rewrote the hot
    path, prove it still behaves identically" primitive. Its worked
    examples ship as real tests (closed-form sum vs loop; naive vs
    sqrt-bounded primality). The property-based companion,
    fuzz_tests::differential::assert_impls_agree (new, behind the
    existing fuzz feature — no new dependency), does the same over
    proptest-generated inputs with automatic shrinking. Both verified to
    catch disagreement, not just pass agreeing pairs.
  • Phase 2.3 of docs/roadmap-production-ready.md: mutation-testing
    polish — scoped, still exploratory.
    New just mutants-crate <crate>
    (cargo mutants -p), just mutants-file <glob>
    (cargo mutants --file), and just mutants-diff <diff>
    (cargo mutants --in-diff) recipes, each taking extra cargo-mutants
    arguments so they compose with the --json/-o machine-readable
    output from Phase 1.3. docs/best-practices.md gains "Scoping it to
    what changed" and a documented soft reporting pattern — an opt-in,
    diff-scoped informational workflow that posts the kill rate as a PR
    comment with continue-on-error: true on every step — deliberately
    NOT part of RustForge's own CI. Mutation testing remains exploratory;
    no kill-rate gate anywhere.

@rwilliamspbg-ops
rwilliamspbg-ops merged commit 1de1c17 into main Oct 14, 2026
22 checks passed
@rwilliamspbg-ops
rwilliamspbg-ops deleted the feat/phase-2-evaluation-readiness branch October 14, 2026 15:50
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