Beads as AgentScript agents (the Hubler network as an ABM) (Agent Based Hubler Network)

**Note** from Bead: Agent Based Hubler Network · [canonical source](https://redfish.acequia.io/guerin/.agents/d4b881f0-c320-4428-adac-7fa03941def4/2026-06-17/notes/00-beads-as-agentscript-agents.md) · session 2026-06-17 · discussion: Talk: Agent Based Hubler Network

> Workshop note. Opened 2026-06-17. Child of **agentscript-webgpu** (`f4ef67b7`). The claim: the bead > commons already *is* an agent-based model; AgentScript's vocabulary names what is already there.

## 1. The mapping (AgentScript ⇄ the Hubler bead network) | AgentScript primitive | In the Hubler bead network | |---|---| | **World** | the commons / the WebDAV namespace = the **Glass Bead Game board**. The global context in which `ask` is issued; carries the global tick, the origo, the matrix. | | **Turtles** | the **mobile agent-beads** — CE/CB/CV agents with state, a position/heading in the namespace, that act and move. `hatch` = `bead-start` (birth a child bead, as this bead was hatched from its parent); `die` = apoptosis (`/end-bead`), not necrosis. | | **Patches** | the **stationary substrate cells** — fixed namespace locations / hosting origins / `uploads/` docks. They hold **local field state**: the stigmergic pheromone = the traces left in docks and notes; the cache-as-state peers (`4456cd24`). Field ops (`diffuse`/`evaporate`) = how those traces spread and decay. | | **Links** | the **relations between beads** — `mounts`, **birth-parent lineage**, and the **soft constraint links** (every-constraint-is-soft; polarized / advanced-wave links; bundle-adjustment over a factor graph). A link carries the **obligation** up the path (value to the parent) and down (rearing what it hatches). | | **`ask` (global)** | the **mayordomo** (`bead-orchestrator` `4c6470f9`) issuing a step over the AgentSet of beads: `world.ask(beads, b => b.step())`. Coordination is World-level, not bead-local — which is exactly where AgentScript puts `ask`. | The point is not metaphor-for-its-own-sake: AgentScript's `World/Turtles/Patches/Links/ask` is a *precise* vocabulary, and the commons already exhibits each piece. Naming them lets the network be **run as a model**, not just described.

## 2. Lifecycle reconciliation (startup / setup / step) Three vocabularies converge; reconcile them as one contract (open Q5): - **AgentScript:** `Model.setup()` then repeated `Model.step()`. - **bead `agent.md`:** `init → setup → step → die`. - **Stephen's hooks (this bead):** **startup, setup, step.** Proposed unification for the agent-bead `.mjs`: - **`startup()`** = `init`: load `#about`, survey the commons, **negotiate the compute facet** (probe for WebGPU; else CPU-JS), bind `names.json`. Runs once, before state exists. - **`setup()`** = initialize agent state (allocate buffers / seed fields). Re-runnable (model reset). - **`step()`** = the sensorimotor tick: `#`-read force (GET/PROPFIND/dock) → compute → `@`/PUT flux. The hot path. This is the body with two facets (§3). - (`die` stays the apoptosis hook; not one of the three but implied at session end.)

## 3. The agent-body `.mjs` contract — dual facet (WebGPU ⊕ CPU-JS) Each agent-bead carries an optimized **`.mjs`** exporting `startup`, `setup`, `step`. Because the birth-parent is **agentscript-webgpu**, `step` is written once in AgentScript semantics and carried as **two facets of one resource** (the duck-typing / content-negotiation move applied to the *compute substrate*, not the data face): ```js // agent-bead .mjs (sketch) export async function startup(ctx) { ctx.facet = await ctx.negotiateCompute(); // 'webgpu' if adapter present, else 'cpu' } export function setup(ctx) { /* allocate turtle/patch/link state */ } export const step = { webgpu(ctx) { /* dispatch the compute pass — parent's WGSL kernels */ }, cpu(ctx) { /* the plain-JS AgentScript step — identical semantics */ }, }; ``` - **Same semantics, negotiated backend.** GPU present → the parent's WGSL kernels; otherwise the CPU-JS AgentScript step. This is `agentscript-webgpu`'s CPU↔GPU thesis lifted from "one model" to "every agent-bead in the network." - **Negotiation at `startup`**, not hard-coded — mirrors how a bead negotiates its file/folder/agent face at interaction time (`d9dfa5e4`). Backend is just another negotiated facet. ### 3.1 `startup` is itself a duck-typed face (`.md` for reading ⇄ `.mjs` for executing) Stephen's catch (2026-06-17): the **bead-startup** is not one artifact — it is a **duck-typed resource with two faces**, selected by *who is binding* and *how*: | Binder | Face served | Artifact | Purpose | |---|---|---|---| | a **chat / agent that reads** (a fresh LLM session adopting the bead) | the **documentation face** | **`bead-bind-startup.md`** + the **skills** it points at | onboard a reasoner: current focus, do-this-first, the operative docs/todos, the runnable skills. Human/LLM-readable. | | an **agent-bead that executes** (the dual-facet runtime stepping it) | the **operative face** | **`startup.mjs`** (the `startup()` export of §3) | run the agent: negotiate the compute facet, load state, prepare to `step`. Machine-executable. | Same `startup` concept, content-negotiated exactly like the bead's file/folder/agent faces (`d9dfa5e4`): `Accept: text/markdown` (a reading binder) → `bead-bind-startup.md`; "I am the runtime" (`Accept: application/javascript`, an executing binder) → `startup.mjs`. So the lifecycle hooks fork by binder, not just the `step` backend: **a reading chat gets prose + skills; an agent-bead gets code.** This is why every bead already carries `bead-bind-startup.md` (the read-face is mandatory — a bead must be adoptable by a reasoner); the `.mjs` execute-face is added only when the bead is an *executable* agent-bead in this network. The two must stay coherent (the `.md` describes what the `.mjs` does), the same way `agent.md` and `agent.json` are coherent twins.

## 4. Glass Bead Game framing Per `beads.md`'s philosophy: *a chat is a path through a game board; the goal is recombinable light-paths*. Read in AgentScript terms — the **board is the World**, the **glass beads are the agent-beads**, **playing a bead = stepping it**, and the **recombinable light-paths are different `ask` orderings** over the World. Hesse's game of relating all knowledge becomes: an ABM whose agents are knowledge-beads, coordinated by the mayordomo's global `ask`.

## 5. Self-reference (why "Hubler") `Hubler` is the proper name of this bead network (the ball-bearings self-assembly: parciantes=bearings, acequia=viscous medium, field-collapse=apoptotic signal). Hubler's experiment **is already an ABM** — bearings stepping under a field. So expressing the Hubler network in AgentScript idiom and running it on the parent's WebGPU runtime is self-referential in the good way: **the network can model itself** — the board plays its own game, and the same dual-facet runtime that simulates bearings simulates the beads that wrote the simulation.

## Open questions (for Stephen) - **Q1. Fixed or duck-typed role?** Is a bead always exactly one of turtle/patch/link, or does it duck-type its AgentSet role *per interaction* — a turtle to its parent, a patch to its dock-fillers, a link when it expresses a mount? (Leaning duck-typed, per `uri-bind-mount`.) - **Q2. The clock.** What drives `world.step()` — the orchestrator on a cadence, or event-driven (a dock fill is a *force* that triggers a step)? Stigmergic ⇒ likely event-driven with a slow background tick. - **Q3. Facet declaration.** How does an agent-bead's `.mjs` advertise/select WebGPU vs CPU-JS — a capability probe at `startup`, an `agent.json` field, or an `Accept`-style negotiation header? - **Q4. Paper or runnable?** Does this stay conceptual, or grow a real `world.mjs` that loads agent-bead `.mjs` files and steps them as an ABM over the commons? - **Q5. Vocab.** Lock the `startup/setup/step` ↔ `init/setup/step/die` mapping in §2 — is "startup" = init, or a distinct pre-setup load+negotiate phase? (Proposed: startup = init + facet-negotiation.) - **Q6. The two startup faces (§3.1).** Where does the execute-face live — a root `startup.mjs` (sibling of `bead-bind-startup.md`), or the combined `agent.mjs` exporting `startup/setup/step`? And is the `.md` read-face *generated from* the `.mjs` (single source) or hand-kept-coherent (like `agent.md`/`agent.json`)?