Skip to content

feat(harness): memfs-less worker agents and explicit per-session memory scopes#3285

Merged
sarahwooders merged 1 commit into
mainfrom
sarah/sdk-dream-worker-support
Jul 9, 2026
Merged

feat(harness): memfs-less worker agents and explicit per-session memory scopes#3285
sarahwooders merged 1 commit into
mainfrom
sarah/sdk-dream-worker-support

Conversation

@sarahwooders

@sarahwooders sarahwooders commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes around deliberately memfs-less agents, plus support for overriding a session's memory directory: the shell-env memory guard can now honor an explicitly-provided MEMORY_DIR instead of stripping it.

Memory-scope override (the main change)

The shell-env guard strips inherited MEMORY_DIR/LETTA_MEMORY_DIR for memfs-less agents unless the value is parent-scoped — any other value is treated as stale leakage. That made it impossible for a launcher to deliberately scope a session's memory to an isolated copy (e.g. a clone of a memory filesystem that a background worker should edit in place).

A launcher can now mark the scope as intentional with LETTA_MEMORY_DIR_EXPLICIT=1. The guard honors the marked value iff it lies outside the agents' memory store — a path outside the store cannot be another agent's memory, which is the threat the guard exists to prevent. Concretely:

  • explicit marker + path outside the store → honored ($MEMORY_DIR resolves in the session)
  • explicit marker + path inside another agent's store → still stripped
  • no marker → unchanged behavior (parent-scoped inherits, everything else stripped)

Bug fixes

  • Explicit memfs: false could not be persisted. upsertAgentSettings deleted falsy values, so "deliberately memfs-less" was unrepresentable in settings — indistinguishable from "never configured". Explicit false is now kept, readable via settingsManager.isMemfsExplicitlyDisabled().
  • The lazy memfs repair force-enabled memfs on deliberately memfs-less agents. The listener treats any untagged cloud agent as broken and repairs it (tag + settings + repo clone) at session start. Agents explicitly marked memfs-disabled are now exempt — they're workers, not broken agents.
  • create_agent had no memfs opt-out. Every agent created through runtime_start got the memfs tag/settings/clone unconditionally. create_agent.memfs?: boolean now allows memfs: false, which skips the setup and records the agent as explicitly memfs-disabled (wiring into the two fixes above).

Test plan

  • tsc --noEmit clean; layer/boundary/filename checks pass (pre-commit)
  • bun test src/tools/shell-env.test.ts src/settings-manager.test.ts src/websocket/app-server.test.ts — 107 pass / 0 fail, including new guard tests for all three override cases
  • Verified live: agent created with memfs: false persists the setting, gets no memory repo, and is not "repaired" at session start; a session launched with MEMORY_DIR=/tmp/probe-memory + the explicit marker resolves $MEMORY_DIR to that path inside the session

…ry scopes

Support for pipelines (e.g. the agent SDK's dreaming) that run many
concurrent sessions on shared worker agents, each scoped to an isolated
memory copy:

- runtime_start create_agent gains memfs?: boolean. memfs: false creates a
  worker-style agent with NO memory filesystem: the memfs tag stamp,
  settings enable, and repo clone are skipped, and the agent is recorded as
  explicitly memfs-disabled.
- Settings can now represent explicit memfs: false (previously stripped as
  a falsy value, making "deliberately memfs-less" unrepresentable), read
  via settingsManager.isMemfsExplicitlyDisabled().
- The listener's lazy memfs repair (which force-enables memfs for any
  untagged cloud agent) exempts explicitly memfs-disabled agents — they are
  workers, not broken agents.
- The shell-env memory guard honors an EXPLICIT inherited memory scope
  (LETTA_MEMORY_DIR_EXPLICIT=1) when it lies outside the agents' memory
  store: such a path cannot be another agent's memory, which is what the
  guard protects. A launcher can therefore point a worker session's
  $MEMORY_DIR at an isolated memory copy (e.g. a dream batch's memfs
  clone). Unmarked non-parent-scoped values are still stripped as stale
  leakage, and an explicit marker pointing INTO another agent's store is
  still rejected.
@sarahwooders
sarahwooders merged commit c9aadda into main Jul 9, 2026
22 checks passed
@sarahwooders
sarahwooders deleted the sarah/sdk-dream-worker-support branch July 9, 2026 20:35
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.

2 participants