Description
cloneContextWith drops the isFile probe when cloning a ToolPermissionContext. After any permission rule update (i.e. any "always allow"/"always deny" decision or managed rule change during a session), the resulting context has isFile === undefined, which silently changes downstream bash permission behavior for the rest of the session.
Source evidence
Audited against the 0.4.12 source preview (release/extraction.json sourceRevision 9b9885e42a3cf1a3df1cfa52a46e4fdb034cfcee); line numbers refer to that revision.
isFile is part of the context and set at creation: packages/agent-modules/permission/src/context.ts:157.
cloneContextWith copies mode, rules, sandbox flags, paths, dirs, agent/session fields — but not isFile: packages/agent-modules/permission/src/context.ts:210-232.
- Every
applyPermissionUpdate (addRules/replaceRules/removeRules, context.ts:190-204) produces the clone, so the field is lost on the first rule mutation.
- Consumer:
packages/agent-modules/permission/src/tools/bash-permission.ts:579 — if (!bashCtx.isFile?.(resolved)) return false;. Once isFile is undefined, this local-script relaxation check permanently returns false, so a single permission grant mid-session changes how later bash commands are classified.
Expected behavior
Cloning a context preserves all probe callbacks; permission behavior should not change as a side effect of granting or revoking a rule.
Suggested fix
Add isFile: ctx.isFile to the object returned by cloneContextWith (packages/agent-modules/permission/src/context.ts:214-231). Consider a type-level guard so future context fields cannot be silently dropped again (e.g. satisfies over a Pick of the mutable fields plus an exhaustiveness check).
Environment
Found by source audit; not runtime-reproduced yet.
Description
cloneContextWithdrops theisFileprobe when cloning aToolPermissionContext. After any permission rule update (i.e. any "always allow"/"always deny" decision or managed rule change during a session), the resulting context hasisFile === undefined, which silently changes downstream bash permission behavior for the rest of the session.Source evidence
Audited against the 0.4.12 source preview (
release/extraction.jsonsourceRevision9b9885e42a3cf1a3df1cfa52a46e4fdb034cfcee); line numbers refer to that revision.isFileis part of the context and set at creation:packages/agent-modules/permission/src/context.ts:157.cloneContextWithcopies mode, rules, sandbox flags, paths, dirs, agent/session fields — but notisFile:packages/agent-modules/permission/src/context.ts:210-232.applyPermissionUpdate(addRules/replaceRules/removeRules,context.ts:190-204) produces the clone, so the field is lost on the first rule mutation.packages/agent-modules/permission/src/tools/bash-permission.ts:579—if (!bashCtx.isFile?.(resolved)) return false;. OnceisFileis undefined, this local-script relaxation check permanently returns false, so a single permission grant mid-session changes how later bash commands are classified.Expected behavior
Cloning a context preserves all probe callbacks; permission behavior should not change as a side effect of granting or revoking a rule.
Suggested fix
Add
isFile: ctx.isFileto the object returned bycloneContextWith(packages/agent-modules/permission/src/context.ts:214-231). Consider a type-level guard so future context fields cannot be silently dropped again (e.g.satisfiesover aPickof the mutable fields plus an exhaustiveness check).Environment
Found by source audit; not runtime-reproduced yet.