sayHeld stays in G's judgeOverHeld, after the written-verdict branch, for a fresh trunk manifest
whose verdict the pass did not write. The test's merged manifest is written as the candidate's
own text ("2.0"): the join's manifest digest is of the raw bytes (meshcatalogclient
ManifestDigest), so "2" was another manifest and the test stopped before the case it adds.
Builds: design 25 bus-state §1 (merged from main)
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h