0027: A person's answer reaches the ticket through an inbox the watcher drains
- Status: Accepted (Navjyot, 2026-10-06; proposed 2026-10-05)
- Date: 2026-10-05
- Related: 0024 (authentication for every write), 0026 (the allowlist this adds an entry to), 0001 (the watcher owns what happens to a ticket)
Contextβ
The second half of the web's end goal is that a person can answer what an agent
stopped on without leaving the browser. Today that means finding the ticket in
Jira, writing a comment, and moving it back to the queue by hand. Orion already
treats a person's plain comment as the answer: the implementer's prompts carry
the three newest (internal/work/notes.go), and orion queue --reset puts a
failed ticket back.
The web package holds no tracker credential, deliberately: the one process that faces a browser should not also be able to write to Jira.
Decisionβ
- The page writes the answer to an inbox, not to the tracker.
POST /api/answersvalidates and writes one file underORION_HOME/answers/(internal/answers). The watcher, which holds the credential, drains the inbox at the start of every tick: it posts the comment and, when the ticket is sitting atorion-failed, puts it back in the queue by the ruleorion queue --resetuses (planQueueAdd: never a ticket a run owns, never one that could not be claimed). The web process can write nothing outsideORION_HOME. - Only a ticket waiting on a person can be answered. The handler refuses a key whose latest run did not end escalated, refused or failed. It is not a way to comment on any ticket in the tracker.
- An answer is delivered once. The comment is posted before the file moves
to
answers/done/; if the comment cannot be posted the answer stays and is retried next tick; once posted it never is again, whatever became of the requeue, and the outcome says what did not happen. - The person is told where their answer is. The page shows it as "waiting for the watcher", then "delivered" with the outcome sentence.
- Bounds. Two thousand characters, the length the agent reads of a note; no control characters; one request body of at most 16 KiB; unknown fields refused; one pending answer per ticket.
Consequencesβ
- An answer takes effect on the next watcher pass, not instantly. A person who answers with no watcher running sees "waiting for the watcher" and nothing else, which is true.
- The advisor does not see answers, as today: they reach the implementer's prompts only.
- The comment starts with a fixed heading so it is recognisably from the page. It must not read as Orion's own comment, or the next run would drop it.
Rejectedβ
- The web process calls Jira. Instant, but it gives the browser-facing
process a tracker credential and needs the claim guard moved out of
package mainfirst.