Repository navigation
Description
Overview
Clicking Edit on a play opens a chat bound to that play, with a first message the system writes and five suggested replies. On the built-in model, picking the first suggestion, "Change when it runs", is answered with a question that has nothing to do with plays. The chat also opens without saying what the play does.
Problem Statement
Observed (desktop app, built-in Gemma 4 E4B, play "Complete a parent task when all its sub-tasks are done", prompt dump on):
- Edit opens the chat with "What would you like to change in [the play]?" and the five options.
- The user picks "Change when it runs".
- The reply is: "Are you trying to change when something runs (like setting a date/time), or are you changing its dependency relationship within a workflow?" with options "Change the execution time of a specific node?" and "Update when this task should run relative to other tasks in the plan?".
What the dump shows. One model call was made, the Stage-1 router, and the turn ended there (routing_decision="clarify", about 3.3s). The router was sent its general instructions with the list of all skills, and as the user message:
PRIOR CONTEXT (for background only — do not treat as part of the current request):
What would you like to change in [Complete a parent task when all its sub-tasks are done](nodespace://<id>)?
CURRENT REQUEST (route this):
Change when it runs
It called route_clarify. Nothing told it the chat is bound to a play, and it saw none of the play's content, so "when it runs" read as scheduling a task.
Why. The chat pins the play-authoring skill and the play, but a pin only adds the skill to Stage 2's candidates. Stage 1 runs unchanged, and a clarification from Stage 1 ends the turn before Stage 2. The pinned skill was never a candidate.
The wrapper around a follow-up message tells the model to ignore what explains it. Every reply after the first reaches Stage 1 as "PRIOR CONTEXT (for background only — do not treat as part of the current request)" followed by "CURRENT REQUEST (route this)". "Change when it runs" means something only because of the question before it; the wrapper labels that question as not part of the request, so the model judges the reply nearly on its own. This is not specific to plays: it applies to any short answer to the assistant's last message ("the second one", "yes, that", "change it").
Also. The opening message asks what to change without describing the play. The user wants the play described first, then the options. Every option is a change, so nothing tells the user the play can be asked about.
Proposed Solution
- A sixth option, listed first: "Explain this play". It tells the user the play can be probed as well as changed. Picking it, or asking in their own words ("tell me about this play", "I don't understand it", "when would this fire?", "what does this condition mean?"), is answered from the play's rules in plain language and writes nothing. The chat stays open for a change afterwards.
- A reply to the assistant's last message is routed with that message. The Stage-1 wrapper stops calling the previous assistant message background to be set aside: when the current request is short or refers back ("it", "that", "the second one", or one of the options just offered), Stage 1 is told to read it as an answer to that message. Requests that stand alone still route on their own.
- Opening message describes the play, then asks. Built with no model call from what the play stores: the play's description, then for each rule what triggers it, what it checks and what it does, in the words of the rule's, conditions' and actions' required descriptions. The link stays, with six options.
- Stage 1 cannot stop a chat that pins a skill. In such a chat Stage 1 is told what the chat pins (the skill, and the pinned node's title and type), and a
clarifyfrom Stage 1 does not end the turn: the request goes on to Stage 2 with the pinned skill, which asks its own question when one is needed. - A reply that is one of the opening message's own options is never treated as ambiguous in that chat.
Documentation
- ADR-090 §1 (the required descriptions the opening message is built from), §3 (the opening message and its six options, amended) and §5 (routing in a chat with pinned skills, amended)
- ADR-038 - the two routing stages
- prompt-dump.md - how the observation above was captured, and how to capture the fix
- Updates:
components/seeded-nodes.mdif it describes routed turns in a pinned chat. The ADR amendments are on nodespace-docsmain.
Acceptance Criteria
- Edit opens a chat whose first message describes the play (its description and each rule's trigger, conditions and actions from their stored descriptions) and then asks what to change, with the six options ("Explain this play" first), and no model call is made to produce it
- On the built-in model, "Explain this play" and a question in the user's own words ("I don't understand it", "when would this fire?") are answered from the play's rules, in plain language, and nothing is written
- A short reply that refers back to the assistant's last message is routed as an answer to it, in any chat; a request that stands alone routes as before
- On the built-in model, each of the five change options, picked as the first reply, reaches the play-authoring skill and is answered about that play; none is answered with a clarification from Stage 1
- In a chat that pins a skill, a Stage-1
clarifydoes not end the turn, and Stage 1's request names what the chat pins - A chat that pins nothing routes exactly as before
- A prompt dump of the first reply shows the play-authoring skill and the play's rule in what the model was sent
- Once fixed, one first reply in a play's Edit chat is sent through a hosted OpenAI-compatible model (a free-tier one is enough) and the result is recorded: accepted, or rejected for message order. The chat's first message is the assistant's, which only the built-in model has been shown to accept (not run: no endpoint or key; tracked in Check a play's Edit chat on a hosted OpenAI-compatible model #3750)
- Tests cover: the opening message for a play with one rule and with several; a pinned chat where Stage 1 would clarify; an unpinned chat where it still does
- Code passes
bun run quality:fixandbun run test:changed
Technical Specifications
Reference Files
packages/daemon/src/services/play_edit_chat.rs-create_play_edit_chat,EDIT_OPTIONS, the opening messagepackages/agent/src/local_agent/agent_loop.rs- Stage 1, theclarifyoutcome,session.pinned_skills,routing::with_pinned_skillspackages/agent/src/local_agent/routing.rs- the Stage-1 prompt and toolspackages/daemon/src/services/local_agent_service.rs- where a chat's pins reach the sessionpackages/agent/src/seeds/skills/play-authoring.md
Implementation Details
- Model-facing text in
packages/agentis pinned by the prompt snapshot; regenerate withUPDATE_GOLDEN=1and review the diff. - The wrapper is used for every follow-up turn in every chat, so changing it is the widest part of this issue. Run the routing eval scenarios before and after, three repetitions on the scenarios it touches and then one full pass, and record both. A request that stands alone must route as before.
- Explaining a play is a read. Check that the play-authoring skill, or a turn narrowed to read-only context, cannot write while answering it.
- The opening message is stored content, so a play edited later is described as it was when the chat was opened. That is acceptable; say so in the code.
- Reproduce and verify with
NODESPACE_PROMPT_DUMPon the built-in model. No hosted provider is needed.
Related Issues
- Three unverified checks on the OpenAI-compatible (BYO-key) path against a hosted provider #2189 (closed; its one unverified check, an assistant-first conversation on a hosted provider, is a criterion here)
Non-Goals
- Changing how routing works in a chat that pins nothing
- The wording or behaviour of the play-authoring skill itself
Activity
[-]A play's Edit chat: describe the play first, and stop general routing from derailing the first reply[/-][+]A play's Edit chat: describe the play first, let the user ask about it, and route a reply with the message it answers[/+]malibio commentedon Oct 11, 2026
Frontend: 324 test files passed (5873 tests)
Describe the play in its edit chat, and route a reply with the messag…
Lead a picked option with the pinned skill (refs #3738)
A play's Edit chat describes the play first, and a reply is routed wi…