# TASK-157-02: Deterministic Gate Verifier And Status Model

**Status:** ✅ Done
**Priority:** 🔴 High
**Parent:** [TASK-157](./TASK-157_Goal_Derived_Quality_Gates_And_Deterministic_Verification.md)
**Category:** Guided Runtime / Gate Verification
**Estimated Effort:** Large

## Objective

Build the status model and the first deterministic verifier slice that
evaluates normalized gates using deterministic scene, spatial, and assertion
evidence. Bounded reference or perception payloads may provide proposal/support
refs, but they are not the truth authority for gate pass/fail status.

This layer must make evidence authority explicit. Perception outputs can
support a verifier only when the gate type allows that evidence class; they do
not become a generic substitute for Blender truth. The current shipped slice is
`scene_relation_graph(...)`-backed; later gate-specific verifiers should extend
the same status model instead of creating parallel gate flows.

## Completion Summary

Completed on 2026-05-01.

- Added evidence-backed gate status contracts, status summaries,
  `completion_blockers`, verifier results, evidence authority, and bounded
  repair-tool hints in `server/adapters/mcp/contracts/quality_gates.py`.
- Added the first deterministic relation-graph verifier in
  `server/adapters/mcp/transforms/quality_gate_verifier.py`.
- The shipped verifier slice now covers `required_part`, `attachment_seam`,
  `support_contact`, and `symmetry_pair` while preserving the shared gate
  contract for later gate-type-specific verifiers.
- Persisted verifier results into session `active_gate_plan` whenever
  `scene_relation_graph(...)` returns authoritative payloads.
- Marked evidence-backed gates `stale` after guided scene mutations, using the
  existing guided spatial dirtying path instead of a parallel invalidation
  flow.
- Kept perception/reference sources advisory: they may seed proposals or
  evidence refs, but only scene/spatial/mesh/assertion verifier evidence can
  move gates to `passed` or `failed`.

Follow-on: cross-domain Blender-backed runtime/E2E proof remains tracked by
[TASK-157-04](./TASK-157-04_Cross_Domain_E2E_Gate_Regression_Harness.md).

## Validation

- `git diff --check`
- `PYTHONPATH=. poetry run pytest tests/unit/adapters/mcp/test_quality_gate_contracts.py tests/unit/adapters/mcp/test_quality_gate_verifier.py tests/unit/adapters/mcp/test_quality_gate_intake.py -v`
- `PYTHONPATH=. poetry run pytest tests/unit/adapters/mcp/test_quality_gate_contracts.py tests/unit/adapters/mcp/test_quality_gate_verifier.py tests/unit/adapters/mcp/test_quality_gate_intake.py tests/unit/adapters/mcp/test_guided_flow_state_contract.py tests/unit/adapters/mcp/test_contract_payload_parity.py tests/unit/tools/scene/test_scene_contracts.py -v`
- `PYTHONPATH=. poetry run pytest tests/unit/tools/scene/test_spatial_graph_service.py tests/unit/tools/scene/test_scene_contracts.py tests/unit/adapters/mcp/test_quality_gate_verifier.py -v`
- `PRE_COMMIT_HOME=/tmp/pre-commit-cache poetry run pre-commit run --files README.md _docs/AVAILABLE_TOOLS_SUMMARY.md _docs/_CHANGELOG/README.md _docs/_CHANGELOG/280-2026-05-01-task-157-deterministic-gate-verifier.md _docs/_MCP_SERVER/README.md _docs/_PROMPTS/README.md _docs/_PROMPTS/REFERENCE_GUIDED_CREATURE_BUILD.md _docs/_ROUTER/RESPONSIBILITY_BOUNDARIES.md _docs/_TASKS/README.md _docs/_TASKS/TASK-157-02-01_Attachment_Support_And_Contact_Gate_Verifier.md _docs/_TASKS/TASK-157-02_Deterministic_Gate_Verifier_And_Status_Model.md _docs/_TASKS/TASK-157_Goal_Derived_Quality_Gates_And_Deterministic_Verification.md _docs/_TESTS/README.md server/adapters/mcp/areas/scene.py server/adapters/mcp/contracts/__init__.py server/adapters/mcp/contracts/quality_gates.py server/adapters/mcp/session_capabilities.py server/adapters/mcp/transforms/quality_gate_verifier.py tests/unit/adapters/mcp/test_quality_gate_intake.py tests/unit/adapters/mcp/test_quality_gate_verifier.py`

## Repository Touchpoints

| Path / Module | Expected Change |
|---------------|-----------------|
| `server/adapters/mcp/contracts/quality_gates.py` | Gate status, evidence, blocker, and verifier-result contracts |
| `server/adapters/mcp/contracts/reference.py` | Stable refs to silhouette/action-hint/segmentation/reference-understanding payloads |
| `server/application/services/spatial_graph.py` | Evidence source for relation/contact/seam gates |
| `server/adapters/mcp/areas/scene.py` | Reuse scene assertions and relation graph outputs |
| `server/adapters/mcp/areas/reference.py` | Attach verifier results to checkpoint/iterate payloads |
| `server/adapters/mcp/vision/` | Source of bounded proposal/support refs when a verifier strategy accepts them |
| `server/adapters/mcp/session_capabilities.py` | Persist gate status and last verification versions |
| `tests/unit/adapters/mcp/test_quality_gate_verifier.py` | Gate status transition tests |
| `tests/unit/tools/scene/` | Evidence mapping tests for scene/spatial verdicts |

## Status Model

| Status | Meaning |
|--------|---------|
| `pending` | Gate exists but has not been checked against current scene truth |
| `blocked` | Required evidence or scope is missing |
| `passed` | Deterministic evidence satisfies the gate |
| `failed` | Deterministic evidence proves the gate is not satisfied |
| `waived` | User/server policy explicitly marks the gate not required |
| `stale` | Scene changed since the last successful check |

## Evidence Authority Model

Gate evidence should be typed and ranked by authority rather than collapsed
into one confidence score.

| Evidence Kind | Typical Gate Use | Authority |
|---------------|------------------|-----------|
| `scene_truth` / assertion output | `required_part`, `final_completion`, object existence, mode/scope checks | Authoritative when fresh |
| `spatial_relation` | `attachment_seam`, `support_contact`, pair seating, floating gap detection | Authoritative for spatial contact/support |
| `mesh_metric` | `opening_or_cut`, selected `shape_profile`, dimensions, topology/count checks | Authoritative when the metric directly measures the gate |
| `silhouette_analysis` | `shape_profile`, coarse `proportion_ratio`, visible contour drift | Bounded supporting context only; must include scope/capture/reference ids and cannot pass gates by itself |
| `part_segmentation` | Target part masks, region hints, future part-aware profile checks | Supporting evidence only; cannot prove Blender object existence/contact |
| `classification_scores` | Domain/profile or construction-strategy score payloads | Routing/proposal evidence only; cannot pass gates |
| `reference_understanding` | Candidate gate plan, style, required details, construction path | Proposal evidence only; cannot pass gates |
| LLM prose | Rationale and client guidance | No verifier authority |

Unsupported or unavailable evidence sources should produce `blocked` with a
machine-readable reason when the gate requires that evidence. Optional
perception evidence may be absent without blocking gates that have an
authoritative scene/spatial/mesh verifier.

## Implementation Notes

- Verifiers should be small and gate-type specific.
- Verification must carry evidence references:
  - tool used
  - scope
  - scene/spatial version
  - measured value or verdict
  - failure reason
- A gate cannot become `passed` without evidence.
- A gate cannot become `passed` solely because a VLM, CLIP-style classifier, or
  reference-understanding summary says the target looks correct.
- `shape_profile` and selected `proportion_ratio` gates may use bounded
  perception evidence only as verifier-supported context when their normalized
  `verification_strategy` explicitly allows it and the evidence carries fresh
  capture/reference scope.
- A scene mutation should mark affected gate statuses `stale` or require
  re-check before final completion.
- Completion blockers should be derived from required gates in `failed`,
  `blocked`, `pending`, or `stale`.

## Runtime / Security Contract Notes

- Visibility level: verifier results may be exposed through existing
  guided/reference checkpoint payloads; the verifier itself should remain a
  server-owned runtime/service contract unless a public read-only assertion
  tool is intentionally promoted.
- Read-only vs mutating behavior: verifier collection and evaluation are
  read-only against Blender scene state. They may update session gate status,
  blockers, stale versions, and evidence refs.
- Authority boundary: scene/spatial/mesh/assertion evidence owns truth for
  existence, contact, measurements, and final completion. Vision,
  `reference_understanding`, `classification_scores`, and segmentation payloads
  are never standalone pass evidence.
- External providers: a verifier must not trigger an implicit SAM/CLIP/VLM call
  to satisfy a missing required source. Missing required evidence returns
  `blocked` with a typed reason.
- Debug limits: evidence refs should carry tool names, versions, ids, measured
  values, and redacted provenance, not raw provider transcripts or secrets.

## Pseudocode

```python
def verify_gate(gate, scene_context):
    verifier = verifier_registry.for_type(gate.gate_type)
    evidence = verifier.collect(gate, scene_context)

    if evidence.missing_scope:
        return GateStatusResult(status="blocked", reason="missing_scope")

    if verifier.passes(gate, evidence):
        return GateStatusResult(status="passed", evidence=evidence)

    return GateStatusResult(
        status="failed",
        evidence=evidence,
        correction_hint=verifier.recommend_correction(gate, evidence),
    )
```

## Tests To Add/Update

- Required gate without scope returns `blocked`.
- Required gate with stale scene version returns `stale`.
- Passed gate requires evidence payload.
- Perception-only completion claims remain `pending` or `blocked` with a typed
  `missing_authoritative_evidence` / `unsupported_evidence` reason until a
  supported verifier evaluates fresh scene, spatial, mesh, or assertion
  evidence; perception-only claims never set `passed` or `failed` by
  themselves.
- Unsupported required perception evidence returns `blocked` with an actionable
  reason instead of triggering an implicit SAM/CLIP call.
- Completion blocker aggregation includes `pending`, `blocked`, `failed`, and
  `stale` required gates.
- Optional failed gates do not block final completion but remain visible.

## E2E Tests

- Cross-domain E2E ownership now lives under
  [TASK-157-04](./TASK-157-04_Cross_Domain_E2E_Gate_Regression_Harness.md),
  which carries the creature/building checkpoint lanes plus the transport
  roundtrip for gate-state persistence.

## Docs To Update

- `_docs/_MCP_SERVER/README.md`
- `_docs/_ROUTER/RESPONSIBILITY_BOUNDARIES.md`
- `_docs/_TESTS/README.md`

## Changelog Impact

- Add a `_docs/_CHANGELOG/*` entry when the verifier/status model ships or when
  verifier authority materially changes.

## Validation Commands

- `git diff --check`
- `PYTHONPATH=. poetry run pytest tests/unit/adapters/mcp/test_quality_gate_verifier.py tests/unit/tools/scene/ -v`
- `rg -n "reference_understanding|part_segmentation|classification_scores|quality-gate verifier|scene_truth|spatial_relation|mesh_metric" server/adapters/mcp tests/unit _docs/_TASKS/TASK-157*.md`

## Acceptance Criteria

- Gate status is evidence-backed and persisted.
- Required gate blockers are machine-readable.
- Scene mutations can invalidate gate status.
- Checkpoint payloads expose gate status without relying on prose summaries.
