Skip to content

feat: question escalation — a subsession's question should be answerable by its parent session, passing up the stack if unanswered #1884

Open

Description

@dezren39

Request (Drew, 2026-11-06)

When a subsession calls the question tool, the parent session — the AI orchestrating it — should be able to answer it. If the parent can't or doesn't answer, the question passes up the stack: grandparent, …, up to the root session / attached client. The parent AI is the natural answerer in detached trees; today the form waits only for an external UI/API actor while the whole foreground chain stalls silently (see the very-high-priority stall bug filed alongside this, and #1881 Q6).

Workshop evidence

Evidence: the 2026-11-06 subsession workshop test, filed as #1881 (production server, 8 test sessions, plan pools only; every behavior claim production-measured and re-verified against the session store + route_attempt).

  • The form lives on the child (GET /api/session/<child>/form → frm_…, fields keyed q0…); an external POST …/form/<id>/reply with {"answer": {"q0": "Blue"}} returned 204 and unblocked the entire tree instantly. The reply path works — it is just not connected to the session tree.

Design questions to explore

  • Order: parent first, then up the ancestry to root, then the attached client/UI? Or client first when one is attached?
  • Timeouts per level: how long does each level get before escalation? What happens when the root also times out — handleable cancellation for the child (never a silent stall, never a re-ask loop).
  • Payload: reuse the existing form answer shape (answer keyed by field key) end-to-end so escalation and the external form API are the same mechanism, not two.
  • Delivery into the parent: synthetic turn (like background-completion delivery, which the workshop proved works unprompted) vs a tool result on the blocked subagent call vs both.
  • Who may answer: only the direct parent, or any ancestor? What if the parent is itself blocked foreground-waiting on this child (the normal case) — the escalation must still reach it, since answering is what unblocks it.
  • Interaction with a future API launch mode that disables question entirely (filed separately): disabled mode should short-circuit before any escalation.

Acceptance sketch

  • Child asks → parent receives the question in-session and answers → child's question call completes with the parent's answer; no external actor involved.
  • Parent declines/ignores past its timeout → question surfaces to the grandparent; at root timeout the child gets a visible cancellation it can handle.
  • The external form API path keeps working unchanged for attached clients.

Acceptance criteria

  • When a subsession calls question, its parent session can answer it; unanswered questions pass up the ancestor chain to the root session / attached client.
  • A foreground chain no longer stalls silently while a form waits only on an external UI/API actor — the waiting state is visible to the parent.
  • Timeout/fallback behavior (nobody answers) is defined and does not re-ask in a loop.

Activity

  1. added
    kind/featureNew feature or capability request
    priority/highImportant and time-sensitive
    effort/lLarge: multi-day or open-ended; expect staged check-ins
    source/humanFiled directly by a human
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Nov 6, 2026
  2. dezren39 commented on Nov 6, 2026

    @dezren39
    Author

    Intake review

    Requested by Drew 2026-11-06 (per the issue body). Part of the workshop cluster from opencode issue #1881 (Q6 evidence: form lives on the child, GET /api/session/<child>/form). Related: issue #1883 (stall bug), issue #1885 (disable-in-detached-mode alternative — the two are complementary: escalation for interactive trees, disable for detached). Effort l: touches form routing across the session tree. Suggested approach: deliver the form as a synthetic turn to the parent first, with pass-up on decline/timeout.

    — fleet monitor intake (Duty 2), 2026-11-06 run. Acceptance criteria appended to the issue body; labels normalized.

  3. dezren39 commented on Nov 7, 2026

    @dezren39
    Author

    Feeder triage — gap confirmed on current main

    Agent: issue sweep (issue-sweep-rotating, Make feeder)
    Checked: 2026-11-07T01:35Z, fresh gh calls verified twice. Repo main 2d11e0f649436d6c4d20a64ce13fd7e0501bdd96 (verified x3); this issue OPEN with no queue/*, work/*, user/* or safety labels — its only prior comment is the fleet-monitor intake note (2026-11-06T20:27Z). No live queue task indicated; queue backend is in the PostgREST outage (developing-today/code#6619), so dedupe was on gh labels/comments.

    What I checked (reads only, gh api raw — no builds/tests):

    • packages/core/src/tool/plugin/question.ts:74-88 — the question tool calls forms.ask with sessionID: context.sessionID only (the calling child session).
    • packages/core/src/form.ts — grep for parent returns no matches on current main: Form.create stores only the child's sessionID; Form.ask returns Deferred.await(entry.deferred) with no timeout race; the pending-state TTL is Duration.infinity. Nothing delivers, surfaces, or escalates a pending form to any ancestor.
    • Workshop evidence on this issue / Workshop test: subsession machinery from a workhorse session — results and system-prompt suggestions #1881 Q6 stands uncontradicted: an external POST …/form/<id>/reply returned 204 and unblocked the whole tree instantly — the reply path works; it is just not connected to the session tree.

    Done looks like: a subsession question is delivered to its parent in answerable form (existing answer shape, keyed by field key); unanswered questions pass up the ancestry to root/client with per-level timeouts; a root timeout resolves the child call with a visible, handleable result — never a silent stall, never a re-ask loop. Regression tests name their oracle (session-store state + form endpoints before/after).

    Scope: #1883 is the stall-bug minimum (already fed); #1885 is the detached-mode disable (picked up by the fleet feature wave, 2026-11-07T01:13Z) — this packet is the escalation feature only.

  4. dezren39 commented on Nov 7, 2026

    @dezren39
    Author

    🤖 Agent note · triage packet prepared, enqueue outboxed

    • Agent: issue sweep (issue-sweep-rotating, Make feeder)
    • Found via: feeder rotation (prev rotating repo dezren39/darwin-nix → developing-today-forks/opencode)
    • Task: Enqueue a repo-task/v1 triage packet (kind triage, priority 70, dedupe repo-health:v1:triage:developing-today/opencode:issue:1884) into queue repo-health-opencode-pilot. Packet: hidden_files/packet-opencode-1884.json.
    • Status: Queue backend is in the PostgREST outage (infra: repo-queue PostgREST timeout: global failures lane-visible again — recurrence after #6450 closed (2026-11-06 21:15-21:31Z) developing-today/code#6619; health timed out 45s this run), so the enqueue is owed via action-outbox OB-2026-11-06-026 — the outbox processor enqueues it idempotently on this dedupe key. The queue/queued label is applied with this note.
    • Expectation: A queue worker claims the resulting triage task and triages this issue per the packet's acceptance criteria.
  5. added
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 7, 2026
  6. dezren39 commented on Nov 7, 2026

    @dezren39
    Author

    Picked up by repo-worker-opencode-a — working this now. (Fleet queue fallback mode: the queue backend is down, so this issue's comments carry the claim. The claim stays live while repo-worker-opencode-a posts progress markers; after 30 minutes of silence any other worker may pick this up.)

  7. added
    queue/claimedA queue worker has claimed the task for this item
    work/assignedAn agent holds this item via the queue (claimed task)
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 7, 2026
  8. 8 remaining items

  9. dezren39 commented on Nov 7, 2026

    @dezren39
    Author

    🤖 Agent note · queued

    • Agent: action-outbox-processor job
    • Session / ID: cron action-outbox-processor run 2026-11-07 06:10 UTC (OB-2026-11-06-026)
    • Found via: queue enqueue owed from the issue-sweep-rotating run 2026-11-06 19:32 CST, executed this run
    • Task: Queue task 11017 (repo-health-opencode-pilot, triage, dedupe_key repo-health:v1:triage:developing-today/opencode:issue:1884) is queued for this issue. The recorded packet's enqueue returned a dedupe hit this run — task 11017 already existed on the queue (created 2026-11-07T05:11:01Z by a concurrent lane) — and was verified queued by fresh queue list readbacks. Opencode queue signal refreshed to generation 1610.
  10. dezren39 commented on Nov 8, 2026

    @dezren39
    Author

    🤖 Agent note · picked up

  11. dezren39 commented on Nov 8, 2026

    @dezren39
    Author

    🤖 Agent note · done

  12. developing-today commented on Nov 9, 2026

    @developing-today

    🤖 Agent note · design verified, parked for a dedicated implementation session — queue task 14135

  13. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 9, 2026
  14. dezren39 commented on Nov 10, 2026

    @dezren39
    Author

    🤖 Agent note · implemented, parked on PR merge — queue task 14135

  15. added
    work/assignedAn agent holds this item via the queue (claimed task)
    task/pr-shepherdQueue packet kind: shepherd an open PR or PR set to merge
    effort/sSmall: expected under 2 hours of work
    and removed
    effort/lLarge: multi-day or open-ended; expect staged check-ins
    on Nov 10, 2026
  16. dezren39 commented on Nov 10, 2026

    @dezren39
    Author

    🤖 Agent note · triaged

  17. dezren39 commented on Nov 10, 2026

    @dezren39
    Author

    🤖 Agent note · parked (PR ready to merge)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/sSmall: expected under 2 hours of workkind/designA design proposal (design-architect): multi-step, phased, decision-bearingkind/featureNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/highImportant and time-sensitivequeue/parkedQueue task is parked (waiting on CI, time, or an event)source/humanFiled directly by a humanstatus/parkedDeliberately paused with a recorded resume conditiontask/pr-shepherdQueue packet kind: shepherd an open PR or PR set to mergework/assignedAn agent holds this item via the queue (claimed task)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions