feat(modules): extension-point-aware resolver policy (§5.5 C2)

Add the runtime heart of extension points: `ModuleSource::resolve_policy`
decides lexical vs dynamic resolution by the NEAREST declaration of a name
walking up the importing origin's chain — a concrete module → lexical (seal
to origin, Phase 4b); an extension-point marker → dynamic, resolved against
the inheriting app (`cx.app_id`) so the app can override, falling back to the
default body up-chain; the EP wins a depth tie.

- shared: `ModuleResolution { Module | NoProvider | NotFound }` + a
  `resolve_policy(origin, inheriting_app, name)` trait method with a
  lexical-only default impl (existing fakes inherit it unchanged).
- PostgresModuleSource: one-round-trip nearest-declaration query (min EP depth
  vs min module depth over the chain CTEs), then the lexical/dynamic branch.
- module_resolver: calls `resolve_policy(origin, cx.app_id, path)`; maps
  NoProvider → a clear "extension point has no provider" error, NotFound →
  module-not-found. Cache + AST-source sealing unchanged.
- executor-core tests: a policy fake + 3 cases (app override binds dynamically,
  no-provider errors, non-EP stays lexical).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-29 20:07:59 +02:00
parent 8b68a7d7e8
commit 8f966783fe
5 changed files with 299 additions and 16 deletions

View File

@@ -76,7 +76,9 @@ pub use inbox::{
pub use invoke::{InvokeError, InvokeService, InvokeTarget, NoopInvokeService, ResolvedScript};
pub use kv::{KvError, KvListPage, KvService, NoopKvService};
pub use log_sink::{ExecutionLogSink, LogSinkError};
pub use modules::{ModuleScript, ModuleSource, ModuleSourceError, NoopModuleSource};
pub use modules::{
ModuleResolution, ModuleScript, ModuleSource, ModuleSourceError, NoopModuleSource,
};
pub use outbox_writer::{HttpDispatchPayload, NewHttpOutbox, OutboxWriter, OutboxWriterError};
pub use pubsub::{
topic_matches, validate_topic_pattern, NoopPubsubService, PubsubError, PubsubService,