docs(design): mark extension points (§5.5) shipped

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-26 21:36:11 +02:00
parent 4dcb8d1136
commit dc8c69ac6f

View File

@@ -552,9 +552,18 @@ trust inversion). The rule:
> site; the `PicloudModuleResolver` reads the importing node from Rhai's `_source` (set to each module's
> owner via `AST::set_source(encode(owner))` before `eval_ast_as_new` — the lexical chaining), and the
> cache is re-keyed by resolved `ScriptId`. Group modules + group-script imports are now allowed
> (`group_scripts_api`), and the single-node apply runs the §5.5 dangling-import `plan` check. **Opt-in
> extension points** (the dynamic-resolution branch + `[extension_points]` manifest declaration) remain
> the one deferred piece of §5.5 — a clean additive follow-up on top of the now-origin-aware resolver.
> (`group_scripts_api`), and the single-node apply runs the §5.5 dangling-import `plan` check.
>
> **Extension points (✅ shipped, 2026-06-26).** The opt-in dynamic-resolution branch landed: migration
> `0051` adds an owner-polymorphic `extension_points` table (optional `default_script_id` fallback);
> `ModuleSource` gained `resolve_extension_point(origin, name)` (Some only when the NEAREST declaration
> of `name` on the importer's chain is an extension point — a peer/nearer concrete module shadows it)
> and a chain-constrained `resolve_by_id(origin, id)`. The resolver checks the importer's chain first
> and, on a hit, resolves against `App(cx.app_id)` (the inheriting app), falling back to the default
> body. The decision keys on the trusted importer `origin`, so only the declaring parent can open the
> inversion — a descendant can't make a parent's sealed import dynamic or hijack one. Declared via
> `[[extension_points]] name = "..." default = "<local module>"` (app or group manifests); reconciled
> like `vars`, gated on the script-write capability, exported by `pic pull`.
### 5.6 Tree lifecycle: delete, reparent, rename
@@ -989,8 +998,8 @@ Resolved items now live inline next to their topic. What genuinely remains:
> can't shadow it; verified e2e). Mechanism: owner-polymorphic `ModuleScript`, origin-rooted
> `ModuleSource::resolve`, `ExecRequest.script_owner` threaded from every dispatch + `invoke()` site,
> `_source`-driven lexical chaining in the resolver (cache re-keyed by `ScriptId`), and the
> single-node dangling-import `plan` check. Still deferred: **opt-in extension points** (the only
> remaining §5.5 piece) and **invoke-by-id** staying app-scoped (inheritance is by-name only); CoW
> single-node dangling-import `plan` check. **Opt-in extension points shipped (§5.5, 2026-06-26).**
> Still deferred: **invoke-by-id** staying app-scoped (inheritance is by-name only); CoW
> is **redefine-in-app + re-apply** (no live auto-rebinding). Sharp edge to track: `routes.script_id`
> is `ON DELETE CASCADE`, so deleting a
> group script removes descendant apps' bound routes (within group-editor authority; the *group*