policy: resolve every knob consumer through the shared override chain

Review fixes (ds-review-bot warnings on #623):

- One chain, every consumer: the override resolution (own post-seed
  switches ?? header baseline, closed-vocabulary validated) moves into pure
  exports (sandboxOverrideOf / approvalOverrideOf); the services delegate,
  and the permission presets consume them — current(session) and set()
  now see inherited baselines, so a child inheriting danger-full-access
  gets REAL knob switches when workspace-write is selected instead of a
  silent no-op, and a seed-carried preset selection is subsumed by the
  baseline. current(events) becomes current(session) (pre-release; the
  only callers were tests).
- Unconditional durable validation: a malformed header baseline fails
  loud on every read, no longer shadowed by an own switch.
- The two policy peers are declared optional (peerDependenciesMeta), so a
  thin spawn/fork deployment without policy plugins can consume the
  driver; verify-runtime-closure honors the flag.

Red-first: inherited-preset derive/switch-away and seeded-selection tests
in the permission suite; malformed-baseline-with-own-switch tests in both
policy suites.
This commit is contained in:
kingwl
2026-07-26 22:02:02 +08:00
parent ffb6435a41
commit f505bd9258
23 changed files with 179 additions and 67 deletions
@@ -54,6 +54,29 @@ export function effectiveSandboxMode(events: readonly SessionEvent[]): SandboxMo
return undefined
}
/**
* The session's complete sandbox-mode OVERRIDE chain — the one home every
* consumer (the policy service, the permission presets) resolves through:
* the fold of the session's OWN switches (events past the seed boundary — a
* fork seed's stale parent switch is subsumed by the delegation baseline
* captured after it), else the header's inherited baseline. Never the
* deployment default. The durable baseline is validated UNCONDITIONALLY — a
* corrupt or foreign header must fail loud on every read, not only when no
* own switch happens to shadow it.
* @param session - the session whose override chain to resolve.
* @returns the effective override, or `undefined` for a session following
* the deployment default.
* @throws when the header baseline is outside the closed mode vocabulary.
*/
export function sandboxOverrideOf(session: Session): SandboxMode | undefined {
const baseline = session.header.sandboxMode
if (baseline !== undefined && !SANDBOX_MODES.includes(baseline as SandboxMode)) {
throw new Error(`session header sandboxMode "${baseline}" is outside the closed mode vocabulary`)
}
const own = effectiveSandboxMode(session.events.slice(session.header.seedLength ?? 0))
return own ?? baseline as SandboxMode | undefined
}
/**
* THE write path for a session's sandbox-mode override: appends exactly one
* `sandbox/mode` event — the switch IS its event; nothing mutates mode state