Applied Analysis: The Entity System SDK Through the Abstract Bridge Lens
Status: Layer 4 applied analysis at Sc2 (architectural decisions). Using the abstract bridge primitives {Ad, Is, Lc, Co, Au, Dp} to analyze the current SDK, identify gaps, and sequence work.
Source material: SDK-SYNTHESIS.md, NAMESPACE-AND-PEER-MODEL.md (the concrete decisions), analysis-abstract-bridge.md (the structural framework)
Purpose: Answer the practical question: what does the abstract bridge analysis actually TELL US about what to build?
1. Setting Up the Layer 4 Analysis
Fw: Abstract bridge domain {Ad, Is, Lc, Co, Au, Dp} as lens
Mn: Entity system SDK (the bridge materialized as code)
Sc: Sc2 (architectural — making SDK design decisions)
Cx: Digital context {Cm4, Pl4, Lb4, Co2-3, Sd3-4, Pr2-3}
Ls: {Go SDK, Rust SDK, Godot SDK} — three implementations as landscape
Tj: From SDK-L1 (raw operations work) → SDK-L2/L3 (ergonomic patterns)
2. Positioning the Entity System Bridge vs SDK Exposure
The entity system's bridge mechanisms are at HIGH levels — the 12 extensions implement all six abstract bridge concerns well. But the SDK doesn't EXPOSE these levels to application developers. There's a gap between what the bridge CAN do and what the SDK LETS you do easily.
2.1 Bridge level vs SDK exposure level
| Abstract bridge | Bridge mechanism level | SDK exposure level | Gap |
|---|---|---|---|
| Addressing (Ad) | Ad4 (composite: tree paths + content hashes + type names) | Ad2-3 (flat path operations, no scoped addressing) | SDK doesn't compose addressing — raw paths, no scoped handles |
| Isolation (Is) | Is3-4 (cryptographic peer isolation, capability scoping) | Is1-2 (peers exist but SDK doesn't scope operations to peers) | SDK doesn't make isolation ergonomic — you manually track which peer you're talking to |
| Lifecycle (Lc) | Lc3 (history extension provides versioned lifecycle) | Lc1 (manual create/delete, no subscription lifecycle, no workspace lifecycle) | SDK doesn't manage lifecycle — you manually create, no watch/subscribe, no cleanup |
| Composition (Co) | Co3 (extensions compose on tree, handlers compose) | Co2 (you can register handlers, but no composition patterns in SDK) | SDK doesn't provide composition patterns — no reactive pipelines, no cross-peer composition |
| Authority (Au) | Au3-4 (capability system specified, delegation chains designed) | Au1-2 (capabilities exist but SDK has --debug-grants not ergonomic auth) | SDK doesn't make authority usable — auth is a dev workaround, not a feature |
| Dispatch (Dp) | Dp3 (type-driven handler dispatch, longest-prefix matching) | Dp2-3 (execute works, but handler registration API incomplete) | SDK dispatch works but isn't fully programmable — can't easily register custom handlers |
2.2 The gap IS the "Level 2 problem"
The SDK-SYNTHESIS identified: "The gap between Level 1 (working) and Level 2 (partially working) is where all three projects are stuck."
In abstract bridge terms: the bridge mechanisms are at high levels (the entity system's extensions DO the right things). The SDK exposes them at LOW levels (raw operations, manual management, no ergonomic patterns). The Level 2 gap is the gap between bridge-level and SDK-exposure-level across ALL six concerns.
3. What the Pair Analysis Tells Us About Priority
The abstract bridge has 5 heavy pairs. Each heavy pair represents a concern-interaction that carries the most structural content. SDK work on heavy pairs produces the most value.
3.1 Heavy pairs → SDK priorities
Ad-Is (Addressing + Isolation) — HEAVIEST What it is: scoped addressing within isolation boundaries. SDK feature: TreeScope / scoped handle — operations scoped to a specific peer's subtree. Current state: Go has flat operations on Executor. Rust proposes TreeScope (v2). Neither has it working. What the analysis says: this is the #1 priority because it addresses the heaviest pair. A scoped handle gives you addressed operations within an isolated context — the fundamental unit of SDK interaction.
Ad-Lc (Addressing + Lifecycle) — HEAVY
What it is: lifecycle-categorized addressing.
SDK feature: Path conventions (workspace/, storage/, temp/) + workspace state management.
Current state: Go has WorkspaceState helper. Rust has raw tree operations. Path conventions diverged.
What the analysis says: #2 priority. Once you have scoped handles (Ad-Is), lifecycle-categorized paths within the scope are the next ergonomic win. This is where app/{id}/workspace/ vs storage/{identity}/ conventions get formalized.
Ad-Dp (Addressing + Dispatch) — HEAVY What it is: pattern-based dispatch to addressed targets. SDK feature: Handler dispatch (already works) + handler registration (incomplete) + watch/subscribe (the #1 implementation gap). Current state: dispatch works but subscription (which IS addressed dispatch of change events) isn't implemented end-to-end. What the analysis says: tied for #2-3. Watch/subscribe IS Ad-Dp — you address a path pattern and dispatch change events to a callback. Handler registration IS Ad-Dp — you address a handler pattern and dispatch operations to your code.
Ad-Co (Addressing + Composition) — HEAVY What it is: namespace composition — combining addressed resources from multiple sources. SDK feature: Multi-peer views (reading from multiple peers), extension composition. Current state: Rust has multi-peer. Go has single-peer. Neither composes across peers ergonomically. What the analysis says: #4 priority. Comes after individual peer access (Ad-Is) and lifecycle management (Ad-Lc) are solid. Composition ACROSS peers requires both addressing and isolation to be working first.
Is-Au (Isolation + Authority) — HEAVY
What it is: authorized access across isolation boundaries.
SDK feature: Capability management — ergonomic operations for grants, delegation, scoping.
Current state: --debug-grants flag. No SDK surface for capability management.
What the analysis says: important but can be deferred. Is-Au matters for multi-user and deployment. Not blocking single-developer experience.
3.2 The SDK work sequence derived from pairs
| Priority | Pair | SDK feature | Why this order |
|---|---|---|---|
| 1 | Ad-Is | Scoped handle (TreeScope) | Heaviest pair. Foundation for everything else. Scope = peer + prefix + capability. |
| 2 | Ad-Lc | Path conventions + WorkspaceState | Once scoped, lifecycle categories organize the scope's content. |
| 3 | Ad-Dp | Watch/subscribe + handler registration | Once scoped and organized, reactivity makes it live. Handler registration makes it programmable. |
| 4 | Ad-Co | Multi-peer composition | Once individual peers work well, compose across them. |
| 5 | Is-Au | Capability management | Once composition works, authorize it properly. |
This sequence matches the SDK-SYNTHESIS priorities almost exactly — but now with structural reasoning for WHY this order.
4. What the Partial Levels Tell Us About Each Decision
4.1 Scoped handle (Ad-Is)
The SDK needs to advance from:
- Ad: SDK-2 (flat paths) → SDK-3 (scoped composite addressing)
- Is: SDK-1 (peers exist) → SDK-2 (scoped to specific peer)
What the scoped handle provides:
scope = sdk.scope(peer, prefix="app/my-app/")
entity = scope.get("workspace/selection") // reads app/my-app/workspace/selection on this peer
scope.put("workspace/layout", layout_data) // writes within scope
scope.watch("workspace/**", callback) // subscribes within scope
// scope handles cleanup on drop/close
The scope composes Ad (prefix-based addressing) with Is (peer-bound isolation). This is the Ad-Is pair materialized as API.
Decision confirmed: Scoped handles as primary SDK interface. The abstract bridge analysis says this IS the right abstraction — it addresses the heaviest pair.
4.2 Path conventions (Ad-Lc)
The SDK needs to advance from:
- Ad-Lc: diverged paths → standardized lifecycle-categorized naming
The path convention IS Ad-Lc composition. Each top-level prefix categorizes by lifecycle:
| Prefix | Lifecycle category (Lc level) | Syncs? | What goes here |
|---|---|---|---|
system/ | Infrastructure (Lc-permanent) | Never (per-peer) | Protocol state — handlers, types, capabilities |
app/{id}/workspace/ | Session (Lc-session) | Optionally | UI state — windows, selection, layout |
app/{id}/settings/ | Configuration (Lc-persistent) | Yes | User preferences — survives sessions |
knowledge/, projects/ | Content (Lc-persistent) | Yes | User data — the valuable stuff |
temp/ | Ephemeral (Lc-ephemeral) | Never | Scratch — disposable |
host/ | Device-bound (Lc-hardware) | Never | Machine resources (device peers only) |
storage/{identity}/ | Identity-persistent | Yes (device network) | Identity-scoped data (device peers) |
Decision confirmed: Per-peer-type conventions from NAMESPACE-AND-PEER-MODEL.md. The abstract bridge analysis says this IS structurally right — it's lifecycle-categorized addressing, the second-heaviest concern pair.
4.3 Watch/subscribe (Ad-Dp)
The SDK needs to advance from:
- Dp: SDK-2 (execute works, polling for changes) → SDK-3 (subscriptions dispatch change events)
Watch/subscribe IS Ad-Dp: address a path pattern (Ad), dispatch change events to a handler (Dp).
The open questions from SDK-SYNTHESIS, now framed as bridge concerns:
"When a local write triggers a subscription, does the callback fire synchronously or on next tick?" → This is a Dp question: dispatch timing. In the abstract bridge, dispatch at Dp2 is pattern-based (asynchronous — event loop delivers). At Dp3 it's content-based (could be synchronous — the content type determines delivery). For the SDK: async (next tick) is safer and matches Dp2. Synchronous delivery is an optimization for Dp3 but risks reentrant complexity.
Recommendation from bridge analysis: Async delivery (Dp2). The SDK is at Level 1-2, not Level 3. Synchronous delivery can be added later as a Dp3 optimization without breaking the async contract.
"What's the event payload? Path + old hash + new hash? Or path + change type?" → This is an Ad question: how much addressing information travels with the event. At Ad2 (structured), path + change type is sufficient. At Ad3 (content-derived), old hash + new hash enables content-level diff. For the SDK: path + change type + new hash (Ad2.5 — enough to detect what changed, not enough for automatic diff).
4.4 Handler registration (Dp-Au)
The SDK needs to advance from:
- Dp-Au: internal-only handlers → application-programmable handlers
Handler registration IS Dp-Au: making a dispatch target available (Dp) with authority requirements (Au).
Go's pattern: RegisterHandler(pattern, handler_func) — simple, works. The handler declares its pattern (Dp) and the capability system scopes access (Au).
Decision from bridge analysis: Go's pattern is correct — it composes Dp (pattern registration) with Au (capability-scoped access). Formalize it. Don't over-design.
5. Landscape Comparison (Ls at Sc2)
5.1 The three implementations positioned in abstract bridge
| Concern | Go SDK | Rust SDK | Godot SDK |
|---|---|---|---|
| Ad | Flat operations + path strings | Flat + peer_id prefix (manual) | Planned: GDExtension path ops |
| Is | Single peer per app (implicit) | Multi-peer PeerManager (explicit) | App peer + network peers (designed) |
| Lc | WorkspaceState helper (partial) | Raw tree ops (none) | JSON files (external) |
| Co | Handler composition (works) | Extension composition (works) | Panel contract (designed) |
| Au | --debug-grants (workaround) | --debug-grants (workaround) | Not yet |
| Dp | Executor dispatch (strong) | Direct access (anti-pattern, fixing) | Panel context (designed) |
5.2 Where each is ahead
- Go: Dispatch (Dp) — Executor pattern is the reference. Lifecycle (Lc) — WorkspaceState exists.
- Rust: Isolation (Is) — multi-peer is implemented. Proposed TreeScope addresses Ad-Is.
- Godot: Design (all) — panel contract, command surface, app/network peer split are well-designed but unbuilt.
5.3 What convergence tells us
All three independently converge on:
- Scoped access as the right abstraction (Ad-Is convergence)
- Entity-backed state as the right pattern (Ad-Lc convergence)
- Protocol-first dispatch (Ad-Dp convergence)
The convergence IS the structural signal. These aren't arbitrary design choices — they're the abstract bridge concerns manifesting as SDK patterns.
6. Trajectory (Tj at Sc2)
6.1 Current → target
Current SDK: {Ad:2, Is:1-2, Lc:1, Co:2, Au:1, Dp:2-3}
Target SDK: {Ad:3-4, Is:3, Lc:2-3, Co:3, Au:3, Dp:3}
6.2 The path (ordered by pair weight)
Phase 1: Ad-Is (scoped handle)
- Implement TreeScope in Rust (v2 architecture)
- Refine Go's Executor to be scope-aware
- Specification: scoped handle = peer + prefix + capability chain
- Validates: Ad2→Ad3 and Is1→Is2 simultaneously
- Unblocks: everything else (all other work is easier with scoped handles)
Phase 2: Ad-Lc (path conventions + state management)
- Finalize path conventions per peer type (NAMESPACE-AND-PEER-MODEL decisions)
- Standardize WorkspaceState pattern from Go → all implementations
- Specification: lifecycle-categorized paths within scoped handles
- Validates: Lc1→Lc2
Phase 3: Ad-Dp (watch/subscribe + handler registration)
- Implement watch/subscribe end-to-end in one implementation (Go or Rust)
- Formalize handler registration API
- Specification: pattern-addressed change streams, handler registration contract
- Validates: Dp2→Dp3 and Lc1→Lc2 (subscription lifecycle)
- This is the #1 IMPLEMENTATION priority (most effort, highest unblocking)
Phase 4: Ad-Co (multi-peer composition)
- Cross-peer read patterns (scope A reads from peer B's tree)
- Sync configuration through SDK (not raw protocol)
- Validates: Co2→Co3
Phase 5: Is-Au (capability management)
- Ergonomic capability grant/delegation operations
- Replace --debug-grants with real auth workflow
- Validates: Au1→Au3
6.3 What changes vs the SDK-SYNTHESIS priority
The SDK-SYNTHESIS said:
- SDK-OPERATIONS.md spec (formalize Level 1)
- Path convention decision
- Type name decision
- Fine-grained subscriptions prototype
- Scoped tree handle implementation
The bridge analysis reorders: scoped handle before path conventions, path conventions before subscriptions. Reasoning: the scoped handle (Ad-Is) is the foundation. Path conventions (Ad-Lc) organize within the scope. Subscriptions (Ad-Dp) make the organized scope reactive. The SDK-SYNTHESIS had subscriptions higher because they're the biggest implementation gap — but structurally, the scope comes first.
The SDK-OPERATIONS.md spec is still urgent — but the spec should be organized around scoped handles as the primary abstraction, not around flat operations.
7. What the Analysis Produces That Ad-Hoc Review Didn't
7.1 Structural priority ordering
The ad-hoc SDK review produced a priority list based on "what's most blocking." The bridge analysis produces a priority list based on "what carries the most structural weight." These MOSTLY agree — but the bridge analysis puts scoped handles FIRST (heaviest pair) and subscriptions THIRD (important but dependent on scoping). The ad-hoc review had subscriptions higher because they're the most painful gap in daily use.
Both orderings are valid. The bridge analysis provides the STRUCTURAL argument; the ad-hoc review provides the PRAGMATIC argument. A good decision weighs both.
7.2 Design validation
The bridge analysis CONFIRMS that the converged SDK patterns are right:
- Scoped handles ARE the right abstraction (Ad-Is, heaviest pair)
- Path conventions ARE structurally necessary (Ad-Lc, lifecycle categorization)
- Protocol-first IS correct (Dp, dispatch goes through the protocol layer)
- Entity-backed state IS correct (Ad-Lc, state organized by lifecycle within addressed scopes)
This isn't new — the SDK review already found these. But the bridge analysis provides the WHY: these patterns implement the heaviest concern-pairs of the abstract bridge. They're not arbitrary conventions — they're structural necessities.
7.3 Gap identification
The bridge analysis identifies that Au (authority) is the MOST under-exposed concern. The capability system is specified but the SDK makes it unusable (--debug-grants). This will become a hard blocker when multi-user or deployment scenarios arise. The ad-hoc review noted this but didn't flag the structural weight. The bridge analysis says: Is-Au is a heavy pair. Neglecting Au while advancing Is (multi-peer) creates a structural imbalance.
7.4 The answer to "what does the abstract bridge domain tell us?"
It tells us:
- The scoped handle is the right central abstraction — it addresses the heaviest bridge pair (Ad-Is)
- The work sequence follows pair weight — Ad-Is → Ad-Lc → Ad-Dp → Ad-Co → Is-Au
- The SDK's Level 2 gap IS the bridge-exposure gap — mechanisms are at high levels, SDK exposes them at low levels
- Authority is a structural debt — currently the most under-exposed concern, will block multi-user
- The namespace conventions are lifecycle-categorized addressing — structurally constrained, not arbitrary
- Subscriptions are dispatch lifecycle management — they sit at the Ad-Dp-Lc intersection