Skip to content

Decisions a Planner waits on no longer time out - #657

Merged
lavaman131 merged 1 commit into
mainfrom
decisions-never-expire
Oct 16, 2026
Merged

lavaman131 merged 1 commit into
mainfrom
decisions-never-expire

Conversation

@lavaman131

Copy link
Copy Markdown
Collaborator

A blocking question from a Planner now waits until a person answers it or it is withdrawn. It never expires after a fixed time.

This covers the in-process Atomic harness and a remote Planner's input-request over the agent connection. A question is withdrawn when its Planner stops, its run is cancelled, the document is archived or deleted, or the asker's link closes.

Timeouts found and what changed

Where Before Now
createHumanInput default (INPUT_EXPIRY_MS, 30 min), reached by harness/session.ts for the in-process and remote Planners The cards were marked expired and the Planner got no answer There is no timer. expiresInMs, Questions.expire, room.projectExpiry and INPUT_EXPIRY_MS are removed
PLANNER_IDLE_MS (30 min) for a Default-machine Planner (experiments/routes.ts) The Planner was stopped once nobody had the document open, which withdrew its open question The document counts as in use while its attached Planner waits on an open question or has a live or paused workflow run (AgentLink.waiting, PlannerAttachments.waiting). The 30 minutes start after the later of the last viewer leaving or the wait ending
The "room to expire" size reserve (fitsExpiry, EXPIRY_ROOM, checks in submit and append-option) Each open question reserved about 40 bytes, and refusals mentioned expiry Removed. Edits, questions, options and answers can fill the document to exactly 256 KiB, and refusals name only that limit
Question UI and Planner prompt "Nobody answered within 30 minutes…" and "Expiry is not an answer or approval" The expired-card note names no time limit. The prompt says a question waits until it is answered or withdrawn

These timeouts were checked and left alone because none of them times out a question:

  • The 10 s operation timeouts in the Copilot SDK, Atomic and remote adapters.
  • The link's ping and revalidation.
  • The 15-minute machine Planner attach credential.
  • Room eviction. A running turn holds the room.

The expired status stays readable for stored records and cards, and for the input-result schema from older servers.

apps/connector and packages/agent-link are unchanged.

Tests (red before the fix)

  • human-input.test.ts: a question asked through createHumanInput is still open after a simulated 31 minutes and 24 hours, then returns the answer. After 31 minutes, aborting it withdraws the cards. testing/decisions.ts laterTimers holds back timers of a minute or more so the test can let time pass.
  • session.test.ts: the Atomic and remote Planners registered by openPlannerSession keep a question open after 31 minutes.
  • link.test.ts: a question on the agent connection stays open after 31 minutes. Closing the link then withdraws its card.
  • planner-dispatch.test.ts: a Default-machine Planner with an open question, or with a live or paused run, is still dispatched with nobody viewing. It stops 30 minutes after the question is answered or the run ends.
  • human-input.test.ts and room.test.ts: Planner edits, a new question, an option, an answer and a person's edit fit at exactly 256 KiB, and one byte more is refused with no expiry wording.
  • question-view.test.ts and decisions.test.tsx: the expired card shows no time limit.

Verification

  • GIT_CONFIG_GLOBAL=/dev/null bun test apps/server packages apps/web: 5768 pass, 7 skip, 0 fail.
  • bun run types and bun run ci pass. The design-contract hash for question-view.tsx was renewed after a copy-only change.
  • bun run e2e on the Decisions, harness, planner-attachment and machine-choice files: 90 passed.

A blocking question from a Planner (the in-process Atomic harness, or a
remote Planner's input-request over the agent connection) now waits until a
person answers it or it is withdrawn: the Planner stops, its run is
cancelled, the document is archived or deleted, or the asker's link closes.
Previously createHumanInput defaulted to a 30-minute timer, after which the
cards were marked expired and the Planner got no answer.

- createHumanInput and Questions.ask no longer take an expiry; the expire
  path, projectExpiry and INPUT_EXPIRY_MS are gone. Stored records and cards
  with status "expired" still load and render.
- A Default-machine Planner is no longer idle-stopped while it waits on an
  open question or a live or paused workflow run. PLANNER_IDLE_MS counts
  from when the last of those ended or the last viewer left.
- The per-question "room to expire" size reserve is removed. Edits,
  questions, options and answers may fill the document to its exact 256 KiB
  limit, and refusals name that limit without mentioning expiry.
- The expired card note no longer names a time limit, and the Planner
  prompt and docs say a question waits until answered or withdrawn.

The connector and the agent-link protocol are unchanged; `expired` stays in
the input-result schema for older servers.

Assistant-model: Claude Opus 5.5 (fast)
Assistant-workflow: inline (fast subagents)
Assistant-verification: red before fix: human-input, session (atomic and remote), link and planner-dispatch tests failed with the question expired or the Planner idle-stopped after a simulated 31 minutes; exact-limit tests in human-input and room failed on the expiry reserve; question-view and decisions tests failed on the "30 minutes" note
Assistant-verification: GIT_CONFIG_GLOBAL=/dev/null bun test apps/server packages apps/web passed: 5768 pass, 7 skip, 0 fail
Assistant-verification: bun run types passed
Assistant-verification: bun run ci passed (design-contract hash renewed for question-view.tsx, copy-only change)
Assistant-verification: bun run e2e passed: 90 tests across decisions, harness, planner-attachment and machine-choice files
User-preference: Decisions a Planner waits on never time out
Co-authored-by: Alex Lavaee <alexlavaee@microsoft.com>
@lavaman131 lavaman131 self-assigned this Oct 16, 2026
@lavaman131
lavaman131 merged commit 5254cc0 into main Oct 16, 2026
24 checks passed
@lavaman131
lavaman131 deleted the decisions-never-expire branch October 16, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant