# Bound-gate fixture (EXPERIMENTAL)

**Status: experimental. Not frozen, not a conformance fixture, and not part of
the Warranted Crossings website.**

## The narrow question

> Can a new GateVerdict be shown to bind to **real, retrievable test inputs** and
> **measured invariants**?

At `crossing-graph-design@517ab64` the published GateVerdict vector cannot: its
`inputs_hash` is the placeholder `0x2222…`, its `policy_hash` (`0x1111…`) and
`authority_state_hash` (`0x4444…`) name no retrievable bytes, and no invariant
definitions exist (see `CROSSING_FIELD_SOURCE_INVENTORY_001.md` in the site
repo, and `AGENT_CONTEXT.md` here). This experiment builds the smallest crossing
that closes those specific gaps, **for test inputs only**.

## What it supplies

Reusing three published wire profiles verbatim
(`request-binding.v1.candidate`, `context-snapshot.v1` frozen wire binding,
`gate-verdict.v1.candidate`) with new values that actually bind:

- `material/policy.json` — retrievable policy bytes; `policy_hash =
  SHA-256(file bytes)` equals the verdict's and context's `policy_hash`.
- `material/authority-state.json` — retrievable authority-state bytes;
  `authority_state_hash = SHA-256(file bytes)` equals the context's field 8.
- **Declared, experimental invariants** `BG-I1..BG-I3` (definitions, inputs,
  measurements, results) in `bound-gate.v1.json`. These are *this fixture's*
  invariants over the supplied inputs; they are **not** the source spec's I1..I8.
- a `RequestBinding` and a `ContextSnapshot` (genesis head: no graph history
  claimed);
- a `GateVerdict` whose signed `inputs_hash` equals the independently
  recomputable `SHA-256("gate-inputs:v1\0" || request_hash || context_hash)`.
- `trust-root.json` — the **test** signing key and its **test** trust root,
  declared *outside* the signed verdict.

The signing key is derived from a published label
(`SHA-256("bound-gate-fixture:test-signing-seed:v1")`). There is **no secret
key custody** and **no claim of production identity**. This is **test
authority**: a warrant here is valid only under the declared test trust root.

## The separately reported checks

`verify_bound_gate.py` (independent of `generate.py`) reports each of:

`byte_conformance · signature · input_binding · material_availability ·
definition_binding · invariant_evaluation · measurement_binding ·
test_authority · gate_result`

A **test-domain warrant** (`EXECUTE`) requires the first eight to PASS. **A passing
signature alone never warrants.** Missing material is `UNAVAILABLE`, never PASS.
The verifier independently registers the three test predicates and checks that
the published definitions agree. It also compares every published measurement
and mask with its recomputation. Its result is fail-closed for malformed vectors.
This binds the published metadata to this test verifier's implementation; it does
not make the metadata cryptographically signed or confer production authority.

## Boundary

`decision_replay: DECISION_REPLAY_UNAVAILABLE`. This fixture evaluates invariants
over the supplied inputs at the recorded instant. It does **not** reconstruct
historical event encoding, authority history, or source policy evaluation over a
log, and it does not compose fields over time. Regenerating a digest is not
independent source-decision replay.

## Run

```powershell
# from the repository root, using any Python with `cryptography`:
$py = ".venv-conformance\Scripts\python"
& $py experiments\bound-gate-fixture\generate.py          # (re)generate; deterministic
& $py experiments\bound-gate-fixture\verify_bound_gate.py # independent checks
& $py -m unittest discover -s experiments/bound-gate-fixture -p test_bound_gate.py -v
```

`generate.py` is deterministic: re-running it reproduces byte-identical
artifacts. The committed `bound-gate.v1.json`, `material/*`, and `trust-root.json`
are those outputs.
