Commit graph

1 commit

Author SHA1 Message Date
Shay
41664ce60d feat(ask): add carried-handle acquisition seam for served ASK
The missing-boundary doc (#682) established that chat/runtime.py has no
lawful in-turn provider for a QUESTION_NEEDED ContemplationResult: the
only producer is the off-serving contemplation pass, and scanning
teaching/questions/ would be new, unspecified acquisition logic. This
slice builds the recommended unblocking seam instead of the forbidden
runtime shortcut: carried-handle acquisition.

core/epistemic_disclosure/ask_handle.py:
- AskArtifactHandle — an explicit, caller-carried reference to one
  already-produced Q1-D DeliveredQuestion artifact. Provenance is the
  producer's own content address (sha256 of blocking_reason:slot_name:
  text, also the artifact filename stem) — the only identity field the
  Q1-D artifact carries today. No turn/case provenance exists yet; that
  boundary is documented, not invented.
- resolve_served_ask_handle — gate-first (zero filesystem access while
  ask_serving_enabled is dark), structural handle validation, single
  explicit-path artifact read (no glob/iterdir/scan), and content-hash
  re-derivation so a stale/replaced/tampered artifact fails closed.
  Emits a ResolvedAskCandidate duck-typed to what evaluate_served_ask
  reads (terminal/question_path/proposal_path) — no question prose is
  ever constructed or carried.
- acquire_served_ask_from_handle — composes resolution into the
  existing acquire_served_ask_candidate / evaluate_served_ask stack.
  All Q1-D artifact policy (status/review/served/answer-binding/text/
  slot/collision) stays delegated; the seam owns identity only.

Not changed: chat/runtime.py, chat(...) signature, ChatResponse,
TurnEvent, telemetry schema, Q1B_ASK_CARVE_OUT, proposal_allowed,
VERIFIED serving, CLAIMS/metrics/lane pins. The seam imports neither
generate.contemplation (pass_manager) nor core.epistemic_questions
render/delivery — enforced by AST tests.

Tests (tests/test_ask_handle.py, 18 cases): gate-dark no-I/O proof,
fallback preservation, valid resolution served end-to-end through the
existing stack, proposal-artifact / missing / malformed / invalid-Q1-D
/ path-collision / stale-hash / non-addressed-filename / structurally-
invalid-handle fail-closed paths, no-discovery-without-exact-handle,
and AST guards for scan primitives, forbidden imports, and prose.

Verification: focused ASK+governance suites 396 passed; architectural
invariants 56 passed; smoke-equivalent suite 90 passed; lane SHAs 8/9
content-match (the 9th is the documented local public_demo wall-clock
flake, 48.3s vs the 30s ADR-0099 budget — no content drift, no re-pin).
2026-06-10 10:53:54 -07:00