Skip to content

Run every wrap into a macOS session inside that session - #83

Merged
ihavespoons merged 1 commit into
mainfrom
macos-wrap-session-reuse
Nov 2, 2026
Merged

ihavespoons merged 1 commit into
mainfrom
macos-wrap-session-reuse

Conversation

@ihavespoons

Copy link
Copy Markdown
Contributor

The problem

A second agentmon wrap --session <id> into a session ran its agent outside that session. No policy applied, but the agent still showed as wrapped (SECENG-312).

The daemon sent the extension only the session's first root PID. wrap-init waited for any snapshot of the session, so it returned at once when the extension already held one. That snapshot did not name the new wrap process.

The fix

  • SessionTracker keeps every PID registered with no parent as a root of the session, in sessionRoots.
  • The snapshot sends them as root_pids. NoteSnapshotDelivered records which roots each delivered snapshot named.
  • wrap-init waits with AwaitRootDelivered for a snapshot that names its own PID.
  • For a session that is already registered, wrap-init also posts the policy-update notification, so that the extension fetches the session again.
  • If that wait times out on a reused session, wrap-init does not end the session. Another agent runs in it, and ending the session would stop the enforcement of that agent.
  • SessionPolicyCache maps each root in root_pids to the session, on the first fetch and on each refetch. It drops its "outside" answers after a new root is mapped.

Verification

  • scripts/test-macos-wrap-session-reuse.sh starts three wraps into one session. The first wrap is still running when the second starts. On build 1676, the second and third wraps ran outside the session (2 of 4 failed). On build 1677, 4 of 4 pass.
  • On build 1677, scripts/test-macos-socket-signal-rules.sh prints 13 ok, and scripts/test-macos-network-proxy.sh passes 6 of 6.
  • New Go tests: TestAwaitRootDelivered, TestBuildPolicySnapshot_RootPIDs, TestPlatformWrapInit_ReusedSessionWaitsForItsOwnRoot and TestPlatformWrapInit_ReusedSessionTimeoutKeepsSession.
  • go test -tags nofuse ./... passes, and golangci-lint reports 0 issues.

Fixes SECENG-312.

🤖 Generated with Claude Code

A second `agentmon wrap --session` into a session ran its agent outside
the session, with no policy (SECENG-312). The daemon sent the extension
only the first root PID. wrap-init waited for any snapshot of the
session, so it returned at once when the extension already held one.

The tracker now keeps every root of a session, and the snapshot sends
them as root_pids. wrap-init waits for a snapshot that names its own
PID. For a session that is already registered, it also posts the
policy-update notification, so that the extension fetches the session
again. If that wait times out, the session stays, because another
agent runs in it.

The extension maps each root in root_pids to the session, and drops
its "outside" answers when a new root arrives.

scripts/test-macos-wrap-session-reuse.sh failed 2 of 4 on build 1676
and passes 4 of 4 on build 1677.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ihavespoons
ihavespoons merged commit a82ba14 into main Nov 2, 2026
8 checks passed
@ihavespoons
ihavespoons deleted the macos-wrap-session-reuse branch November 2, 2026 12:26
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.

1 participant