qp-run
qp-run — Automation (execute → verdict → mask)
Input: qp/plan/tcs.tsv + the adapter/engine lines from qp/plan/inventory.md. Output dir: qp/run/<YYYYMMDD-HHMM>/.
0. MTM state — decide once, write it first
#mtm: is the first line of verdicts.tsv:
| value | when |
|---|---|
ACTIVE |
a plan document was given and you opened it (path recorded) |
UNAVAILABLE |
no plan document — expected values come from the inventory; the branch differs from plan is unreachable and the vocabulary collapses to AS_PLANNED / CODE_DIFFERS |
FAILED |
a plan document was given but could not be read — say so; do not fall back silently |
DISABLED |
the user turned it off (reason recorded) |
UNAVAILABLE and FAILED are different events; never merge them. |
1. Precondition first — attribution, not blocking
Before step 1 of each TC, establish its precondition. Navigation you can do (at:/about) you do; state you cannot create (logged-in, has-an-order) you mark UNMET_UNEXECUTABLE. A step-1 failure under an unmet precondition is BLOCKED, not FAIL — you never reached the screen, so it is not a claim about the app. Only step 1 is re-attributed; later steps failed after arrival.
2. Execute each step, observe before and after
web: accessibility snapshot before → action → snapshot after. desktop: screenshot before/after. Save each observation as <tc_id>_step<N>_{before,after}.{md,png} and append its stable id from bash plugins/fh-qp/scripts/qp_tools.sh screen-id <file> (a content hash — Playwright MCP ref tokens change every navigation, so a raw file hash is NOT stable; measured 2026-09-05) to evidence.tsv (tc_id<TAB>step<TAB>screen_hash) — this file is what qp-regress reads.