saphan verify-union
Advisory: run the suite on the branch merged onto current trunk in a detached worktree
saphan verify-union
Advisory: run the suite on the branch merged onto current trunk in a detached worktree
Measure what this branch does WHEN MERGED: the union of the stream's branch and the CURRENT tip of its trunk, materialized in a DETACHED worktree at both named SHAs — outside the shared working tree, always — with the deterministic suite (go test -count=1 ./...) run there and the scratch tree removed again on every path, success or failure.
WHY, in one sentence: a branch can be green on its own base, the trunk can be green on its own tip, and the two can still be red together with an EMPTY conflict set — four such collisions landed in one evening (2026-08-10/11), and no per-branch instrument can see that class, structurally.
The verdict has FOUR outcomes: clean-green, clean-red, clean-crash and conflict, each distinct. A conflict means git could not combine the parents at all, so the suite NEVER RAN and there is no verdict about the code — it is not a red. A clean-crash means the suite failed to BUILD or crashed before any test could be identified as failing — a different fact than clean-red, where the suite ran and named an actual failing test (order union-record-honesty §2.3).
The verdict is a durable ADVISORY RECORD keyed on BOTH parent SHAs, under
<workspace>/.saphan/union/<stream>/. It is not a merge input: saphan merge
materializes the current pair itself, runs a suite-free conflict probe, and on
a clean probe lands in that same serialized engine act. This command survives
as an instrument and future certification seam.
A measurement is keyed on the SHA PAIR, so re-asking the SAME question has one honest answer: the one already on record. When a record for this exact pair already exists this command PRINTS IT and materializes nothing — the cached verdict carries the ORIGINAL measurement's instant, never "now", because a record that restamped itself would be an instrument lying about time. --force re-measures anyway.
--status reads the last record without measuring anything, and reports whether either parent has moved since (STALE), naming which one and to what.
Options
| Option | Type | Default | Description |
|---|---|---|---|
--force | bool | false | measure even when this exact SHA pair is already on record, replacing that record |
--status | bool | false | read the last recorded union verdict without measuring; reports staleness against both parents' live SHAs |