OpenProgram / Web / Conversation input
Queue and active-turn steering
Reference and compatibility
Codex prompting separates queued follow-ups from active-turn input. Codex App Server binds steering to the expected active turn and does not accept runtime-setting overrides. OpenProgram uses its existing execution command service and safe points instead of adding a second session inbox or provider-specific steering transport.
Delivery
The queue retains an entry until a matching applied receipt confirms that its user message is persisted. Accepted or applying commands are checked automatically with the same envelope. The command carries only the message, exact execution identity, version and an idempotency key. It does not change permissions, models, tools or the current running program. Unsupported or ended executions leave the entry queued; idle reconciliation drains normal follow-ups in FIFO order.
Before posting, the client retains the immutable command envelope. A lost acknowledgement leaves delivery unconfirmed: the row remains visible, normal drain cannot send it again, and automatic confirmation retries reuse the same envelope. Confirmation uses one timer per queued row, starting at 1.5 seconds and backing off to at most 30 seconds after transport failures. A definitive receipt clears retry state; uncertain delivery never becomes an ordinary duplicate send. A confirmed stale-version rejection permits one new envelope against a fresh snapshot of the same execution. Errors are visible; injected flags are always released after transport failure.
Ownership and UI
The active session and its running execution determine the target. Another session or related sub-Agent is never selected opportunistically. There is no standing queue-or-steer preference; the key chosen at send time decides. Queued messages show as one raised card docked above the input box. The heading counts the rows and how many are being added to this turn, and collapses the card. Each row is one line: a tag (This turn while its steer is in flight, Next turn while it waits, Not sent or Unconfirmed after a failure), the first line of text, and actions shown on hover or keyboard focus. The actions are a non-cancelling add-to-this-turn, retry, edit and removal when delivery is not uncertain. Clicking the text expands the full message and its attachments. Clear all removes every row in one write except rows being delivered or edited, so clearing never drains a row that was about to be removed. Attachments retain their existing draft behavior; steering accepts text within the canonical command size limit.
Normal follow-up admission resolves its predecessor from the durable session head before updating the server conversation mirror. It includes the preceding assistant reply, tool results and delivered steering inputs; explicit branch predecessors remain unchanged.
Cancelled and interrupted assistant turns retain their partial content and display their terminal status, including empty replies. A cancellation notice does not infer who initiated the cancellation.
Storage boundary
Ordinary queue entries remain in renderer memory. Pending text steering receipts and stopped or ended steering drafts use same-window session storage. Pending steering entries cannot be drained as ordinary messages until a definitive acknowledgement resolves the command. Canonical acceptance persists the command on the server; application persists the user message. When an execution finishes, undelivered steering commands are rejected and their rows can resume ordinary queuing. A completed tool batch is never skipped merely because a steering message arrives. This change does not replace ordinary chat transport with a new message broker.
Acceptance
- Queue two follow-ups: each starts only after the preceding turn ends.
- Add text while a tool runs: the same execution and tool continue; the instruction reaches the subsequent model context.
- Lost acknowledgement: retain the row and replay the same command without duplicate delivery.
- Ended, unavailable and unsupported targets retain the input and report their state.
- Scope switching cannot steer another conversation; Stop remains a separate explicit action.
Implementation status
The implementation uses canonical execution commands and non-cancelling queue controls. Agent command application confirms persisted user input in the active reply branch; safe-point admission alone remains applying. Owner expiry cannot authorize a late input write. Execution closure resolves undelivered commands even when the execution awaits effect reconciliation. Acceptance uses the default App and real request handling; static checks do not replace that runtime acceptance.
Automatic receipt confirmation and terminal assistant status notices are implemented. The expanded lifecycle audit passes independent specification and quality review and its complete verification manifest.
Function retry acknowledgement
Each retry carries a request identity echoed by its dispatch acknowledgement or rejection. The acceptance timer ends when dispatch is accepted, not when the function finishes. A rejection or disconnected send restores only the corresponding pending card and reports the actual cause once. Missing acknowledgements remain uncertain and are not automatically resubmitted. History and surface validation remain authoritative.
Steering lifecycle audit contract
Steering binds to the execution selected when the user requests it. A version retry can refresh that execution's version but cannot select a replacement execution. Stop retains an in-flight instruction as an unsent draft even when admission has not yet completed. An uncertain command remains immutable until the server provides a definitive receipt; Stop must not erase it or permit duplicate ordinary dispatch.
The renderer retains text-only steering commands and stopped or ended steering drafts in same-window session storage. Refresh restores them without replaying ordinary chat. After authoritative session hydration, unresolved commands are confirmed using their original identity. Ordinary unsent queues and attachments remain memory-only. Storage is best-effort when browser storage is unavailable; it is not a second server command log.
Acceptance covers Stop during snapshot retrieval and version retry; replacement executions; replay after accepted or lost acknowledgements and refresh; multiple accepted inputs; provider text, reasoning and silent waits; tools, pause and continuation; cancellation and cold history; unsupported targets, attachment and length limits, and cross-session authorization. The command service remains authoritative for receipt order and execution ownership. No provider-specific transport or new permission mechanism is introduced.
The lifecycle repair passes independent specification and quality review. The combined verification manifest reports 3,279 Python tests passed, two existing skips, 964 Web tests passed and eight browser tests passed. Static checks, TypeScript and documentation links pass. The local release ledger records the exact reviewed implementation and installed-App acceptance separately.
Audit coverage
| Boundary | Observable behavior | Regression evidence |
|---|---|---|
| Input preparation | Expanded paste, attachments, 4,096 Unicode code points | submit-reliability.test.mjs |
| Target ownership | Session identity; snapshot replacement; same-execution version retry | submit-reliability.test.mjs; execution_cursor_auth_audit |
| Duplicate and uncertain commands | Same-envelope retry; one confirmation timer; bounded transport backoff | submit-reliability.test.mjs |
| Stop before admission | Snapshot and version-rejection races retain the draft | submit-reliability.test.mjs |
| Refresh and storage | Accepted, lost ACK and stopped commands; exact replay; storage denial | test_queue_steer.py; submit-reliability.test.mjs |
| Streaming | Text, reasoning and silent provider wait interrupt; partial content survives | test_streaming_steer.py |
| Tools and pause | Whole tool batch completes; paused inputs enter continuation | test_safe_points.py; test_continue_step_steer.py |
| Durable commands | Accepted order, idempotency, checkpoint rollback, owner expiry | test_safe_points.py; test_continue_step_steer.py |
| History | Cancelled partial reply; explicit next-turn predecessor; no head rewind | test_streaming_steer.py; test_queue_steer.py |