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
@@ -399,8 +399,8 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
summary: 'Owns the deployment\'s permission presets and their write path.',
methods: [
{
signature: 'current(events: readonly SessionEvent[]): string',
jsDoc: '/**\n * Resolve the preset matching the effective knob values. A still-matching\n * last selection wins shared-bundle ties; otherwise the first table match\n * wins, or {@link CUSTOM_PRESET} when no entry matches.\n * @param events - the session\'s events in log order.\n * @returns the effective preset name, or `custom` when nothing matches.\n */',
signature: 'current(session: Session): string',
jsDoc: '/**\n * Resolve the preset matching the effective knob values — the same\n * override chains execution reads (own post-seed switches, else the\n * inherited header baseline, else the composition defaults), so a\n * delegated child\'s inherited knobs derive its real preset. A\n * still-matching last OWN selection wins shared-bundle ties (a seed-carried\n * selection is stale parent history, subsumed by the baseline); otherwise\n * the first table match wins, or {@link CUSTOM_PRESET} when no entry\n * matches.\n * @param session - the session whose preset to derive.\n * @returns the effective preset name, or `custom` when nothing matches.\n */',
},
{
signature: 'resolve(name: string): PresetSpec',