feat(runtime): typed slots and principal/conversation-scoped clarification dialogue (#155) #284

Closed
nsaspy wants to merge 0 commits from rage/155-typed-slots into master
Owner

Summary

Implements #155 against the frozen IntentFrame v1 contract (#154, docs/intentframe-contract.md), per the design in rage/155-clarification-dialogue.org (D1-D12, adversarial review, A2 test-matrix row).

  • zara/runtime/frames.py — IntentFrame v1 Python mirror: closed typed slot value set (text/number/duration/datetime/ref/boolean), slot origins, frame statuses. Frames are pure values and carry no envelope metadata (frame_id/supersedes live in session bookkeeping only).
  • zara/runtime/clarification.py — ClarificationCoordinator: one open session per (principal, conversation); deterministic question order from required slots; follow-ups fill only the active requested slot; focused retry after invalid answers with bounded attempts; corrections ("actually five minutes") rotate the frame id and record supersedes; cancellation phrases close cancelled; TTL expiry on an injectable virtual clock (no sleeps); bounded session count / value size / lifetime; uniform byte-identical stale rejection wording (no cross-principal inference); drop_all for typed degraded restart/shutdown.
  • RuntimeHost owns a coordinator (D2) and drops open sessions on restart/shutdown.
  • Wake pending path: pending(open)/pending(text)/pending(python(schedule_todo)) open dialogue templates and answer with the deterministic question; follow-ups are routed to the open session before the command gate; completion executes via the existing execute_intent/python_skills paths and closes the session. Unknown pending shapes keep the legacy prompt (bounded migration).
  • Non-goals honored: no provider execution (frames are handed back, not executed by the machine), no Android, no second ContextManager, no Prolog dynamic state.

Closes #155

Test plan

  • 26 machine-level state-machine tests (mandatory examples: timer ask/fill, "bananas" focused retry, cancel-then-late-answer not consumed, correction 20->5 with supersedes, open->app, text sarah->message, deterministic two-slot order, A/B principal isolation, two conversations, stale uniformity across expired/cancelled/restarted/none, double-hold guard, cancel-vs-fill race, capacity bound, virtual-clock timeout, attempts bound, oversized values, ambiguity choice, supersede-on-new-dialogue, frame-envelope split, typed validation).
  • 9 wake wire-up tests (pending -> question -> fill -> "Executed: ...", never-mind, retry, two-slot text flow, schedule_todo skill, command supersede, agent fallback unchanged, legacy prompt for unknown shapes, execution failure closes cleanly).
  • 3 RuntimeHost ownership tests (coordinator exposed; restart/shutdown drop sessions with typed superseded state).
  • Non-interactive dialogue script walking every mandatory example in one deterministic conversation.
  • Migrated fixtures in test_command_routing.py / test_latency_metrics.py carry the coordinator; the pending-prompt test now asserts the new required behavior.
  • Full local gate at candidate head: scripts/test-all.sh 10/10 phases, nix flake check green, nix build green.
## Summary Implements #155 against the frozen IntentFrame v1 contract (#154, docs/intentframe-contract.md), per the design in `rage/155-clarification-dialogue.org` (D1-D12, adversarial review, A2 test-matrix row). - `zara/runtime/frames.py` — IntentFrame v1 Python mirror: closed typed slot value set (text/number/duration/datetime/ref/boolean), slot origins, frame statuses. Frames are pure values and carry **no** envelope metadata (frame_id/supersedes live in session bookkeeping only). - `zara/runtime/clarification.py` — ClarificationCoordinator: one open session per (principal, conversation); deterministic question order from required slots; follow-ups fill only the active requested slot; focused retry after invalid answers with bounded attempts; corrections ("actually five minutes") rotate the frame id and record `supersedes`; cancellation phrases close cancelled; TTL expiry on an injectable virtual clock (no sleeps); bounded session count / value size / lifetime; uniform byte-identical stale rejection wording (no cross-principal inference); `drop_all` for typed degraded restart/shutdown. - `RuntimeHost` owns a coordinator (D2) and drops open sessions on restart/shutdown. - Wake pending path: `pending(open)`/`pending(text)`/`pending(python(schedule_todo))` open dialogue templates and answer with the deterministic question; follow-ups are routed to the open session before the command gate; completion executes via the existing `execute_intent`/`python_skills` paths and closes the session. Unknown pending shapes keep the legacy prompt (bounded migration). - Non-goals honored: no provider execution (frames are handed back, not executed by the machine), no Android, no second ContextManager, no Prolog dynamic state. Closes #155 ## Test plan - 26 machine-level state-machine tests (mandatory examples: timer ask/fill, "bananas" focused retry, cancel-then-late-answer not consumed, correction 20->5 with supersedes, open->app, text sarah->message, deterministic two-slot order, A/B principal isolation, two conversations, stale uniformity across expired/cancelled/restarted/none, double-hold guard, cancel-vs-fill race, capacity bound, virtual-clock timeout, attempts bound, oversized values, ambiguity choice, supersede-on-new-dialogue, frame-envelope split, typed validation). - 9 wake wire-up tests (pending -> question -> fill -> "Executed: ...", never-mind, retry, two-slot text flow, schedule_todo skill, command supersede, agent fallback unchanged, legacy prompt for unknown shapes, execution failure closes cleanly). - 3 RuntimeHost ownership tests (coordinator exposed; restart/shutdown drop sessions with typed superseded state). - Non-interactive dialogue script walking every mandatory example in one deterministic conversation. - Migrated fixtures in test_command_routing.py / test_latency_metrics.py carry the coordinator; the pending-prompt test now asserts the new required behavior. - Full local gate at candidate head: `scripts/test-all.sh` 10/10 phases, `nix flake check` green, `nix build` green.
nsaspy closed this pull request 2026-09-04 23:09:00 +00:00
Some checks failed
CI / test (pull_request) Failing after 9s
CI / android skeleton gate (pull_request) Failing after 5s
CI / shared mic / Arch Linux (pull_request) Failing after 10m41s
CI / shared mic / Ubuntu 24.04 (pull_request) Failing after 13m15s

Pull request closed

Sign in to join this conversation.
No description provided.