fix(review): reconcile sandbox and approval contracts

This commit is contained in:
Tianyi Cui
2026-07-11 21:37:38 +08:00
parent 6a13dcb364
commit b29a8eca71
61 changed files with 620 additions and 358 deletions
+3 -1
View File
@@ -173,7 +173,9 @@ Waterfall asking the composed answerers to decide one approval request. Dispatch
'approval/request'(this: ApprovalService, req: ApprovalRequest, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>
```
Source: [`packages/approval/approval/src/index.ts:64`](../../packages/approval/approval/src/index.ts)
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md)
Source: [`packages/ui/user-approval/src/index.ts:64`](../../packages/ui/user-approval/src/index.ts)
## `fs/*`
+6 -2
View File
@@ -44,13 +44,15 @@ Source: [`packages/core/agent/src/index.ts:117`](../../packages/core/agent/src/i
The `ctx.approval` service: dispatches ApprovalRequests to the `approval/request` waterfall and audits every ask/outcome pair to the requesting agent's session log. Stateless between requests — grants are returned to the caller, never stored here.
Owns the policy tier too (`effective = fold(the session's 'approval/policy' events) ?? config.policy`): a PREPENDED decide-or-delegate gate resolves `'never'` sessions to `'rejected'` before any interactive answerer is prompted, a per-agent prompt section states a `'never'` policy (and only that one — an `'ask'` promise could overclaim an answerer that headless compositions do not have), and an `agent/pre-step` narrator injects at most one coalesced notice when a session's effective policy moved past what the model was last told.
Owns the policy tier too (`effective = fold(the session's 'approval/policy' events) ?? config.policy`): `request()` resolves `'never'` to `'rejected'` before dispatching any interactive answerer, a per-agent prompt section states a `'never'` policy (and only that one in prose — an `'ask'` promise could overclaim an answerer that headless compositions do not have), and an `agent/pre-step` narrator injects at most one coalesced notice when a session's effective policy moved past what the model was last told.
```ts cordis-catalog
async request(req: ApprovalRequest): Promise<ApprovalOutcome>
```
Source: [`packages/approval/approval/src/index.ts:269`](../../packages/approval/approval/src/index.ts)
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md)
Source: [`packages/ui/user-approval/src/index.ts:282`](../../packages/ui/user-approval/src/index.ts)
## `ctx.bash` — `BashExecutor` (abstract seam)
@@ -173,6 +175,8 @@ Semantics every implementation must honor:
abstract confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv
```
Types: [ConfinedArgv](../core-data-structures/sandbox.md) · [SandboxPolicy](../core-data-structures/sandbox.md)
Source: [`packages/sandbox/sandbox/src/index.ts:180`](../../packages/sandbox/sandbox/src/index.ts)
## `ctx.sessionPersistence` — `SessionPersistence` (abstract seam)