Prevent oversized FIFO failures and preserve rejected drafts - #90
seanzqliang wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Copilot review overview
Review tier: Lite
Findings: 1
Open findings (2)
What changed in this PR
Introduces explicit message-size admission limits and permanent rejection handling across the SDK, durable orchestration (v1.0.79), and UI, with updated docs and tests to ensure oversized/terminal-session sends are preserved for recovery rather than retried.
Changes:
- Enforce a 12 KiB serialized UTF-8 inline prompt/answer envelope limit (
MESSAGE_TOO_LARGE, HTTP 413) in SDK send paths. - Add orchestration v1.0.79 FIFO validation + durable
session.message_rejectedreceipts and keep v1.0.78 frozen/registered for replay. - Update portal/TUI outbox UX to retain rejected drafts, display “Not sent” reasons, and prevent automatic retry; expand test coverage and documentation.
| File | Description |
|---|---|
| templates/builder-agents/skills/pilotswarm-sdk-builder/SKILL.md | Adds SDK builder guardrail guidance for inline message size limits and rejection handling. |
| templates/builder-agents/README.md | Documents the 12 KiB inline message limit and artifact-based large-input workflow. |
| packages/sdk/test/local/session-refresh-ui.test.js | Adds UI-controller tests for permanent outbox rejections and explicit recovery behavior. |
| packages/sdk/test/local/prompt-attachments.test.js | Adds tests for serialized UTF-8 payload measurement and pre-side-effect oversized rejection across client surfaces. |
| packages/sdk/test/local/outbox-bulk-reconcile.test.js | Ensures durable session.message_rejected reconciles correctly via live and bulk event paths. |
| packages/sdk/test/local/orchestration-version-upgrade.test.js | Verifies v1.0.78 handler remains frozen and v1.0.79 is registered as latest. |
| packages/sdk/test/local/cancel-pending-orchestration.test.js | Adds orchestration-level tests for FIFO-size rejection, state preservation, and queue capacity behavior. |
| packages/sdk/src/orchestration_1_0_78/utils.ts | Introduces frozen helpers for v1.0.78 (multi-writer attribution, context usage reduction, retry classification). |
| packages/sdk/src/orchestration_1_0_78/state.ts | Adds frozen orchestration state/types/constants for v1.0.78. |
| packages/sdk/src/orchestration_1_0_78/runtime.ts | Adds frozen runtime loop and startup gates for v1.0.78. |
| packages/sdk/src/orchestration_1_0_78/queue.ts | Adds frozen FIFO/drain/decide logic for v1.0.78. |
| packages/sdk/src/orchestration_1_0_78/lifecycle.ts | Adds frozen lifecycle utilities for v1.0.78 including CAN, status, regen pipeline. |
| packages/sdk/src/orchestration_1_0_78/index.ts | Adds frozen orchestration entrypoint for v1.0.78. |
| packages/sdk/src/orchestration_1_0_78/agents.ts | Adds frozen sub-agent tracking/actions and shutdown cascade for v1.0.78. |
| packages/sdk/src/orchestration/queue.ts | Adds FIFO item UTF-8 byte sizing, rejection receipts, and queue-capacity protection in v1.0.79. |
| packages/sdk/src/orchestration/index.ts | Bumps orchestration entrypoint to v1.0.79. |
| packages/sdk/src/orchestration.ts | Re-exports latest durable orchestration entrypoint name/version. |
| packages/sdk/src/orchestration-version.ts | Updates latest orchestration version constant to 1.0.79. |
| packages/sdk/src/orchestration-registry.ts | Registers frozen v1.0.78 and latest v1.0.79 handlers. |
| packages/sdk/src/message-size.ts | Adds shared 12 KiB serialized UTF-8 envelope measurement and MessageTooLargeError. |
| packages/sdk/src/management-client.ts | Enforces serialized-size admission before enqueue/update and reuses shared serializer. |
| packages/sdk/src/index.ts | Exports message-size constants/errors as part of the SDK public surface. |
| packages/sdk/src/client.ts | Enforces serialized-size admission for sends/events and reuses shared serializer. |
| packages/app/web/test/e2e/composer-resize.spec.mjs | Adds E2E coverage for rejected drafts retention/recovery across viewports. |
| packages/app/web/test/api-router.test.mjs | Ensures API-router surfaces actionable 413s and maps SDK errors into structured envelopes. |
| packages/app/ui/react/src/web-app.js | Adds portal composer affordances for recovering/resending/dismissing rejected drafts. |
| packages/app/ui/core/src/selectors.js | Adds rejected-reason rendering (“Not sent: …”) in outbox overlay lines. |
| packages/app/ui/core/src/history.js | Surfaces durable session.message_rejected in activity feed. |
| packages/app/ui/core/src/controller.js | Implements rejected outbox phase semantics, reconciliation, and local dismissal/recovery flows. |
| examples/horizon-harvester/README.md | Documents artifact-first workflow and inline message size restrictions. |
| examples/devops-command-center/README.md | Documents artifact-first workflow and inline message size restrictions. |
| docs/user-guide/keybindings.md | Documents rejected-draft behavior and recovery/dismiss UX. |
| docs/developer/building/builder-agents.md | Adds maintenance guidance for builder templates re: inline message limit behavior. |
| docs/architecture/orchestration/design.md | Documents FIFO byte-budget semantics and 1.0.79 rejection behavior. |
| docs/api/clients.md | Adds inline message limit specification and describes runtime FIFO rejection receipts. |
| docs/api/building-a-custom-ux.md | Documents recommended client UX for MESSAGE_TOO_LARGE / terminal rejections and durable receipts. |
| CHANGELOG.md | Summarizes unreleased message-admission + rejection-handling behavior across SDK/runtime/UI. |
| .github/skills/pilotswarm-tui/SKILL.md | Updates TUI/portal alignment guidance to include rejected outbox state and recovery semantics. |
| .github/copilot-instructions.md | Adds repo guidance around message admission and rejected-draft handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Address both frozen 1.0.78 formatting comments without execution changes. Reclaim FIFO head capacity for cancellation sweeps, validate before duplicate tracking, and guard outbox rollback against newer durable outcomes. Add seven focused regression cases and update maintenance docs.
Follow-up review: 3bc2b11Pushed to the existing sean/fix-oversized-message-fifo branch. The follow-up changes 8 already-included files (116 additions, 10 deletions); the PR remains at 40 files. The starting worktree was clean and the PR head was rechecked before committing. Existing PR content and newer branch edits were preserved. Findings and corrections
Replay, capacity, and performanceAll 8 frozen 1.0.78 modules were compared with the pre-PR live implementation. Executable output matches after the required 1.0.78 version-constant pin and checkout CRLF/LF normalization. Older frozen versions and shared activity serialization were not changed. The registry/upgrade suite passes; this is source and harness verification, not a claim of live durable replay coverage. Admission stays at 12 KiB of serialized UTF-8 per prompt/answer envelope; each FIFO bucket/item remains bounded at 14 KiB. No silent truncation or increased queue limits. Compaction scans at most 20 buckets, runs only under tail-capacity pressure, preserves item order, and adds no external I/O. Rejected sweep entries no longer consume pending-ID receipts. Remaining boundary: cancellation is still bounded and best effort. A truly saturated FIFO with no reclaimable whole bucket, or a tombstone beyond available sweep capacity, can still dispatch work before that tombstone is read. This fixes stranded free capacity; it does not introduce a priority control channel or promise cancellation of already-dispatched work. The architecture doc states this explicitly. Why all 40 files are justifiedPaths below use braces to enumerate files under a common directory. The frozen snapshot accounts for most added lines. Documentation files are not runtime dependencies, but are required maintenance parity for this user/builder-facing behavior.
Validation
Unverified integration gates: the full credentialed PostgreSQL/Copilot suite, including live replay/continue-as-new, durability, multi-worker handoff, and crash/chaos coverage. The standard .env is absent, and neither DATABASE_URL nor GITHUB_TOKEN is configured in the test environment. No credential files were created or modified. A configured maintainer environment still needs to run @affandar, please review the follow-up, the 40-file scope rationale, and the remaining saturation/integration caveats. No merge, main push, tag, publish, deploy, or Waldemort modification was performed. |


Summary
Fix two connected bugs: an oversized inline message can fail a durable session while writing its FIFO, and later rejected sends can remain forever pending in the portal/TUI.
Failure Evidence
A reported session's Duroxide history ended with:
The session then refused new messages as a terminal orchestration, while the UI continued showing those requests as pending. The earlier idle affinity release and completed model turn were not the failure cause. Deployment identity and prompt contents are intentionally omitted.
Root Causes
Solution
MAX_MESSAGE_BYTESandMessageTooLargeError; HTTP/RPC preserveMESSAGE_TOO_LARGEand status413with artifact-reference guidance.1.0.79. Validate individual FIFO items and combined buckets against their separate 14 KiB budget. Reserve buffer capacity while draining, leaving excess messages on the incoming durable queue. Preserve wait/child-digest state if runtime augmentation makes a prompt oversized.session.message_rejectedwith the error and contributing message IDs when work is refused inside the orchestration. Rejected prompts are not acknowledged as processed or inserted into the duplicate-suppression receipt set. The session can process a later valid request.Not sentreason. Reconcile rejection receipts through live and bulk history, and prevent a late enqueue acknowledgement from restoring queued state.Recover rejected prompt, explicit resend with fresh IDs, and local dismissal; keep native TUI prompt recall and shared rejection semantics aligned. Surface durable rejection reasons in Activity.Latest Follow-up (3bc2b11)
Compatibility And Safety
Validation
fifo.1overflow and permanent-send pending-state failures before applying the fixes.413without enqueue/state mutation, then a short request succeeds. Legacy RPC mapping is covered too.git diff --checkpassed. Frozen-handler content was compared against the base commit.Required Gate Still Blocked
The follow-up prerequisite check still found no .env, DATABASE_URL, or GITHUB_TOKEN in the test environment. GitHub currently reports no CI checks for this head; the passing results above are local validation.
The canonical full integration gate was attempted before this follow-up with
./scripts/run-tests.shand stopped before tests with:Credentialed PostgreSQL/Copilot integration, multi-worker, and chaos/replay execution therefore remain unverified in this environment. Run the full gate in an appropriately configured test environment before approving a release. The generator/HTTP/browser fixtures above are not a substitute for that gate. No credentials were read or created, and no test parallelism or retry policy was reduced.
Review Request
@affandar please review the inline admission policy, FIFO rejection/versioning behavior, and retained-draft UX. This submission is for review only: do not merge, tag, publish, or deploy as part of this request. The full credentialed gate must be completed and Affan's approval confirmed before a subsequent authorized release/rollout.