feat: SPEC-6-5 cwd isolation (#20) — foreground cwd + userMemory opt-in - #68
Merged
Merged
Conversation
3rd input step (task → name → cwd) prefilled with the session cwd; Enter accepts, Escape accepts the default. Validates the chosen cwd (exists + dir) + surfaces cross-cwd via onNotify. Threads entryCwd to runLifecycle + cwd:o.cwd to the spawn adapter (lifecycle cwd precedence). No unit test — the panel interactive Run-action flow has no existing harness; gated by the release-gate smoke + manual QA (matches existing panel coverage: startLifecycleRun had zero unit tests pre-SPEC-6-5).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Foreground cwd isolation for the
subagenttool — the #20 confabulation fix. A dispatch can now target a working directory (cwd), and the child's working dir + context (AGENTS.md cascade, skill discovery, memory scopes) are scoped to it instead of always inheriting the session cwd. Also makes the global cross-project user-memory scope opt-in (userMemory: true, default off) — it was a cross-project memory bleed by construction.The end-to-end chain
src/tools/subagent.ts)cwd?param;resolveDispatchCwd(relative → resolve against session cwd; exists + is-dir validation, actionable error); cross-cwdonNotify; threaded to direct/retry/lifecycle-adapterspawnSubagentcalls;entryCwd: resolvedCwd→runLifecyclesrc/engine/spawnSubagent.ts)childCwd = opts.cwd ?? opts.parentCwdthreaded toRunRecord.cwd,factory.create,run:meta(+sessionCwd: parentCwdaudit on both)run-lifecycle.ts,registry.ts,lifecycle-types.ts)cwd?frontmatter field; precedencelifecycle.cwd ?? entryCwd;PhaseSpawnOpts.cwdthreaded to each phase spawnfleet-panel.ts)cwdinput step (prefilled session cwd; Enter accepts, Escape cancels); validation + cross-cwd notify +entryCwdthreadingwidget-rows.ts)↗<basename>glyph on cross-cwd fg runschild-loader.ts,port.ts,adapter.ts,claude-factory.ts)memoryScopesFor(cwd, { includeUser });user?optional; adapter null-guards; both backends passincludeUser: agent.userMemory ?? falsefrontmatter.ts)userMemory: boolean(default false)Breaking changes (migration notes in README)
userMemorydefault flip — the user pseudo-scope (/__armory-fleet-user__) is no longer hydrated by default. AdduserMemory: trueto opt back in. TS consumers constructingAgentDefliterals must includeuserMemory(required field).AgentDef.userMemoryrequired — compile-time break for external TS constructors ofAgentDef.Deferred (tracked)
cwdparam is honored by foreground dispatches only for now. TheWorktreeServiceis session-scoped (rootDir: ctx.cwd) and the bg path doesn't receivecwdyet. Rare intersection (cross-cwd × bg × worktree); documented in README.Verification
pnpm typecheckclean;pnpm test:run699/699 (677 → 699, +22).Closes #20 (foreground cwd isolation; bg/worktree follow-up → #62; SPEC-6-4 keeps event-bus RPC + live conversation viewer).