11 KiB
ASK Serving Integration Scoping — ask_serving_enabled, QUESTION_NEEDED, and Carve-Out Retirement
1. Current State
Currently, the ASK capability exists strictly off-serving.
- Residue Capture (Q1-B): The
core/epistemic_disclosure/limitation.pymodule capturesLimitationAssessmentwith typed ASK residue includingMissingSlotandgrounded_terms. Specifically,missing_total_countandmissing_weighted_totalare classified as ask-oriented inside the disclosure layer. - Carve-Out Safety (Q1-B): The transitional carve-out constant
Q1B_ASK_CARVE_OUTis defined incore/epistemic_disclosure/limitation.py. The registry incore/comprehension_attempt/failure_family.pypreservesproposal_allowed=Truefor these carve-out families. This guarantees that the proposal-pile signal remains active and uninterrupted until served ASK is fully wired and verified. - Grounded Rendering (Q1-C): The
core/epistemic_questions/render.pymodule safely rendersEpistemicQuestionstructures. It enforces structural rendering, ensuring no ungrounded problem-entity names or internalsnake_casetokens escape to the user. Multi-slot, unmapped, or unsafe cases fall back toquestion_unrenderable. - Off-serving Delivery (Q1-D): The delivery infrastructure in
core/epistemic_questions/delivery.pydefinesDeliveredQuestionand ships theTerminal.QUESTION_NEEDEDtenant. The resulting off-serving artifacts are written directly to theteaching/questions/sink. No served/user-facing surfaces are exposed. - Default-Dark Gate (Helper): The helper function
ask_serving_enabledis implemented incore/epistemic_questions/serving_gate.py. It operates in a fail-closed, default-dark manner. If the config fieldask_serving_enabledis absent, it returnsFalse. An explicit, truthy configuration is required to allow served ASK. - Integration gaps: Currently,
generate/contemplation/pass_manager.pydoes not emit served ASK,chat/runtime.pydoes not expose ASK, and theQ1B_ASK_CARVE_OUTremains active (unretired).
2. Non-Negotiable Boundary
Before ASK can be delivered to any user-facing surface, the following boundaries must be strictly enforced:
- Strict Gate Guard: No served question may be shown without an explicit, active
ask_serving_enabledconfiguration check. - Fail-Closed Default: The
ask_serving_enabledhelper must default toFalse. A missing orNoneconfig attribute must evaluate toFalse. - Prose Encapsulation: The serving layer must not construct or mutate question prose directly. It may only consume pre-rendered
EpistemicQuestion/DeliveredQuestionstructures produced by Q1-C/Q1-D. - No Contentless Delivery: An unrenderable ASK must never be promoted to
QUESTION_NEEDED. ContentlessQUESTION_NEEDEDoutcomes are strictly forbidden. - Carve-Out Preservation: The
Q1B_ASK_CARVE_OUTmust remain active and unchanged until served ASK is fully verified. No proposal signal may be lost before a servedQUESTION_NEEDEDis verified live. - Sink Distinction: The
question_only(teaching/questions) sink must remain logically and physically distinct from theproposal_only(teaching/proposals) sink. - Zero Impact on Claims: No benchmark,
CLAIMS.md, or performance metrics may be modified by this scoping documentation.
3. Proposed Served Gate: ask_serving_enabled
The serving gate helper exists under core/epistemic_questions/serving_gate.py. This document scoping defines how future served-surface code must interact with the gate:
- Helper Invariant: Future code in the served-surface layer (e.g.,
chat/runtime.py) must verifyask_serving_enabled(config)before delivering anyQUESTION_NEEDEDresponse to a user. - Off-Serving Isolation: The gate controls served (user-visible) output only. It must not disable or interfere with off-serving artifacts written to the
teaching/questions/directory.
Serving Gate Policy
| Config State | ask_serving_enabled(...) | Served ASK Allowed? |
|---|---|---|
| Missing field | False |
No |
None / Default config |
False |
No |
Explicit False |
False |
No |
Explicit True |
True |
Only if rendering and delivery obligations pass |
4. pass_manager Integration Boundary
This section defines the future integration interface for generate/contemplation/pass_manager.py. This is scoping only; no execution is performed here.
- Evaluation: The refusal/comprehension flow yields a
ComprehensionAttempt. - Assessment: A
LimitationAssessmentis derived from the attempt. - Resolution Action: If
resolution_action == "ask_question":- The pipeline invokes
deliver_ask(assessment). deliver_askcallsrender_questionexactly once.- If the question is renderable, the final
DeliveryOutcometerminal becomesQUESTION_NEEDED. - If the question is unrenderable, the outcome falls back to the standing disposition (e.g., proposal or refusal).
- The pipeline invokes
- Gate Enforced downstream:
generate/contemplation/pass_manager.pymay produce/record ASK delivery outcomes later, but user-visible exposure remains gated downstream byask_serving_enabled(e.g., inchat/runtime.py).
- Constraints:
pass_managermust not contain prose templates or formatting rules.pass_managermust not constructDeliveredQuestionmanually (it must delegate todeliver_ask).pass_managermust never bypassdeliver_ask.pass_managermust never emit a contentlessQUESTION_NEEDED.
5. Served Behavior Matrix
| Assessment / Rendering | Gate Disabled | Gate Enabled |
|---|---|---|
Renderable ask_question |
No served ASK; existing refusal/proposal behavior preserved | Served QUESTION_NEEDED is allowed |
Unrenderable ask_question |
Standing fallback; no QUESTION_NEEDED |
Standing fallback; no QUESTION_NEEDED |
| Non-ASK limitation | Unaffected | Unaffected |
missing_total_count / missing_weighted_total (carve-out) |
Proposal signal preserved | Served ASK only after carve-out retirement proof |
| Multi-slot ASK | Unrenderable fallback | Unrenderable fallback |
Note: Gate enabled is a necessary but not sufficient condition for serving. The renderable checks and delivery invariants must also pass.
6. Q1B_ASK_CARVE_OUT Retirement Conditions
The transitional carve-out constant Q1B_ASK_CARVE_OUT can only be retired and removed from core/epistemic_disclosure/limitation.py when the following milestones are met and verified:
- The
ask_serving_enabledhelper is tested and confirmed default-dark. - The
pass_manager.pyASK integration is fully implemented behind the gate. - Served
QUESTION_NEEDEDterminal behavior is successfully tested using renderableEpistemicQuestioninstances. - Unrenderable ASK paths are verified to fall back correctly, never emitting
QUESTION_NEEDED. - Carve-out keys
missing_total_countandmissing_weighted_totalare proven to yield safe renderable questions (or safe standing fallbacks). - A dedicated no-question/no-proposal dead-zone validation test is introduced and passes.
- The registry in
core/comprehension_attempt/failure_family.pyflipsproposal_allowed=Falsefor the carve-out families without dropping signal. - The
teaching/questions/(question_only) sink remains physically distinct from theteaching/proposals/(proposal_only) sink. - Smoke, contemplation, proposal, and disclosure test suites remain fully green.
Until all 9 conditions are met, the registry's proposal_allowed=True setting for these families must remain.
7. No-Dead-Zone Proof Obligation
The Dead-Zone Hazard
If proposal_allowed is flipped to False on a failure family before ASK serving is enabled/renderable, an input falling into that family would yield no proposal signal AND no served question. This results in a silent loss of capability (a dead zone), violating the wrong=0 refusal-first discipline.
Required Proof Before Retirement
Before the carve-out is retired, tests must prove that for each carve-out family:
- If
proposal_allowedis removed, either a servedQUESTION_NEEDEDis emitted safely, or the standing fallback preserves an admissible signal. - The test suite must assert failure if an evaluation result yields neither a proposal nor a valid served question.
Suggested Test Names
test_ask_serving_disabled_preserves_existing_proposal_signaltest_carveout_retirement_has_no_question_no_proposal_dead_zonetest_unrenderable_ask_never_emits_question_neededtest_pass_manager_uses_deliver_ask_not_direct_renderingtest_question_only_not_proposal_only
8. Required Future Tests Before Wiring
The implementation PR must include tests asserting the following behaviors:
- Gate Default:
ask_serving_enableddefaults toFalse. - Config Completeness: A missing config field evaluates to
False. - Opt-in Activation: An explicit
Trueconfiguration is required to allow served ASK. - Gate Override: If the gate is disabled, no served ASK is emitted even if
deliver_askproduces aQUESTION_NEEDEDoutcome. - Rendering Obligation: If the gate is enabled, the output still requires a renderable
EpistemicQuestion. - Unrenderable Fallback: Unrenderable ASK instances are never served.
- Prose Isolation:
pass_managerdoes not construct prose templates or strings. - Delegated Delivery:
pass_managerdelegates entirely todeliver_askand does not callrender_questiondirectly. - No Empty Terminals: No contentless
QUESTION_NEEDEDoutcomes are permitted. - Sink Safety: The
question_onlyartifact is written to the correct, distinct location. - Carve-out Lock:
Q1B_ASK_CARVE_OUTis preserved until both the gate and the dead-zone proofs are active. - Registry Guard: Flipped registries are blocked until all retirement conditions are met.
9. Non-Claims
This scoping document establishes architectural boundaries only:
- No Implementation: It does not implement served ASK.
- No Wiring: It does not wire
generate/contemplation/pass_manager.pyorchat/runtime.py. - No Retirement: It does not retire
Q1B_ASK_CARVE_OUTor flip any registryproposal_allowedflags. - No Metric Changes: It does not alter GSM8K benchmark claims or refusal behaviors.
- No General Intelligence: It does not make ASK generally intelligent; it simply bounds the served-surface gate.
10. Recommended Next Slice
To safely approach the implementation, the next sequential slices are recommended:
Slice 1: Configuration Definition (No Wiring)
- Add a concrete configuration field
RuntimeConfig.ask_serving_enabled: bool = False(if not already present). - Ensure the helper
ask_serving_enabled(...)references this configuration. - Write configuration tests verifying the default and override values.
- Do not wire
pass_manageror modify runtime loops.
Slice 2: pass_manager Integration
- Wire
pass_managerto calldeliver_askwithout constructing prose; any user-visible ASK exposure remains behindask_serving_enabled; preserveQ1B_ASK_CARVE_OUT.