The Companion-as-interface principle says the Operator changes settings, and increasingly operates the system, by talking to the Companion. That principle has a hole: a settings screen shows you what you can change, but a conversation shows you nothing until you ask — and you can't ask for what you don't know exists. An Operator could sit in front of the Companion never knowing the wait time is adjustable, or never knowing what they're able to do in the room they're in.
This capability fills that hole. The Operator can ask the Companion "what can I do here?" or "what can I change?" or "I'm lost — help," and the Companion answers with what's available in the current context — the actions this room offers and the settings this surface exposes — and can give examples of what to say to actually do each one. When the Operator asks for something close-but-not-quite (a setting by a name the Companion doesn't recognize), the Companion tells them what is available rather than just refusing.
The design holds three disciplines. It is pull, not push — the Companion answers when asked; it does not nag with unprompted lists (so the seed's "only show what is available" holds — nothing is shown unfilled). It is context-scoped — the answer is about here, not a global catalog dump. And it is generated, never hand-written — the list of what's available comes from the system's own registries, so it can never go stale the way the current (incomplete, hand-typed) settings list already has.
The Companion-as-Operator-system-interface standing note v0.1 commits Loomworks to conversation as the primary surface for Operator-system interaction. That commitment is incomplete without discoverability: a conversational interface that cannot tell the Operator what it offers leaves the Operator unable to use it. A settings screen is self-advertising (the controls are visible); a conversation is not (nothing is visible until asked, and you cannot ask for the unknown). So the standing note's principle obligates this capability — it is the discovery surface the principle assumes but does not itself provide.
The triggering observation: "the conversation is the interface" needs a way for the Operator to know which settings are available and how to modify them — and, more broadly, an Operator who is lost should be able to engage Loomworks to identify what to do and ask for examples.
Scope. The capability answers, in the current context: - What can I do here? — the actions available in this room/surface (contribute, organize, shape, render, adjust, and the rest, scoped to context). - What can I change here? — the settings adjustable in this context (the "adjust" category; subsumes the settings-discovery case). - I'm lost / what's next? — orientation: what a sensible next step is, given the current state. - Show me / for example? — drive-it examples: what the Operator could say to the Companion to do each available thing ("you could say: 'add a note that…'").
The gap. No discovery or help intent exists. The 20-intent classifier taxonomy is all action intents plus one catch-all (general_conversation), which has zero awareness of available actions or settings — a "what can I do?" today lands there and is answered conversationally with no catalog knowledge (it would deflect or invent). The one place capabilities are ever named — tune_setting's unknown_setting response — is hardcoded prose, lists only 2 of the 3 settings (it has already gone stale), and is reachable only by a failed tune attempt.
The two foundations to build on, not around.
- suggested_actions — the ConverseResponse field and its Operator-Layer renderer (SuggestedActions.tsx) are built end-to-end and state-aware, but wired only into the engagement-creation flow with hardcoded strings, empty on every other path. This is the surfacing pipe to generalize.
- tryPromptHint — static "you could say…" tooltips already exist ("draft a scoping note," "what should I do next"). Primitive (static, tooltip-only, and — tellingly — one suggests "what should I do next" while nothing answers it), but the seed of the examples half.
The three shared missing pieces (settings discovery and orientation fail on the same three):
1. No capability-query intent.
2. No enumerable, context-scoped catalog (settings exist as KNOWN_SETTINGS but unsurfaced; room-actions are not enumerated at all).
3. No surface-context signal on ConverseRequest.
These were settled with the Operator before scoping; recorded here with their reasoning and the alternatives set aside.
Settings discovery is one category of orientation — the "adjust" category alongside contribute / organize / shape / render. A single capability-query/orientation intent handles both: "what can I change" returns the adjust-category slice; "what can I do" returns the whole context-scoped catalog.
Set aside: two separate intents (a settings-discovery intent and an orientation intent). Rejected because it rebuilds the same machinery (intent + catalog + scoping + surfacing) twice for what is one question at different granularities.
The answer must be scoped to the current surface — "what can I do here," not a global dump. ConverseRequest carries project_id (which engagement) but no surface signal, so this requires a new surface-context field on ConverseRequest, populated by the Operator Layer from the active surface.
Why it's load-bearing, not optional: the seed's "only show what is available" commitment practically requires it. A context-scoped answer shows what's available here (honoring the principle); an unscoped answer dumps all ~20 capabilities regardless of relevance (violating it in spirit — showing things not available in the current context). The difference is between a useful answer ("in voice listening you can adjust blur and the wait time") and an overwhelming one.
Set aside: deferring scoping (engine answers "everything"). Rejected — it makes the feature much weaker and sits against "only show what is available."
The catalog answer is generated from source registries, never restated in prose. This is the spine, and it is the direct lesson of the unknown_setting defect: hand-written capability text rots — the current settings list drifted to 2-of-3 the moment a third setting landed.
Two source registries feed the catalog:
- Settings (the "adjust" category) — from KNOWN_SETTINGS, extended with a canonical display name per setting (none exists today; names live as a synonym list in _LABEL_TO_KEY, none marked primary). A small enumeration helper joins key → canonical-name → bounds → conversation-synonyms.
- Room-actions (the rest) — a new room→actions registry (net-new; does not exist). The 20-intent taxonomy is the raw material, but it is a flat classifier list with no room-scoping, no descriptions, and no example phrasings. The registry maps each room/surface to the actions available there, each carrying a plain-language description and one or more drive-it example phrasings.
Set aside: a hand-maintained catalog document. Rejected — it is exactly the thing that already rotted; the registry is the single source so the answer cannot go stale.
suggested_actionsThe orientation answer populates suggested_actions (now context-aware and generated), rendered by the existing SuggestedActions.tsx. This reuses the one pipe already built end-to-end rather than building a parallel channel.
The widening, named: suggested_actions today means "next steps in the creation flow." This widens it to "what you can do here." That is the right widening — next-steps and what-you-can-do are the same family — but it changes the field's meaning and touches the creation flow's existing behavior, so the CR must preserve the creation-flow population as one case of the general mechanism, not break it.
Set aside: a new dedicated discovery-response channel. Rejected — suggested_actions + its renderer already work front-to-back; a parallel channel duplicates them.
"Show me / for example" yields drive-it examples — what the Operator could say to the Companion to perform an available action ("you could say: 'add a note that the client prefers email'"), not examples of finished work-products. This teaches the Operator to drive Loomworks.
The examples live in the room-actions registry (§3.3) — each action carries its example phrasing(s) as registry data, so they are generated with the catalog, not hand-written per surface (the failure mode the static tryPromptHint tooltips show — coarse, per-surface, disconnected from any handler). The existing tryPromptHint strings are the seed: the build migrates their content into the registry as the first examples and wires them to the answering handler, so "what should I do next" (which a tooltip already suggests) becomes a question the Companion actually answers.
The queued-directions §6.4 Explain affordance is orientation's sibling, not its parent. Both belong to the discipline-plus-recovery family (every UX discipline that reduces a gap needs a recovery affordance for the residue). But they address different gaps: - Explain (§6.4) — comprehension recovery: "what did you mean by that?" (the Operator didn't grasp a Companion utterance). - Orientation (this note) — capability discovery: "what can I do here?" (the Operator doesn't know what's available).
§6.4's anticipated sibling list does not include orientation; the record had no orientation entry. This note records orientation as the new sibling and follows §6.4's shape (the affordance model below).
Why orientation builds ahead of §6.4, which is deferred. §6.4 is gated on Phase-32 lived-Operator calibration evidence because its hard problem is voice composition — phrasing a clarification on-discipline, which needs real-use data. Orientation's hard problem is different and more mechanical: enumeration — knowing what's available here, which is knowable from the code today and needs no calibration evidence to be correct. The catalog is a registry problem, not a voice problem. (The examples half has a voice element, but it is registry-authored drive-it phrasings, lower-stakes than Explain's clarification composition.) So orientation is buildable now in a way Explain is not. This was a flagged, Operator-confirmed decision: build orientation ahead of its sibling.
Affordance model (following §6.4). §6.4 anticipates button mode (text substrate) and audible mode (voice substrate). Orientation follows the same: the primary build is text/conversational (ask in the conversation, answered via suggested_actions) — no voice-modality substrate required, matching §6.4's button-mode-first candidate. An audible "what can I do here" rides the shared voice-modality substrate later, alongside §6.4's audible mode, mobile presence, and quick-capture — voice-modality work compounds across all of them. This note scopes the text/conversational build; audible is a later voice-modality-arc addition.
This is an engine + Operator-Layer build. Proposed CR structure (to be settled in the CR itself):
Engine:
1. Settings enumeration helper — a function over KNOWN_SETTINGS returning the catalog (key, canonical display name, bounds, synonyms). Add a canonical display name per setting.
2. Room-actions registry — net-new: room/surface → available actions, each with a plain-language description and drive-it example phrasing(s). Seeded from the intent taxonomy + the migrated tryPromptHint content.
3. Orientation intent + handler — a new capability-query intent in the classifier; a handler that assembles the context-scoped catalog (settings slice + room-actions slice) and populates suggested_actions. Handles the full-catalog ("what can I do"), the adjust-slice ("what can I change"), and the orientation/next-step ("I'm lost / what's next") cases.
4. unknown_setting fix — repoint tune_setting's near-miss response at the enumeration helper so it names all current settings, generated. (This is the staleness defect; see §7 — it ships as part of this build, and the helper it needs is piece 1.)
5. Surface-context field on ConverseRequest — so the handler can scope to the current surface.
Operator Layer:
6. Pass surface context — populate the new ConverseRequest field from the active surface.
7. Generalize suggested_actions rendering — render the orientation answer through SuggestedActions.tsx, preserving the creation-flow case as one instance of the general mechanism.
8. Migrate tryPromptHint content into the registry (engine piece 2) and wire the tooltips' suggested utterances to the now-answering handler.
Sequencing within the CR: engine pieces 1–2 (the registries/helpers) are the foundation; piece 4 (the unknown_setting fix) can land early since it only needs piece 1; pieces 3 + 5 are the capability proper; OL pieces 6–8 surface it. The CR will sequence per-step with halts, the API-grind rhythm.
The unknown_setting staleness is a live defect independent of the larger capability: the Companion currently tells Operators an incomplete list of adjustable settings (2 of 3), and will keep rotting as settings are added. The fix (engine piece 4) makes it generate from KNOWN_SETTINGS via the enumeration helper (piece 1), so it cannot rot again. It is called out separately so that, if the Operator ever wants the defect fixed ahead of the full capability, it can be pulled forward as a one-piece correction — but as planned it ships within this build, since it shares the enumeration helper.