core/generate/contemplation/findings.py
Shay 1adf4f5de5 feat(contemplation): contemplation v0 pass manager (N6) + boundary-first growth fix
generate/contemplation/{findings,pass_manager}.py: a single bounded pass — route (N3) -> classify+enrich (N4) -> terminal -> maybe emit proposal-only (N5). No loops/daemon/L10. Seven terminals: SOLVED_VERIFIED / REFUSED_KNOWN_BOUNDARY / REFUSED_UNSUPPORTED_FAMILY / CONTRADICTION_DETECTED / PROPOSAL_EMITTED / AMBIGUOUS_ORGAN / NO_PROGRESS. R2 solved+verified end-to-end; R1 routed setup is SOLVED_VERIFIED (numeric answer stays the eval lane in v0).

Hazard found+fixed: N6 exposed that category_pair_not_found fires on ANY non-R2 text, so mapping it to a growth surface made gibberish falsely PROPOSAL_EMITTED. Reclassified it to input_shape and made missing_category_pair reserved — only the PRECISE missing_total_count/missing_weighted_total remain reachable growth surfaces. Classification is boundary-first (input_shape non-blocking), so a problem one organ recognizes as a substantive boundary never proposes against the other's broad refusal.

Acceptance proven: known correct refusal -> no proposal; unsupported gap -> proposal-only artifact (exactly the 2 missing_* gaps over the gold); answer-key contradiction -> CONTRADICTION_DETECTED; organ conflict -> AMBIGUOUS_ORGAN. 188 tests green incl. architectural invariants; R1 7/0/3 + R2 reader 10/0/0 unchanged; off-serving.
2026-06-07 08:59:47 -07:00

34 lines
1 KiB
Python

"""Typed terminal states + per-pass findings for the contemplation pass manager (N6).
v0 is a single bounded pass chain — no loops, no daemon, no L10 runtime. Each pass appends a
``Finding`` (a traceable artifact, not hidden chain-of-thought), and the chain ends in exactly
one ``Terminal`` state.
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
class Terminal(str, Enum):
"""The terminal state of one bounded contemplation pass."""
SOLVED_VERIFIED = "SOLVED_VERIFIED"
REFUSED_KNOWN_BOUNDARY = "REFUSED_KNOWN_BOUNDARY"
REFUSED_UNSUPPORTED_FAMILY = "REFUSED_UNSUPPORTED_FAMILY"
CONTRADICTION_DETECTED = "CONTRADICTION_DETECTED"
PROPOSAL_EMITTED = "PROPOSAL_EMITTED"
AMBIGUOUS_ORGAN = "AMBIGUOUS_ORGAN"
NO_PROGRESS = "NO_PROGRESS"
@dataclass(frozen=True, slots=True)
class Finding:
"""One pass's typed result — name of the pass and a short summary of what it observed."""
pass_name: str
summary: str
__all__ = ["Finding", "Terminal"]