Skip to main content
Version: Next

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​

  1. The page writes the answer to an inbox, not to the tracker. POST /api/answers validates and writes one file under ORION_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 at orion-failed, puts it back in the queue by the rule orion queue --reset uses (planQueueAdd: never a ticket a run owns, never one that could not be claimed). The web process can write nothing outside ORION_HOME.
  2. 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.
  3. 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.
  4. The person is told where their answer is. The page shows it as "waiting for the watcher", then "delivered" with the outcome sentence.
  5. 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 main first.