fix(pty-local): restore the session-resolved workspace policy
The linear replay resurrected the July spawn path: mode folded inline
and both confinement and the default cwd fenced to the deployment
workspaceRoot. Master (and the pre-rebase merge result) resolve the
policy once per spawn — resolve({ session }) — so session.header.cwd
is both the workspace-write boundary and the default shell cwd, as the
README already states. Restores the single resolve, threads the policy
through spawnArgv and the cwd fallback, re-expresses master's
session-root test on the terminal spec, and pins the recorded confine
policy in the explicit-cwd test.
Also from the same review round: the Python SDK exe build stages
pty.node from subprocess-local (node-pty's home since the relocation),
and fs-local's README counts the seam's eleven primitives.
This commit is contained in:
@@ -44,9 +44,9 @@ function config(): ResolvedConfig {
|
||||
}
|
||||
}
|
||||
|
||||
function agent(ctx: Context): Agent {
|
||||
function agent(ctx: Context, cwd?: string): Agent {
|
||||
const id = SessionId('agent')
|
||||
const session = Session.create(id, undefined, { version: 0, id, createdAt: 0 })
|
||||
const session = Session.create(id, undefined, { version: 0, id, createdAt: 0, ...cwd === undefined ? {} : { cwd } })
|
||||
return {
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
@@ -213,6 +213,42 @@ describe('LocalPtyBackend startup rollback', () => {
|
||||
})
|
||||
expect(spawned?.env?.PTY_TEST_SECRET).toBeUndefined()
|
||||
expect(initialized).toHaveBeenCalledWith(undefined)
|
||||
expect((ctx.sandbox as RecordingSandbox).calls).toEqual([{
|
||||
argv: ['/bin/bash', '-i'],
|
||||
policy: { mode: 'workspace-write', workspaceRoot: '/workspace' },
|
||||
}])
|
||||
})
|
||||
|
||||
it('resolves session mode and root together before wrapping the shell', async () => {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(RecordingSandbox)
|
||||
await ctx.plugin(SandboxPolicyService, { mode: 'read-only', workspaceRoot: '/deployment-fallback' })
|
||||
const terminal = terminalHandle()
|
||||
let spawned: SubprocessTerminalSpawnSpec | undefined
|
||||
const spawnTerminal = async (spec: SubprocessTerminalSpawnSpec): Promise<SubprocessTerminalHandle> => {
|
||||
spawned = spec
|
||||
return terminal
|
||||
}
|
||||
const initialized = vi.fn<() => Promise<void>>().mockResolvedValue(undefined)
|
||||
const session = { initialize: initialized } as unknown as LocalPtySession
|
||||
const backend = new LocalPtyBackend(
|
||||
ctx,
|
||||
{ ...config(), shellArgs: ['-i'] },
|
||||
spawnTerminal,
|
||||
() => session,
|
||||
)
|
||||
const owner = agent(ctx, '/session-workspace')
|
||||
setSandboxMode(owner.session, 'workspace-write')
|
||||
expect(await backend.spawn(spec(owner))).toBe(session)
|
||||
|
||||
expect(spawned).toMatchObject({
|
||||
argv: ['/sandbox', '--', '/bin/bash', '-i'],
|
||||
cwd: '/session-workspace',
|
||||
})
|
||||
expect((ctx.sandbox as RecordingSandbox).calls).toEqual([{
|
||||
argv: ['/bin/bash', '-i'],
|
||||
policy: { mode: 'workspace-write', workspaceRoot: '/session-workspace' },
|
||||
}])
|
||||
})
|
||||
|
||||
it('rejects a confined spawn without a sandbox provider', async () => {
|
||||
|
||||
Reference in New Issue
Block a user