# Evidence-method teaching experiments

These are runnable, synthetic examples, not customer incidents or a product benchmark. Python 3.9 or later with the standard-library `sqlite3` module is sufficient. No pip packages, network, external service, Proof binary or mutation-testing engine are used.

From this directory:

```sh
python3 run.py --output results
```

Use a new or empty output directory. The runner refuses to overwrite retained evidence. Source paths are resolved relative to the runner, so it also works from another directory. Temporary SQLite databases are removed after their observed rows have been recorded. The program writes `results.json`, `stdout.txt` and `SHA256SUMS`. An exit of zero means the expected teaching outcomes matched; the deliberately faulty migration candidate is still rejected.

## Mutation experiment

`access.py` contains a baseline and two explicitly hand-applied mutations: `<` becomes `<=`, and the revocation condition is removed. Both mutants survive the weak positive-case assertion. Three cases justified by `EX-TOKEN-1` kill both mutants while the baseline passes. The expiry and revocation expectations come from the authored requirement in `requirements.json`, not from copying the baseline's output or inventing a rule to maximize a score. The contract itself is illustrative and needs independent authorization in a real project.

The run records six variant/suite combinations and twelve individual assertion observations. No coverage instrumentation, automatic mutant generation or Stryker integration is claimed. Killing these two selected mutants is bounded evidence that these assertions distinguish these faults. It does not establish test-suite completeness, all equivalent mutants or production correctness.

## API migration experiment

`migration.py` implements old and candidate handlers against separate, freshly initialized SQLite files. Each handler is called for an authorized and unauthorized tenant, making four real calls. The candidate deliberately commits a label update before checking ownership, then returns the same rejection response as the old handler. A fresh database connection reads committed rows after each call ends.

The exact request ID differs between implementations. The fixture contract permits that difference after checking that both IDs are nonempty strings. The permitted comparison removes only that field and retains durable rows. It finds agreement for the authorized case and disagreement for the unauthorized case. A deliberately dangerous comparator also drops durable state; it falsely reports agreement for the unauthorized case.

`disposition.json` records a fictional service owner's authorization of the comparison rule and rejection criterion. It is an illustrative decision record, not evidence of a real person's approval, a customer acceptance or a compliant release. The runner applies the record's stated rule through explicit comparator code; it is not a generic policy interpreter.

This models an API implementation cutover, not a database schema migration. It does not test locks, live traffic, distributed transactions, rollback, data volume or overlapping production versions. Extend the corpus and deployment checks for the actual migration. Differential agreement is also insufficient when both versions share a defect, which is why this example checks expected behavior independently.

## Evidence and reproduction

`results.json` contains actual outputs and stored rows, runtime versions, UTC execution time, the invocation, individual assertion observations and SHA-256 digests of every source/input file, including this README and the runner. The basis digest hashes the sorted JSON mapping of source digests. The results manifest hashes the result and stdout files. Digests identify bytes and detect accidental changes; they are not an independent signature or proof of origin. Execution timestamps and environment fields naturally vary on reruns.

Published files under `website/assets/samples/evidence-methods/` are a copy of these sources and one captured run. The downloadable ZIP contains that copy. Its adjacent SHA-256 file identifies the ZIP bytes. To reproduce, extract it, inspect the sources, and choose a new output directory.

## Primary method sources

Reviewed October 3, 2026:

- [Stryker mutant states and metrics](https://stryker-mutator.io/docs/mutation-testing-elements/mutant-states-and-metrics/), for killed/survived terminology only. Stryker was not executed.
- [Python sqlite3 documentation](https://docs.python.org/3/library/sqlite3.html), for committing writes and reopening a database connection to inspect persisted rows. This example does not generalize SQLite behavior to another database.
