Determinism-contract wave-5 item 6. Extends the existing
PromotionGate (yang→yin promotion of verified model answers) with
the determinism-contract precondition: promotion may proceed only
if (a) a verification artifact is attached, (b) the artifact
verifies via the supplied dispatcher, AND (c) any preregistration
locking conditions are satisfied.
This is the actual enforcement of the contract that's been the
spine of wave-5: the proposer (any LLM, any seed) stays
stochastic; the verifier is tiered (formal / computational /
physical); nothing gets promoted without a re-runnable artifact.
Surface:
- `DeterminismContractGate<V: ArtifactVerifier, S: PromotionStore>`
composes a PromotionGate + a VerificationArtifact + an
ArtifactVerifier.
- `.with_prereg(prereg, claim)` attaches an optional preregistration
+ evaluation claim for additional gating on locked data hash +
approved grader.
- `.check()` — pure check (no mutation); runs verifier + prereg.
- `.consider(query, answer, verified, now_secs) -> Result<bool,
ContractError>` — runs check, then PromotionGate::is_eligible,
then promotes. Returns Ok(true) on new promotion, Ok(false) on
already-promoted, Err on contract / not-eligible failure.
- Impls `jouleclaw_gate::Gate` so the contract gate composes with
the broader gate registry.
ContractError aggregates artifact / prereg / not-eligible failure
modes with thiserror::From for the underlying types.
Honest scope (v1): the contract enforces the protocol. It does
NOT certify the artifact's claim is true — only that anyone with
the artifact can re-run the verdict. No artifact versioning,
no deferred verification signals, no async verifier chain in v1.
Adds jouleclaw-gate / jouleclaw-graph / jouleclaw-artifact /
jouleclaw-prereg as deps; jouleclaw-formalize as a dev-dep
(test fixtures).
+7 tests on top of the existing 15: contract allows when
artifact + answer eligible; refuses when artifact refuses;
refuses when answer not eligible; with prereg refuses on
data-hash mismatch; with prereg allows on match; evaluates as a
jouleclaw_gate::Gate (Allow when verified); check() is pure +
repeatable.
Co-Authored-By: Claude Opus 4.7 <[email protected]>