feat(interceptors): ordered before-chains + cycle guard + ctx plumbing (§9.4 M1+M2)
M1: introduces a clone-cheap InterceptorCtx { interceptors, self_engine,
limits } threaded into every SDK register fn (kv/docs/files/queue/pubsub/http)
so the non-KV services carry the hook seam (unused until M7-M11); KvHandle
collapses its three fields into one ictx.
M2: replaces the nearest-only resolver with ordered before/after chains. The
trait becomes resolve(cx, service, op) -> InterceptorChain { before, after }
(migration 0074 adds a phase column + phase-aware unique indexes). The before
-chain runs ancestor->app (depth DESC) so a group compliance guard can't be
bypassed by a descendant; single-marker behavior is byte-identical to before.
An identity cycle guard (thread-local visited-set keyed by script_id) denies a
detected cycle, alongside the existing binary re-entrancy break. Fail-closed
verdict preserved (allow only on #{ allowed: true }; a Dangling entry or a
missing engine back-ref denies); app_id still derives from cx.app_id only.
after-chains resolve but stay unused until M3. Pinned by two new interceptor
journeys (ancestor->app chain ordering; self-referential no-recurse).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
20
crates/manager-core/migrations/0074_interceptor_phase.sql
Normal file
20
crates/manager-core/migrations/0074_interceptor_phase.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- §9.4 Service Interceptors M2 — before + after phases.
|
||||
--
|
||||
-- The 0073 marker guarded only the BEFORE-op allow/deny hook. M2 introduces an
|
||||
-- explicit `phase` so an owner can declare a `before` AND an `after` interceptor
|
||||
-- for one `(service, op)`. Existing markers default to `phase='before'` — the
|
||||
-- 0073 behaviour is unchanged. The partial-unique indexes gain `phase` so the
|
||||
-- two phases are distinct rows per owner (one before + one after each).
|
||||
|
||||
ALTER TABLE interceptors
|
||||
ADD COLUMN phase TEXT NOT NULL DEFAULT 'before'
|
||||
CHECK (phase IN ('before', 'after'));
|
||||
|
||||
-- Recreate the per-owner uniqueness to be per (owner, service, op, PHASE).
|
||||
DROP INDEX interceptors_group_uidx;
|
||||
DROP INDEX interceptors_app_uidx;
|
||||
|
||||
CREATE UNIQUE INDEX interceptors_group_uidx
|
||||
ON interceptors (group_id, service, op, phase) WHERE group_id IS NOT NULL;
|
||||
CREATE UNIQUE INDEX interceptors_app_uidx
|
||||
ON interceptors (app_id, service, op, phase) WHERE app_id IS NOT NULL;
|
||||
Reference in New Issue
Block a user