DUNIN7 · Loomworks · Completion Record
Plain-language summary
This is the spoken half of the current-engagement spine. CR-2026-123 made the engine able to resolve an engagement handle and set it as your current focus, but only through a direct endpoint call. This CR teaches the Companion the spoken triggers: say "open Goosey" (or "open 7", or "open E0007") and it takes you into that project; say "close" and it clears where you are. With both CRs merged, the full loop works — "open Goosey," then "commit held 14" lands in Goosey without re-naming, then "close" and the next unqualified instruction makes the Companion ask which project.
v0.2 folded a spoken "close" in alongside "open X," so this CR adds two intents. The risk in touching the live classifier is intent theft — a new intent capturing utterances that should mean something else, especially the common "close" family. That was checked empirically with a live key: the two new intents classify correctly and eight existing intents still classify as themselves. No tuning was needed.
Branch cr-2026-124-open-engagement-intent off the CR-2026-123 merge 6f785f9. Not pushed. No schema change (classifier-only).
| Commit | Step | Change |
|---|---|---|
4a1a129 | 0 | Archive CR v0.2 as branch base (baseline 6f785f9, suite 2966/46, alembic 0095). |
5e5d89a | 1 | open_engagement + close_engagement in IntentLabel (23 → 25); two classifier blocks + the open_engagement PARAMETER EXTRACTION line (the close block carries a disambiguation note vs orient and vs a confirmation turn); two instruction .md; both enumeration guards 23 → 25. |
d104c88 | 2 | _route_open_engagement (resolve → set focus → confirm; ambiguous-before-miss catch order) + _route_close_engagement (clear focus) + dispatch branches; helpers _engagement_display_name / _ambiguous_open_message. All replies server-composed. |
Suite: baseline 2966 → Step 1 2966/63 → Step 2 2973 passed, 0 failed, 63 skipped. The skipped count is 46 baseline + 17 new LLM-classification tests (@skip_no_llm_key) that skip in the keyless gate. No migration.
The classification + anti-theft tests (tests/test_cr_2026_124_open_close_intents.py) are LLM-dependent (the test_classifier.py pattern: @skip_no_llm_key). They skip in the keyless suite, so they were run directly against a live Anthropic key (from the repo .env) to exercise the anti-theft loop the CR anticipated:
open_engagement, with engagement_reference extracted ("Goosey" / "7" / "E0007").close_engagement.commit_assertion; "The deadline is March 15th." → add_knowledge; "Save this filter as 'urgent across all'." → save_filter; "Less blur." → tune_setting; "I want to start a new project." → create_project; "I need to download the report." → request_download; "What can I do here?" → orient; "What did I decide about the budget?" → ask_about_past_input. All held — neither new intent stole them.17/17 passed with the key. No tuning halt was needed (the expected "close"-collision halt did not fire).
IntentLabel members: open_engagement, close_engagement (23 → 25). Guards bumped at test_phase_54 (~587) and test_phase_55:144.orient and from a confirmation turn.playground_dev, rolled backno_project (asks), nothing in Personal — PASSHalt before push — Operator authorization required
The branch (3 commits, 4a1a129..d104c88) is not pushed. On your review and explicit authorization, push CR-2026-124 (merge --no-ff to engine main). With both CRs pushed, the full spoken open/close loop is live.
cr-2026-124-open-engagement-intent at d104c88, 3 commits ahead of main 6f785f9. Not pushed. Tree clean. No schema change (alembic stays 0095).change-requests/) and this completion record. The CR-2026-123 spine it depends on is already merged and pushed.