Orchestrator charter — the mayordomo of the bead commons (Orchestrator)

**Note** from Bead: Orchestrator · [canonical source](https://redfish.acequia.io/guerin/.agents/4c6470f9-b74a-4aba-b436-5e998f469cce/2026-06-14/notes/00-orchestrator-charter.md) · session 2026-06-14 · discussion: Talk: Orchestrator

**Bead:** `4c6470f9-b74a-4aba-b436-5e998f469cce` (`bead-orchestrator`) · **Opened** 2026-06-14 · for Stephen Guerin This note is the working charter. It states the four duties, sketches a mechanism for each grounded in the existing ecology design, and lists the binding decisions left to Stephen. It is a workshop piece, not a gallery piece: expect it to be revised as duties get bound.

## Frame: orchestrator = mayordomo, not owner In the acequia tradition the **mayordomo** keeps the ditch flowing and shapes the demand on it; the mayordomo does not own the water. This bead is the digital mayordomo of the `.agents/` commons. It **observes, reports, adapts, and brokers** — it never force-writes into a bead it does not own. Its efferent writes land in its own subtree and in other beads' `uploads/` docks ("hey you, it's me"). It shapes the demand ring; it does not rewire the parciante beads under them. This keeps it inside the parciante ethics: reciprocity / prorrata, apoptosis-not-cancer, no reification of infrastructure it doesn't own. The orchestrator is also, structurally, a **Hubler-net demand shaper**: protocol-conformance is a structured demand on the bead field; the orchestrator concentrates that demand where the field is out of conformance, and lets the parciante beads (or their animators) do the actual rewiring.

## Duty 1 — Conformance monitoring (keep the architecture current) **Goal.** Each bead's interface files should track the latest bead protocol (`.agents/beads.md`). Today the canonical root-file set is: `about.md` (required), `README.md` (required when deployed), `agent.md` + `agent.json` (when it has an agent-face), `keywords.json` (recommended), `names.json` (when it cites others), `bead-bind-startup.md` (recommended when resumable), optional `mcp.md` / `handler.mjs`. Beads minted before each ratification drift. **Mechanism sketch.** - A `conformance-scan.mjs` skill walks `.agents/*/`, and for each bead emits a record: which root files exist, whether `agent.json` parses and carries the current keys (`id`, `name`, `resourcetype`, `body`, `parent`, `corridors`, `capabilities`, `lifecycle`), whether `keywords.json`/`names.json` are present and well-formed, last-sync staleness, and a declared-vs-detected `protocolVersion`. - Output is a single `conformance.json` + human `conformance.md` **in this bead's `artifacts/`** — the registry/index the commons currently lacks. - Per-bead findings are *offered* into that bead's `uploads/` dock as a "hey you, it's me" envelope; the bead's own animator (or its parciante) decides whether to apply. The orchestrator never edits another bead's tree. - The scan is the discovery substrate for Duties 2–4 (it produces the bead list + version map everyone else reads). **Conformance rules (seed list).** The scan checks each bead against named rules; findings are *offered* into the target's dock. First rules: - `root-files` — required root files present + well-formed for the bead's faces (the table in `beads.md`). - `agent-json-keys` — `agent.json` parses and carries the current keys. - `protocol-version` — declared `protocolVersion` resolves (else Duty-2 adapter needed). - **`clickable-urls`** *(added 2026-06-18, Stephen)* — **every URL in a bead's `.md`/`.html` must be a clickable link (`[text](url)` / `<a href>`), never a bare-text or backtick-code-span URL.** Rationale: a non-clickable URL is an **un-hatched link** — dead text with no charge, not participating in the field ([polarized-links `874fce5b`](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/polarized-links.md); [acequia-link `72efa91c`](https://redfish.acequia.io/guerin/.agents/72efa91c-3506-49f2-9b5e-6af4c02ec12e/about.md) is the rule's conceptual home). The human-readable convention belongs in [`.ai/conventions.md`](https://redfish.acequia.io/.ai/conventions.md); the orchestrator is the *enforcer*. First finding logged 2026-06-18 against fire-progression [`182bd1a7`](https://redfish.acequia.io/guerin/.agents/182bd1a7-a376-4dd0-b445-578adc6635b9/about.md) (offered into its dock). **Open:** is the registry a flat `conformance.json` here, or a first-class **registry bead** that other beads mount by name? (lean: start flat here, promote to a registry bead if it earns traffic — desire-path rule.)

## Duty 2 — Interface-version duck-typing (don't break apps bound to old beads) **Goal.** Apps/callers were written against a bead's interface *as it was*. When the protocol evolves we must not silently break them. We need (a) an explicit version label and (b) an adapter layer that presents an old bead under a newer contract — or a new bead under an older caller's expectations — *at interaction time*. **Mechanism sketch.** - **Introduce `protocolVersion`** on the agent-face (`agent.json.protocolVersion`, mirrored as a header field in `agent.md`). Today identity is GUID + file-hash with **no explicit version field**; this is the gap. This bead dogfoods `"protocolVersion": "bead-protocol/0.3"` (the current ratified root-file set; label is provisional pending Stephen). - **Adapter layer, not rewrite.** A bead is duck-typed: its face is chosen at interaction time (`GET`+`Accept` → file; `PROPFIND` → folder; `OPTIONS` → agent). Extend that collapse with **version negotiation**: a caller may send `Accept-Bead-Version: <range>`; the handler/animator resolves through an adapter that maps the bead's native version to the requested one (rename moved fields, synthesize newly-required ones with safe defaults, downcast removed ones). This is content-negotiation applied to the *protocol*, exactly the existing duck-typing rule one level up. - Adapters live as small pure transforms (e.g. `adapters/0.2-to-0.3.mjs`) the orchestrator publishes; the animator runtime (`server.js`, the SW handler) applies them. Migration is therefore **lazy and reversible**: nothing is force-upgraded; old beads keep their bytes and are adapted on read. - A bead may *also* be eagerly migrated (offer a patch into its dock) when its parciante consents — but adaptation is the default so nothing breaks while consent is pending. **Open:** version label scheme (`bead-protocol/MAJOR.MINOR`? date-stamped?); where adapters execute (orchestrator-published, animator-applied — confirm); whether `Accept-Bead-Version` is the negotiation channel or a query param.

## Duty 3 — Smart sync + leader election across acequia endpoints **Goal.** Beads are increasingly served from **several origins** (the home port-forward node, cloud hosts, the shared host). Sync today is per-origin and additive (`/bead-sync`, local-origin-authoritative, MKCOL-on-first, dirty-gated background push). There is **no cross-endpoint consensus and no leader election** — the hosting runbook (7049c694) *names* a lease but nothing implements it. Two animators could both think they hold a path. **Mechanism sketch.** - **Endpoint registry** — `names.json` carries the known acequia endpoints; the orchestrator probes each (PROPFIND/`_status`) for liveness + the version-vector of each bead it serves. - **Conflict resolution** — additive by default; on divergence resolve by (mtime + a per-bead version vector) and surface true conflicts rather than silently clobbering. Remote deletes never auto-propagate (existing rule). - **Leader election / lease** — exactly one animator holds the write-lease for a given path/bead at a time. Sketch: a lease record (short TTL, renewed by the holder) written to a well-known path; challengers read it, and on a lapsed lease the highest-priority live endpoint takes it via a "hey you, it's me" claim. Lease loss demotes the bead down the liveness ladder (animator → SW → static 202-dock) — no request is ever refused, only answered at lower liveness. This reuses the apoptosis model: an animator that loses its lease apoptoses its hold cleanly rather than necrosing into a split-brain. - The orchestrator is the **broker/observer** of this, not necessarily the lease-holder itself: it watches that election is healthy and reports split-brain / stale-lease conditions. **Open:** where the lease record lives (per-bead `lease.json`? a central `acequia.leases` plane sibling of `acequia.chains`/`acequia.keys`?); election priority policy (home-node-preferred? lowest-latency-to-origin? explicit rank?); whether the orchestrator brokers or merely audits.

## Duty 4 — OS-node subagents: service-worker cache → real CORS origin **Goal.** A service worker on domain A fills a cross-origin cache (subresources, bead data, model weights) that logically belongs to origin B. Getting those cached bytes to / from the **actual CORS origin** — across the same parciante's devices (windows / mac / linux / android / iphone) — needs help the SW alone can't give (CORS walls, background-fetch limits, no cross-origin SW reach). **Mechanism sketch.** - The orchestrator dispatches a thin **node subagent per OS** that runs where the SW can't: it holds (or can mint, via the token-granting pattern) a **scoped, short-TTL token** for origin B, and bridges the SW's cache to B's CORS origin — pushing what the SW staged up to the origin, or pulling origin-fresh bytes the SW could not fetch cross-origin. - Each OS gets its own adapter because the bridge primitive differs: a desktop daemon (CV) vs. a mobile background-task vs. a SW companion. Same contract, per-platform body — the liveness-ladder idea applied across devices. - Credential placement follows the parciante-node rule: keys live on the node, scoped by blast-radius, never in the commons; the bridge token is attenuated to origin B's needed paths only and cascade-revocable. - This is the cross-origin generalization of the home-hosting "origin is an animator" pattern: the SW is one rung, the OS subagent is the rung that can reach across origins the browser sandbox can't. **Open:** the exact bridge contract (push-staged vs. pull-fresh vs. both); whether subagents are long-lived daemons or woken on demand; how a SW signals "I have cross-origin work" to its OS subagent (a dock path it PUTs to? a local socket?); which platform to prototype first (lean: windows/CV first — the existing animator substrate is already there).

## Mounted beads (the commons this orchestrator tends) Recorded in `names.json`. The load-bearing ones: - **[`fe7fbaf5` bead-as-webdav-handler](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/about.md)** — the handler contract, liveness ladder (static→SW→OS animator), cognition ladder, "one daemon many beads" animator. Duties 3 & 4 build on this. - **[`82bd6fa4` stephenguerin-live-router](https://redfish.acequia.io/guerin/.agents/82bd6fa4-4d5a-435b-9deb-ca930a82aa89/about.md)** — the live, deterministic router-bead + generic `server.js` runtime + `names.json`-as-mount-table. The worked instance of bead-as-config / animator-as-runtime. - **[`7049c694` home-port-forward-hosting](https://redfish.acequia.io/guerin/.agents/7049c694-e45b-4116-a887-49e64885ac8e/about.md)** — multi-endpoint hosting (Caddy→node origin), where the lease/leader-election is named. Duty 3's substrate. - **[`d9dfa5e4` agentify-bead / duck-typing](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/about.md)** — bead-duck-typing-file-folder-agent + the `agent.md`/`agent.json` agent-face design. Duty 2's foundation. - **[`5595c7f1`](https://redfish.acequia.io/guerin/.agents/5595c7f1-4621-437c-a4ae-7902b640f0e8/agent.md)** — the original `agent.md` prototype; the canonical interface shape Duty 1 validates against. - **Protocol + skills:** [`.agents/beads.md`](https://redfish.acequia.io/guerin/.agents/beads.md), [beads SKILL](https://redfish.acequia.io/skills/beads/SKILL.md), [bead-sync SKILL](https://redfish.acequia.io/skills/bead-sync/SKILL.md) (in `.ai/skills/bead-sync/SKILL.md`), [webdav-context](https://redfish.acequia.io/skills/webdav-context/SKILL.md), [EULA-compliance](https://redfish.acequia.io/skills/EULA-compliance.md).

## Open questions (Stephen binds) 1. **Registry shape** — flat `conformance.json` in this bead, or a first-class registry bead other beads mount? 2. **Version label** — `bead-protocol/MAJOR.MINOR`? date-stamped? Is `0.3` the right name for today's root-file set? 3. **Adapter execution** — orchestrator publishes adapters, animator/SW applies them at read time — confirm? Negotiation channel = `Accept-Bead-Version` header vs query param? 4. **Lease record location + election policy** — per-bead `lease.json` vs a central `acequia.leases` plane; election priority (home-preferred / lowest-latency / explicit rank); does the orchestrator broker the lease or only audit it? 5. **Cross-origin bridge contract** — push-staged / pull-fresh / both; long-lived daemons vs woken-on-demand; SW→OS-subagent signaling channel; first platform to prototype. 6. **Scope of force** — confirm the orchestrator only ever *offers* (dock envelopes) and never writes into another bead's tree, even for "obviously safe" migrations.

## References (bead cross-links) - Bead: 874fce5b · [canonical](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/) - Bead: Acequia Link · [canonical](https://redfish.acequia.io/guerin/.agents/72efa91c-3506-49f2-9b5e-6af4c02ec12e/) - Bead: Fire Progression · [canonical](https://redfish.acequia.io/guerin/.agents/182bd1a7-a376-4dd0-b445-578adc6635b9/) - Bead: As Webdav Handler · [canonical](https://redfish.acequia.io/guerin/.agents/fe7fbaf5-4c47-43b6-be1b-2f6ca15e8bfa/) - Bead: Stephenguerin.live Router Bead · [canonical](https://redfish.acequia.io/guerin/.agents/82bd6fa4-4d5a-435b-9deb-ca930a82aa89/) - Bead: Home Port Forward Hosting · [canonical](https://redfish.acequia.io/guerin/.agents/7049c694-e45b-4116-a887-49e64885ac8e/) - Bead: Agentify Bead · [canonical](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/) - Bead: CV · [canonical](https://redfish.acequia.io/guerin/.agents/5595c7f1-4621-437c-a4ae-7902b640f0e8/)