← All posts

Needs you: every decision an agent is waiting on, answerable from a phone

Release notes 2026-09-15 — the ask primitive and the Needs-you inbox (vocion-core#325, merged): approvals, rulings, merges and gates as one list with decision sheets, a recommended option, and an always-on Other.

Vocion Teamvocion-v2.69.0

Shipped: vocion-core#325, merged to main on 2026-09-15. Part of the 2026-09-15 release notes.

The outcome

An operator should be able to answer everything their agents are waiting on in one place, in a few minutes, from a phone. Before this change, that list did not exist as a thing. Approvals lived in the review queue, learning candidates on the learnings page, paused runs on their own pages, and anything that needed a ruling — an architecture question, a credential, a pull request a person has to merge — lived in a file or a chat message. Nothing counted it, and nothing was accountable for getting it answered.

What it is

Two additions to core.

The ask primitive. A row for anything that needs a person: kind is one of approval | input | ruling | credential | merge | recommendation | gate; title and a short body; options as { id, label, description?, recommended? } with at most one recommended; groupKey / groupTitle so several asks form one decision sheet; contextUrl and contextMd for the long form; a status that moves from open to approved | rejected | done | superseded; and the decision, note, actor and time once answered. The API is POST /api/v1/asks (an upsert on sourceRef, so re-filing the same question refreshes it instead of duplicating it), GET /api/v1/asks, GET /api/v1/asks/:id and POST /api/v1/asks/:id/decide. The full contract is in docs/entities/ask.md; the service is packages/core/src/services/AskService.ts.

The Needs-you inbox. /dashboard/inbox aggregates open asks with the rest of what waits on a human — pending review-queue proposals, paused or waiting mission, workflow and worker runs, pending learning candidates, worker runs that failed in the last day (packages/core/src/services/InboxService.ts). The header answers three things in one line each: What needs me, What changed, What happens next. Rows carry title, kind, who asked, age and risk, and nothing else.

How a decision feels

Each ask opens as one question on one screen. Options are tall rows with a consequence line under the label; the recommended option is pre-selected and marked; Other is always present and takes free text. Several asks with the same groupKey open as a stepper — one question, Next, a receipt of question → answer pairs with an Edit per row, then Submit all. Every decision with a note where the answer was reject or other is queued for the feedback classifier (packages/core/src/services/feedback/askFeedbackQueue.ts), so a correction becomes a learning candidate rather than a comment nobody re-reads.

The reference interaction was Claude Code's remote-control question flow on mobile. The design notes in the PR map each choice to a principle in the Product Design Manifesto: make the important things obvious, one obvious action, every interaction teaches the system something, hide complexity without hiding truth.

For workspaces already running

Additive. One table, one nav item with a live count, one adoption event (ask.decided). Nothing existing changes behaviour. An external process files asks with a tenant token:

curl -X POST "$VOCION_URL/api/v1/asks" \
  -H "Authorization: Bearer $VOCION_TOKEN" -H 'content-type: application/json' \
  -d '{"kind":"ruling","title":"Slack app: one per workspace or one per agent?",
       "sourceRef":"ops:slack-granularity","risk":"medium",
       "options":[{"id":"per-workspace","label":"One app per workspace","recommended":true},
                  {"id":"per-agent","label":"One app per agent"}]}'

and reads decisions back with:

curl "$VOCION_URL/api/v1/asks?status=decided&source=ops:&limit=50" -H "Authorization: Bearer $VOCION_TOKEN"
# → { items: [{ id, kind, title, status, decision, decisionNote, decidedBy, decidedAt, followUp, ... }], total, limit, offset }

status accepts open (default), decided, all or an exact status; source is a sourceRef prefix.

The screenshot above is a local workspace on fictional data.

Docs: docs/entities/ask.md.

Where this lives in the repo