Repository navigation
feat(prime): impact of human-message priority (#2334) and bash continuation holds (#2465) on Pylon occurrence model #727
Description
Activity
Current-source/status correction for this impact issue:
- Upstream human-priority PR #2334 merged 2026-09-14 and is an ancestor of the v0.9.5 release (published 2026-09-16). It is already a stock v0.9.5 behavior, not a future hypothetical.
- Upstream bash-hold PR #2465 merged 2026-09-21, after v0.9.5; it needs a separately proved Pylon managed/stock artifact before assigning it to any running session.
- Pylon's current
PrimeAgentDaemonSessionRuntimerecords native queue count and consumes native event cursors; itsremoveOnlyInputQueueItempath only mutates a queue lane when it contains exactly one entry, usingexpectedTexton an isolated mutation connection. This source does not by itself prove that priority insertion breaks Pylon event occurrence order or that an abort must cancel all background shell work.
The next acceptance step is an isolated stock/managed-version trace with mixed user/agent/cron queued messages and a running background bash handle: record native event cursor order, queue snapshots, prompt-admission receipts, turn settlement, and abort latency. Keep this as a proof task until a concrete mismatch is shown; do not relax occurrence or recovery fences based solely on the scheduling change.
Characterization Trace Results & Adversarial Invariant Analysis
Completed the isolated stock v0.9.5 characterization trace and independent adversarial invariant analysis per the acceptance criteria above.
1. Empirical Characterization Trace (Stock v0.9.5 Daemon)
- Harness Setup: Tested against
/Users/rynfar/.local/bin/prime-agent(v0.9.5, schema revision 28, protocol 7) over an isolated domain socket with a deterministic local streaming OpenAI completion mock provider. - Queue Snapshots Under Mixed Traffic:
- Turn 1 was dispatched and held in the mock backend stream.
- While busy, a background agent message (
source: "internal",agentMessageId: "agent-sub-1") and a scheduled cron prompt (source: "internal") were enqueued infollowUp. - An interactive human user prompt (
source: "interactive") was then submitted. - Snapshot confirmed PR #2334 priority insertion: the human message jumped ahead to index
0of thefollowUplane:{ "steering": [], "followUp": [ "MESSAGE_FROM_HUMAN_USER", "MESSAGE_FROM_AGENT", "MESSAGE_FROM_CRON" ] }
- Turn Settlement & Dispatch Order:
- Upon Turn 1 stream completion, the daemon dispatched Turn 2 (
MESSAGE_FROM_HUMAN_USER), followed by Turn 3 (MESSAGE_FROM_AGENT), and Turn 4 (MESSAGE_FROM_CRON). Execution strictly mirrored priority queue ordering.
- Upon Turn 1 stream completion, the daemon dispatched Turn 2 (
- Native Event Cursor Monotonicity:
- All 62 events captured progressed strictly monotonically (
seq = 1, 2, 3, ..., 61) with zero sequence inversions or gaps. Monotonicity holds because cursors (meta.cursor: { generation, sequence }) are assigned at execution dispatch time, not queue admission time.
- All 62 events captured progressed strictly monotonically (
- Abort Latency:
abort_and_clear_queueacknowledged in 2 ms, atomically emptying bothsteeringandfollowUp.
2. Concrete Architectural Mismatches in Pylon
While cursor sequence numbers are monotonic in isolation, an adversarial review against Pylon's dual-state runtime (
PrimeAgentDaemonSessionRuntime.ts) and adapter (PrimeAgentDaemonAdapter.ts) uncovered concrete invariant violations if PR #2334 or PR #2465 are adopted into Pylon's managed fork without adapter changes:-
Transcript Resync Failure on Reconnect (
snapshotRecoversSubmittedUser):PrimeAgentDaemonAdapter.ts:2799-2830computessubmittedUserIndex = activeTurn.nativeTranscriptBaselineMessageCountand assertsmatchesSubmittedUserMessage(activeTurn, missingMessages[submittedUserIndex]).- If Pylon disconnects while a background task turn is queued, and during the disconnect window a human message jumps to index 0 and completes,
missingMessages[submittedUserIndex]is the human message, whereasactiveTurn.submittedUserMessagewas the background task. matchesSubmittedUserMessagefails, settingreconnectRecoveryFailed = trueand force-terminating the entire session viastopSessionInternal.
-
Native Event Attribution Blackout (
activeTurnForNativeEvent):PrimeAgentDaemonAdapter.ts:2600-2615only attributes events tocontext.activeTurnifattribution.correlationId === activeTurn.correlationId.- Pylon maintains a single active turn pointer. When a preempting human turn executes, its events carry
correlationId = "corr-human". BecauseactiveTurn.correlationIdpoints to the background turn,activeTurnForNativeEventreturnsundefined. - Impact: All streaming tokens (
MessageStarted,MessageDelta,RunCompleted) for the user turn are silently dropped, and the UI appears completely frozen.
-
Queue Mutation TOCTOU Race (
removeOnlyInputQueueItem):PrimeAgentDaemonSessionRuntime.ts:8096-8200validatesentries.length === 1and issuesmutate_queued_message(lane, index: 0, expectedText).- If a human prompt jumps into index 0 while the mutation RPC is in flight, the daemon rejects the mutation due to text mismatch (
expectedText !== item.text). The targeted background item is shifted to index 1 and remains undeleted.
-
Admission Guard Contradiction (
sendTurn):PrimeAgentDaemonAdapter.ts:6075-6095checksnativeInputQueuedCount > 0and rejects subsequent turn submissions with HTTP 400 Validation Error (reason: "busy"). Human preemption in the daemon is currently blocked at the Pylon adapter boundary.
-
IPython Background Process Leaks on Abort:
- The 2ms latency of
abort_and_clear_queueis a synchronous fire-and-forget signal (requestAbort()). requestAbort()only signals_bashAbortControllers; it never signalsReplKernelManagerbackground handles. Background processes running inside the IPython kernel continue executing after the abort, leaking file locks, ports, and child processes.
- The 2ms latency of
3. Conclusion & Disposition
- Maintainer directive confirmed: Do NOT relax occurrence or recovery fences.
- Do NOT adopt upstream PR #2334 or PR #2465 into Pylon's fork (
pylon-code/prime-agent) until Pylon's adapter is re-architected to support:- Multi-correlation concurrent turn event dispatching (retiring the single
activeTurnpointer constraint). - Non-FIFO fingerprint-based transcript reconciliation on reconnect.
- Correlation-ID-targeted queue mutations rather than array index targeting.
- Synchronous process reaping in daemon abort handlers.
- Multi-correlation concurrent turn event dispatching (retiring the single
- Harness Setup: Tested against
Background & Upstream Changes
Upstream Prime Agent introduced two queue / scheduling semantics changes:
Architectural Analysis for Pylon
1. Occurrence Model & Queue Ordering Guarantees
PrimeAgentDaemonAdapterandPrimeAgentDaemonSessionRuntimerely on strict monotonic ordering of runtime occurrences, prompt admission barriers, and per-event recovery cursors.queue_message_mutationcapability handler must ensure the client UI timeline updates gracefully rather than assuming strict FIFO across heterogeneous message classes.2. Continuation Holds While Bash Runs
abort,abort_and_send_queued) remain instantly responsive even while a background command is running.Action Items
PrimeAgentDaemonAdapterqueue management when the daemon prioritizes user prompts over agent messages.abortandabort_and_send_queuedcleanly cancel background shell tasks and release held continuations.