The fourth and final Q1 rung: route the Q1-C rendered question onto the contemplation bus as the QUESTION_NEEDED tenant (sibling of PROPOSAL_EMITTED), off-serving. Consumes render_question VERBATIM — Q1-D constructs no prose, so the Q1-C grounded-rendering wrong=0 guard is never bypassed by a second surface. - generate/contemplation/findings.py: add Terminal.QUESTION_NEEDED. - core/epistemic_disclosure/limitation.py: ask_question's home terminal is now QUESTION_NEEDED, making terminal_for_action total (all six actions map onto shipped terminals — the consolidation proof is now complete, not 'five of six'). - core/epistemic_questions/delivery.py: DeliveredQuestion (proposal-only artifact, cannot wrap an unrenderable question / cannot be served / answer_binding reserved None — illegal states unrepresentable), DeliveryOutcome, deliver_ask, the teaching/questions sink emitter, and AnswerBinding (reserved for Q2). Rulings honored: - D1: off-serving only — no served surface, no ask_serving_enabled, no chat wiring. - D2: an unrenderable ASK falls back to the family's standing disposition (PROPOSAL_EMITTED if it still proposes, else NO_PROGRESS) — never a contentless QUESTION_NEEDED. Enforced twice: in deliver_ask and structurally in __post_init__. - D3: Q1B_ASK_CARVE_OUT untouched — registry keeps proposal_allowed=True; both signals coexist off-serving so no operational signal is lost. - D4: sink under teaching/questions/ (sibling of teaching/proposals/). - D5: strictly single-slot — multi-slot is unrenderable, takes the D2 fallback. Tests: 16 delivery tests (happy path verbatim, both D2 fallback branches, structural guards, idempotent sink, off-serving AST) + updated the two limitation consolidation tests for the now-total terminal map. smoke 90/0, affected suites 128/0.
40 lines
1.5 KiB
Python
40 lines
1.5 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"
|
|
# The ASK tenant (Q1-D): a solvable attempt blocked on missing/ambiguous *input*
|
|
# that a grounded question can intake. A SIBLING of PROPOSAL_EMITTED, never a
|
|
# subtype — a proposal offers a capability for review; a question requests a datum
|
|
# from the user. Off-serving: produced by the Q1-D delivery layer into the
|
|
# teaching/questions sink, never served until a future ask_serving_enabled gate.
|
|
QUESTION_NEEDED = "QUESTION_NEEDED"
|
|
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"]
|