feat(app-boot): register cordis:group beside cordis:include

A composition that shares one `isolate` realm across rows needs a
`cordis:group` row, and a preset living outside this workspace — the
authored ones under the Harness home — cannot resolve
`@cordisjs/plugin-group` by name: Node's upward `node_modules` walk
never reaches the harness from there. Registering it as a loader builtin
beside `cordis:include` loads both through the ambient module pipeline
instead.

Record it in the preset Agent Note, which leans on the realm vocabulary
without saying where the group row comes from, and drop the preset
README's limitation claiming this builtin is unavailable — it described
the state this change ends.

The test's assertion had a vacuous escape: `provide` mints the root
symbol unconditionally, so the `rootKey === undefined` disjunct could
never hold and the comment claiming the root realm never learned the
name was wrong. Pin both halves — the symbol exists, nothing is stored
under it — and clean up the global the fixture writes.
This commit is contained in:
Yichen Jiang
2026-08-06 11:57:00 +08:00
parent 065257addb
commit e27d38efd6
15 changed files with 82 additions and 14 deletions
-1
View File
@@ -58,5 +58,4 @@ Prefix-stable for the life of an agent: a composition is installed once, before
- **A preset cannot be changed on a live agent** — the mount happens once during creation, so switching a running session's composition would mean unwinding its subtree mid-turn, dropping tools the model may already have called. Changing the default affects only sessions created afterwards.
- **Display names are the directory id** — a preset carries no manifest, so pickers and settings surfaces show the id until a consumer needs richer metadata.
- **`isolate` realms cannot be expressed across rows without `cordis:group`** — an entry-local realm works on a single row, but grouping a provider with its consumers under one shared realm needs the group builtin, which `dsh-app-boot` does not register.
- **Root scans are not watched** — every read hits the filesystem instead, which keeps the roster fresh but puts one `readdir` per root on each `list()`.