fix(sessions): exclude workflow stage sessions from resume history - #1510
Conversation
Mark workflow-stage sessions as internal and filter them from standard resume/list/continue paths by default, while preserving includeInternal opt-ins for workflow resume and direct session access. Refs: #1504 Assistant-model: OpenAI ChatGPT
…essions - readSessionHeader no longer calls decoder.end() after a newline is found, preventing extra bytes from data after the header line from corrupting the parsed header (affects >1MiB headers spanning multiple read chunks). - listSessionsFromDir and listAllSessions now prefilter internal sessions via readSessionHeader before the expensive buildSessionInfo transcript parse, preserving includeInternal opt-in behavior. - Added regression tests for >1MiB header newline handling, single-line files, and malformed-body internal sessions. Refs: #1504
readSessionHeader now reads in 64KB chunks via a dedicated HEADER_READ_BUFFER_SIZE instead of the 1MiB transcript buffer. This keeps the early internal-session prefilter cheap while still reading the full first line across chunks. Decoder.end() remains guarded to only flush on EOF without a newline. Refs: #1504
Implementation NotesTask: Implement GitHub issue #1504 in bastani-inc/atomic: #1504 ("Exclude workflow sessions from standard resume history"). Start by reading the full issue body with
Repo rules: use Bun commands only ( Running Notes
Decisions / tradeoffs
Tradeoffs made explicit
Validation
Files changed
Commit
QA E2E VideoNo QA E2E video applies. This change is a backend session-history filtering behavior (TUI/CLI resume history) with no user-visible web/UI scenario that playwright-cli can drive in this checkout; correctness is covered by the unit + SDK regression tests above. Follow-up: reviewer robustness fixes (commit 9205d7449)Applied two reviewer findings from the latest research:
Test discovery note: the malformed-body test revealed that Validation (follow-up):
Docs/changelog: No changes needed for these internal robustness fixes; they do not introduce new user-visible behavior beyond what was already documented. Follow-up: origin/main integration and small header buffer (commits 61066df, f0521b5, 95549fc)Resolved the latest research findings (P2 and P3):
Validation:
Final branch state: |
|
Review: exclude workflow sessions from resume history (#1510) Solid, well-scoped change. Internal-session marking is threaded cleanly through the header type, list/continue paths, and the SDK; the opt-out semantics are correct (default-exclude, Code quality & correctness
Performance
Security
Test coverage Excellent breadth: marking, marker preservation/backfill,
Note The new Nice work overall — the fix is targeted and the regression coverage is thorough. Reviewed by Claude (Opus 4.8) |
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
…1510) * fix: exclude workflow sessions from resume history Mark workflow-stage sessions as internal and filter them from standard resume/list/continue paths by default, while preserving includeInternal opt-ins for workflow resume and direct session access. Refs: #1504 Assistant-model: OpenAI ChatGPT * fix: prevent header decoder flush corruption and prefilter internal sessions - readSessionHeader no longer calls decoder.end() after a newline is found, preventing extra bytes from data after the header line from corrupting the parsed header (affects >1MiB headers spanning multiple read chunks). - listSessionsFromDir and listAllSessions now prefilter internal sessions via readSessionHeader before the expensive buildSessionInfo transcript parse, preserving includeInternal opt-in behavior. - Added regression tests for >1MiB header newline handling, single-line files, and malformed-body internal sessions. Refs: #1504 * perf: use small dedicated header buffer for readSessionHeader readSessionHeader now reads in 64KB chunks via a dedicated HEADER_READ_BUFFER_SIZE instead of the 1MiB transcript buffer. This keeps the early internal-session prefilter cheap while still reading the full first line across chunks. Decoder.end() remains guarded to only flush on EOF without a newline. Refs: #1504
Summary
Workflow stage sessions are now marked as internal in their
SessionHeaderand excluded from the standard/resume,atomic -r, and--continuehistory by default — keeping the resume picker focused on interactive sessions while workflow stages remain fully accessible through workflow-specific commands and direct file access.Key Changes
SessionWorkflowMetadatatype (session-manager-types.ts) — capturesrunId/stageId/stageNamelinkage on internal session headersSessionHeader/SessionInfoextension — new optionalinternal: trueandworkflowfields propagate through the full session lifecyclemarkSessionInternal(workflow?)method onSessionManager— stamps a session as internal post-creation; idempotent (preserves existing full marker on reattach)sdk.ts) —createAgentSessionstamps the internal marker automatically whenorchestrationContext.kind === "workflow-stage"session-manager-list.ts) — listing reads only the lightweight header before skipping internal sessions, avoiding the expensive full 1 MiB transcript parse for hidden sessionsreadSessionHeader(session-manager-storage.ts) — replaces the old fixed 512-byte window with a proper chunked line-reader using a dedicated 64 KB buffer; correctly handles headers larger than one chunk (e.g. workflow sessions carrying long stage metadata) and avoids decoder flush corruption when a newline is found mid-bufferincludeInternalopt-in —SessionManager.list,listAll, andcontinueRecentaccept{ includeInternal: true }for workflow-specific resume paths and diagnosticsdocs/session-format.md,docs/sessions.md,docs/workflows.mdand both package changelogstest/session-manager/internal-sessions.test.ts,sdk-session-manager.test.ts) — covers filtering, workflow metadata visibility, robust multi-chunk header reads, decoder-flush correctness, prefilter skipping of malformed internal sessions, and SDK-level markingMigration Notes
Legacy workflow sessions created before this change lack the
internalmarker and will continue to appear in the standard history until they age out or are deleted. No action required.Validation
Fixes #1504