Skip to content

fix(security): keep no-session descendants ephemeral - #1251

Open
sethkarten wants to merge 5 commits into
mainfrom
sethkarten/security-autonomous-isolation
Open

fix(security): keep no-session descendants ephemeral#1251
sethkarten wants to merge 5 commits into
mainfrom
sethkarten/security-autonomous-isolation

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • keep child and grandchild runs in memory when their ancestor was started with --no-session
  • prevent daemon/runtime paths from silently creating persisted sessions beneath an ephemeral parent
  • document the actual autonomous-run trust boundary and practical OS/container isolation guidance

Fixes #1120.

Risk

Low to medium. The behavioral change is limited to descendants of explicitly ephemeral sessions. Normal persisted sessions continue to create persisted descendants.

Provenance

Extracted directly onto current main from #1159. Commits retain cherry picked from trailers for 4c7cdc4b6f6a7ee96e2307e0a42c3db3fe82a68f, 6446bafa5fe57421cc1660ce195fd302d9643a89, and d07e5a80db1ee704d67d029c838264699f6b4793. No MCP/provider changes are included.

Validation

  • npm run check
  • npm run test -- test/agent-session-recursion.test.ts — 97 passed
  • npm run test -- test/suite/agent-session-runtime.test.ts — 24 passed
  • npm run test -- test/daemon-mode.test.ts — 191 passed
  • focused Biome check on all changed TypeScript files
  • parsed docs.json
  • git diff --check origin/main...HEAD

Independent review found and fixed descendant depth initialization across inline, hosted-runtime, and daemon paths; the added assertions cover child/grandchild depth while confirming no session file is created.

Review focus

Please verify the ephemeral-session inheritance across inline, runtime, and daemon paths, and that the documentation accurately distinguishes application behavior from OS-level isolation.

Note

Keep RLM descendant sessions ephemeral when root is started with --no-session

  • Previously, child sessions spawned under a --no-session root could still create JSONL session files on disk; now all RLM descendants (inline, runtime, and daemon) use an in-memory SessionManager when the parent is non-persisted.
  • The fix is applied across three session-creation paths: agent-session-runtime.ts, agent-session.ts, and daemon-mode.ts.
  • rlmDepth and parentSession are now always set on child session headers, even when no parent session file exists.
  • Adds a new security.md guide covering trust boundaries, persisted state locations, container isolation recommendations, and an unattended-run checklist; cross-links it from --no-session help text and autonomous mode docs.

Macroscope summarized e6da654.


Note

Cursor Bugbot is generating a summary for commit e6da654. Configure here.

Comment thread packages/coding-agent/src/modes/daemon/daemon-mode.ts
Comment thread packages/coding-agent/docs/security.md Outdated
@Apocrathia

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6da654721

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2309 to +2311
const sessionManager = options.parentSession.sessionManager.isPersisted()
? SessionManager.create(childCwd, options.sessionDir)
: SessionManager.inMemory(childCwd, options.sessionDir);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve no-session ancestry across daemon update restarts

When a daemon update occurs while a --no-session root has queued or active work, createUpdateRestartSession() calls materializeSessionFile() at line 5652, which permanently changes the manager to persisted; after the manifest reopens that session, this predicate creates persisted descendants. The update therefore writes the root transcript and causes later children to create JSONL/artifact state despite the documented guarantee that a root started with --no-session keeps every descendant ephemeral. Track the original no-session policy independently of the manager's current persistence state and carry it through the restart manifest.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't key off isPersisted here. materializeSessionFile flips the root, so every child after the restart hits disk.

Comment on lines +2309 to +2311
const sessionManager = options.parentSession.sessionManager.isPersisted()
? SessionManager.create(childCwd, options.sessionDir)
: SessionManager.inMemory(childCwd, options.sessionDir);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Retain in-memory children after daemon tasks complete

For a daemon-hosted --no-session run, this branch gives every child an undefined sessionFile, but createSubagentRuntimeHost().completeRlmSubagentRuntime() returns false whenever that file is absent. After a successful child task, registerRlmChildSession() consequently treats registration as failed and releases the runtime, so the completed child disappears instead of remaining addressable for inspection, messaging, or subsequent nested work. Accept resident in-memory children without attempting to write the persisted registry.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in-memory children have no sessionFile, so this returns false and releaseRlmSubagentRuntime kills them as errors.

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.

Add security/sandboxing guidance for long-running autonomous runs

2 participants