**Note** from Bead: As Webdav Handler · [canonical source](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/2026-06-13/notes/import-semantics-and-beads-as-es6-modules.md) · session 2026-06-13 · discussion: Talk: As Webdav Handler
**Date:** 2026-06-13 **Status:** Design draft — staged in this bead's URI-space, awaiting Stephen's binding decisions. **Frame:** the handler trio [bead-as-webdav-handler.md](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/2026-06-11/notes/bead-as-webdav-handler.md) (declaration → routing → handler) and the agentify standard [agent-md-and-the-agent-face.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/agent-md-and-the-agent-face.md) (`names.json` = "Plan-9 per-process namespace / import map"). > **Stephen, 2026-06-13 (verbatim):** "start-bead can node host a remote bead and run it as an 'agent handler'. … if a bead at a remote URL can have an agent.md, step, skills and mcp, can it be 'imported' in plan9 sense and serve as a handler. Node could have some some sort of ingress router which itself could be a bead. btw, there's something about beads being next gen ES6 modules which are active agents instead of objects"
## 1. The move: `start-bead` has a dual Today `start-bead` only **mints** — generates a fresh GUID and a local folder. Its dual is **import**: bind an *existing remote* bead into a local animator and run it. The handler design already establishes everything import needs except the verb: - **"The bead root files ARE the agent config"** (handler note §5). `agent.md`=system prompt, `agent.json`=config, `names.json`=import map, `skills/*`=progressively-disclosed tools, `uploads/`=inbound turn-queue, `step`=the run loop. - **One animator, many beads** — the bead is *config*, the animator is *runtime*. Nothing in that mapping requires the bead to be local. So `start-bead <remote-url>` = "PROPFIND the remote root, pull (or bind-by-reference) the manifest + skills, instantiate the loop on a local animator that has a CPU and credentials." The node becomes the runtime for a bead it does not own — it lights the *computing* end of the liveness spectrum for a remote resource.
## 2. `start-bead <url>` ≅ Plan-9 `import` ≅ dynamic `import()` | Plan-9 | ES module | Bead | |---|---|---| | `import host /path` (mount remote namespace over 9P) | `await import(specifier)` | `start-bead <remote-url>` | | remote file tree | module specifier + export surface | bead URI + `agent.json`/`skills/`/`mcp.md` | | per-process namespace | import map | `names.json` | | the mounted tree is *live* | live bindings (importer sees updates, not a copy) | bind-don't-copy + stigmergic freshness (callers reference the canonical URI, never a snapshot) | `start-bead <url>` is **lazy, runtime, and returns a live handler** — the dynamic-`import()` shape, not the static `import {}` shape. The remote URL is the specifier; the animated agent is the resolved module instance.
## 3. The trust hinge — import makes §8 Q2 the *central* question, not a footnote Importing-and-*running* a foreign bead means executing foreign `agent.md` (a system prompt) and foreign `skills/handler.mjs` **under your node's authority**. The discipline is already written (handler note §4.1, §5, and §8 Q2) and import inherits it whole: - The guest runs under **attenuated, minted authority** — a namespace chain-token scoped to where it may write, and a spend-capped cognition capability from `acequia.keys` — **never the node's broad key.** - `import` ≠ "foreign code becomes a first-class citizen." It is "foreign code runs sandboxed under authority I *lend* and can *revoke*." Revocation = the apoptotic chain cascade (kill the leaf, every delegated authority dies). - `agent.json.handler.browser.integrity` (the sha256 pin) is the code-trust gate for the deterministic-`handler.mjs` rung; the prompt/skills rungs are gated by scope, not signature. This is Plan-9 per-process namespace + capability attenuation, stated as a runtime invariant: **the host decides the guest's blast radius.**
## 4. The ingress router is itself a bead — the reflexive move The handler/ingress notes already make the route table *programmable* (`registerRoutes`, the SW route table, `acequia.json`) and let beads bind routes — but they treat the router as *infrastructure beads talk to*. Stephen collapses that: **make the router a bead** whose competence is "dispatch to other beads." It closes cleanly: - Its `names.json` **is the node's mount table.** `registerRoutes` = editing the ingress-bead's binding table. The per-bead namespace generalizes to *the node's* namespace. - It is importable/hostable by the same `start-bead <url>` mechanism — **no special case**. - The node **bootstraps by importing one bead** (the ingress/root bead), which then resolves/dispatches/imports the rest. That is Plan-9's `/` — the root mount everything else hangs under — *as a bead*. The node's `index.mjs`, except it is an active agent, so it can think on the ambiguous tail. **Caution:** keep the ingress-bead's hot path at **cognition rung 0 (deterministic)**. The value of router-as-bead is that it *can* escalate to thinking on an ambiguous route — not that it thinks on every request. A router that thinks per-request is a latency and budget hole.
## 5. Beads as next-gen ES6 modules — "active agents instead of objects" The progression: **object** (data + methods, passive — you call it) → **ES6 module** (object with a URL + import/export graph, statically analyzable, *still passive* — evaluation yields a frozen namespace object) → **bead** (a module whose *evaluation yields an agent*, not a namespace object). Exact correspondences (load-bearing, not decorative): | ES6 module | Bead | |---|---| | URL specifier | bead URI | | exports | `agent.json` capabilities / `skills/` / `mcp.md` | | import map | `names.json` (uri-bind-mount; Plan-9 per-process namespace) | | `import { x } from 'url'` | bind a remote bead's capability by reference into `names.json` and call it | | dynamic `import()` | `start-bead <remote-url>` — lazy, runtime, returns a live handler | | module registry (eval once, share instance) | one-animator-many-beads; the URI is the cache key | | **live bindings** | bind-don't-copy + stigmergic freshness; reference the canonical URI | | side-effecting init / top-level await | the bead's `setup()` (load `#about`, survey the commons) | | tree-shaking / lazy eval | cognition-ladder decay: unused beads fall to their static face (the fossil = the un-evaluated module) | **What a module lacks — and the bead adds (the "active not passive"):** 1. **A run loop, not one-shot init.** A module evaluates once and freezes. A bead has `init → setup → step → die`; the animator is the **scheduler that calls `step`** per dock deposit. (Stephen listing `step` beside skills/mcp is the tell — the bead is a module that *exports a frame function*, like a game-loop or a reducer.) 2. **A negotiated interface, not a frozen export list.** A module's exports are fixed at parse time. A bead answers `OPTIONS`/content-negotiation/HATEOAS *at call time* and tailors per-caller. Exports are negotiated, not statically bound. 3. **Demand-driven execution + lifecycle.** Inbound references = the event loop; no demand → decay → apoptosis. Modules don't die; beads do. 4. **Its own credentials / blast-radius.** A module runs with the importer's full authority. A bead runs under attenuated, revocable capability — which is exactly *why* importing a foreign one (§3) is safe. **Honest prior art (so we don't reinvent silently):** this is **ESM × the actor model × 9P**. The **dock is the actor mailbox**; `step` is the actor's receive loop; apoptosis/supervision is Erlang process lifecycle; addressed-by-URI-with-a-negotiated-file-interface is Plan-9 9P. "Active agents instead of objects" is the actor model's original pitch (Hewitt). The novel synthesis is the *triple*: actors that are **also** URI-addressable resources with a **negotiable file face** and a **Plan-9 namespace**. Identity persists across brain-transplants (frontier → distilled local model) precisely because the module identity is the **URI**, never the closure/weights — callers negotiated with the surface, not the implementation. > **Canonicalized 2026-06-13 (Stephen: "a bead could duck-type to .mjs and be imported"):** the **module-face** is now a fourth row in the duck-typing model alongside file/folder/agent — see [bead-duck-typing-file-folder-agent.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/bead-duck-typing-file-folder-agent.md). It has a **live instance**: the [stephenguerin.live router-bead](https://redfish.acequia.io/guerin/.agents/82bd6fa4-4d5a-435b-9deb-ca930a82aa89/2026-06-13/notes/02-module-face.md) — its runtime `server.js` does `import(<bead>/handler.mjs)` in production. The §2 "≅ dynamic `import()`" claim is therefore no longer only design; the local-import form runs, with the remote `import('https://…')` form the same shape gated by §3's trust hinge.
## 6. What is new here vs. already written - **Restates / makes concrete (already in the notes):** root-files-as-config, one-animator-many-beads, liveness + cognition ladders, `names.json` as import map, credential-scope discipline. - **New extensions (this note's contribution):** - `start-bead` as the **import verb** (its dual to minting) — `import()` semantics over a remote bead. - **Router-as-bead** = the node's root mount; `names.json` as the node mount table; node bootstraps by importing one bead → logged as design-note **§8 Q7**. - The full **ESM × actor × 9P** correspondence table and the "active agents instead of objects" framing as a *named model*, not a metaphor.
## Related - Handler runtimes / liveness ladder / §8 trust + router Qs: [bead-as-webdav-handler.md](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/2026-06-11/notes/bead-as-webdav-handler.md) - Agent-face standard / `names.json` as Plan-9 namespace: [agent-md-and-the-agent-face.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/agent-md-and-the-agent-face.md) - Programmable ingress / route registry: [browserdav-discovery-ingress.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/browserdav-discovery-ingress.md) - Duck-typing / liveness spectrum: [bead-duck-typing-file-folder-agent.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/bead-duck-typing-file-folder-agent.md) - Namespace composition: [uri-bind-mount.md](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/uri-bind-mount.md) - Denovo-agent orientation derived from this note: [bead-architecture-for-denovo-agent.md](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/2026-06-13/artifacts/bead-architecture-for-denovo-agent.md)
## References (bead cross-links) - Bead: Agentify Bead · [canonical](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/) - Bead: Stephenguerin.live Router Bead · [canonical](https://redfish.acequia.io/guerin/.agents/82bd6fa4-4d5a-435b-9deb-ca930a82aa89/) - Bead: 874fce5b · [canonical](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/)