<!-- [doc->REQ-PICK-FIDELITY-AUDIT] -->

# IR-57 instrument — `xtask pick-audit`, the scripted pick-fidelity audit

The instrument behind [[IR-57]] in `docs/INFRA-REGISTER.md`. Run it at every assembly, over the
whole pick chain, before the head is handed anywhere.

```
cargo run -p xtask -- pick-audit --range <assembly-base>..<head> --lane <lane-base>..<lane-tip> [--lane …]
```

## What it answers, and what it does not

It answers one question per pick: **did the pick carry the same changed lines its lane source
carried?** It says nothing about whether the assembled head compiles — that is the entry's other
must-do, and no audit replaces it. `traceable-reqs check` does not either: it parses tags and never
invokes the compiler, which is why it returned 797/797 exit 0 over the head that filed this entry.

## Reading the two verdicts

Count and digest are reported per pick because **they fail in opposite directions**, measured over
24 picks on the #212 chain:

| Verdict | Means | Run |
| --- | --- | --- |
| `MATCH` | same changed-line count, same digest | passes |
| `DRIFT` | same count, different lines | **passes, loudly** — the benign class |
| `LOSS` | the counts differ | **fails, exit 1** |
| `UNPAIRED` / `AMBIGUOUS` | the audit could not pair the pick to a lane source | **fails, exit 3** |

`DRIFT` is not a defect on its own evidence: the measured instance was a paragraph the head had
already amended for another lane, whose merged result correctly carries both lanes' sentences. It
is printed rather than reddened on, because a check that reds on its benign class gets disabled and
takes the count arm with it. It still deserves a human read — `git show` both shas and confirm the
difference is a region the head had legitimately moved.

`LOSS` is the class that filed the entry: a resolution that dropped `        );` and `    }` while
`git cherry-pick` reported no conflict remaining.

## Why the changed-line SET and not the whole diff

Hunk headers and context lines legitimately drift once the head's copy of a file has moved, so a
whole-diff comparison returns a confident wrong answer. The audit compares only the `+`/`-` lines of
`git show --format= <sha>`, minus the `+++`/`---` file headers — both sides read at one layer, git's
own diff output for two commits in one repository.

## Pairing, and the pick it cannot pair

Picks are paired to lane sources by **subject**: a cherry-pick rewrites the sha and, without `-x`,
records nothing about where it came from — the assemblies this exists for carry no such trailer. A
pick whose subject was reworded, or one that collides with several lane commits sharing a subject,
is reported as unaudited and exits non-zero. It is rescued explicitly, never guessed at:

```
--pair <lane-rev>:<pick-rev>
```

## Scope: PICK-shaped assemblies only

**This audits an assembly built from cherry-picks. A MERGE-based assembly — CONDUIT's form — has no
picks to audit, and this verb will report zero rows over it.** Zero rows is not a pass and must never
be read as one: a merge-composed head keeps the blob-fidelity parity leg instead. Check which shape
the assembly is before quoting this tool's silence as evidence about it.

## Limits, stated because a green here is used as evidence

- **Equal counts with substituted content read as `DRIFT`, not `LOSS`.** A resolution that dropped
  one line and invented another is invisible to the count arm. That is what the digest arm is for,
  and why `DRIFT` rows are printed rather than filtered out.
- **Merges are excluded from both ranges.** A merge carries no pick of its own, and its diff against
  one parent would classify as a whole-file rewrite.
- **The audit reads commits, not the tree.** A head that passes it can still fail to build — for a
  composition break between two individually faithful picks, which is the #182 v2 assembly's
  mechanism rather than this one's.
