Repository navigation
Description
Summary
Design client-side capability providers: the mechanism by which a client — any client — offers capabilities (sensors, actuators, storage, compute, UI surfaces, local services) into the same data / capability model the rest of id uses, so other authorised parties can discover and use them under least-privilege grants.
This extends #789 (Phase 13 F13.7 client-side capability providers under the ceiling model). Drew's framing: this is a huge part of the project — arguably the core feature. The test of the model is that the same data / capability model works, unchanged in its essentials, when the provider is:
- an ESP32 emitting data over an MQTT bridge,
- a terminal acting as client or as server,
- a game engine integration (Bevy named),
- a smartphone, and
- a website.
If the model needs a special case per target, the model is wrong; this issue exists to find the model that does not.
Relates to: #789.
Core model to design
Providers and capabilities
- A provider is any client-side entity that declares capabilities it offers: typed, described, and versioned (capability name, input/output shape, units / semantics, rate / size limits, side effects).
- Capabilities are offered into the ceiling model (id: Phase 13 F13.7 client-side capability providers under the ceiling model #789's framing): a provider can never offer more than its own ceiling allows, and a consumer can never receive more than the grant — the provider model must compose with, not bypass, existing capability / grant machinery.
- Provider identity: a provider is bound to an identity in the system (which one — the user's, the device's own, a pseudo / delegated identity?) and the design must cover device-owned vs user-owned providers and shared / public providers.
Declaration
- How a provider declares what it offers: a manifest / declaration artefact — contents, signing, versioning, update and withdrawal of declarations.
- Static vs dynamic declaration: fixed firmware capabilities (ESP32) vs runtime-discovered capabilities (phone sensors present, terminal tools installed, engine features enabled).
- Declaration honesty: a declaration is a claim — what, if anything, verifies that a provider can actually do what it declares (test invocations, attestation, nothing — reputation only)? State the choice per target class.
Discovery
- How consumers find providers and their capabilities: within a world, within a server, across a bridge / federation — and the visibility rules (a provider is discoverable by whom, by default?).
- Discovery metadata minimisation: discovery must not leak a device inventory to parties with no grant (what does an unauthorised browser learn — existence? type? owner?).
- Stale discovery: providers that vanish (device off, tab closed, game quit) — TTLs, heartbeats, tombstones, and what a consumer's cached view may assume.
Negotiation
- Before use, provider and consumer negotiate: capability version, data format / encoding, rate, quality / resolution, session lifetime.
- Negotiation failure is a normal outcome: partial agreement (lower rate, coarser data), counter-offers, and clear failure reasons — design the shape, per target class where bandwidth / latency differ wildly (MQTT bridge vs in-process engine plugin).
- Who initiates, who can refuse, and whether negotiation itself requires a grant or is pre-grant metadata exchange (see discovery minimisation).
Least-privilege grants
- Use of a capability requires a grant: scoped to capability, provider, consumer, purpose where expressible, rate / volume, and expiry. Default is no access; grants are explicit, revocable, and auditable.
- Grant issuance flows per target class: who approves a grant to read a phone's location vs an ESP32's temperature vs a terminal's command execution — the sensitivity range here is enormous and the UX must scale with it (standing grants for low-sensitivity telemetry; per-use approval for actuation / execution).
- Delegation and attenuation: can a consumer pass on a narrower grant? Must compose with the system's existing delegation model.
- Actuation vs observation are different risk classes and the grant model must treat them differently (reading a sensor vs firing a relay vs running a terminal command).
Offline / degraded behaviour
Per target class, define what happens when connectivity, the server, or the consumer disappears:
- Provider keeps sensing / buffering? Buffer size, drop policy, backfill on reconnect, ordering and gap signalling in emitted data.
- Grants while offline: cached grants with expiry, no-new-grants-while-offline rule, actuation while offline (allowed under a standing grant? never? per class?).
- Degraded modes: reduced rate / resolution, local-only operation, store-and-forward via bridge (MQTT QoS levels and their mapping onto the model's delivery guarantees).
Target classes (the model must fit all five)
For each: declaration form, transport, constraints (power, bandwidth, CPU, sandbox), identity binding, and the offline story — as instantiations of the one model, with differences listed explicitly and justified.
- ESP32 over an MQTT bridge — constrained device, intermittent connectivity, firmware-fixed capabilities, the bridge as translator between MQTT topics and the capability model: topic ↔ capability mapping, bridge trust (the bridge sees / can forge what?), provisioning a device identity and its ceiling.
- Terminal as client or server — a CLI host offering capabilities (files, commands, local services) as a client, and the dual case: the terminal host is the server others connect to. Command execution as the highest-sensitivity capability class; sandboxing expectations stated, not assumed.
- Game engines (Bevy named) — an engine plugin / component model: in-game entities offering and consuming capabilities, tick-rate and latency constraints, capabilities that exist only while a world / session runs, and the boundary between game state and the wider system (what may an external consumer do to a running game, and vice versa).
- Smartphone — OS permission systems (location, sensors, notifications) composed with
idgrants: two gates, both must pass; background execution limits; provider lifecycle tied to app state; battery-aware rates. - Website — a browser tab as provider: sandbox limits, per-origin identity, capabilities that die with the tab, user-gesture requirements for sensitive grants, and what a website may offer other clients vs only the user viewing it.
Cross-cutting requirements
- Data model uniformity: data emitted by any provider lands in the same model (same typing, provenance, and access rules) regardless of origin target. Provenance records at minimum: provider identity, capability, grant under which it was obtained, and time.
- Security model: provider impersonation, rogue providers, malicious consumers probing declarations, bridge compromise (MQTT case), and capability confusion (a grant for one capability replayed against another) — each named with its mitigation or its accepted risk.
- Versioning & evolution: capability schemas evolve; consumers pinned to old versions; providers withdrawing a capability version — the compatibility story.
- Ceiling composition: every design element must state how it interacts with the ceiling model from id: Phase 13 F13.7 client-side capability providers under the ceiling model #789; any place the provider model would punch through a ceiling is a design bug to be caught here.
Non-goals
- Implementing providers for all five targets (design the model; prototypes / spikes only where the Decomposition sketch calls for them).
- Designing the MQTT bridge as a standalone product (only its provider-model surface is in scope).
- A general IoT device-management platform (provisioning fleets, OTA updates) beyond the identity / declaration hooks the provider model needs.
- Replacing the existing grant / ceiling machinery — this issue extends it client-side, per id: Phase 13 F13.7 client-side capability providers under the ceiling model #789.
Acceptance criteria for the design deliverable
- A design document covering declaration, discovery, negotiation, least-privilege grants, and offline / degraded behaviour as one model, linked from this issue.
- All five target classes instantiated from that model, with per-target differences listed and justified — no silent special cases.
- Grant model distinguishing observation vs actuation, with issuance / approval flows scaled by sensitivity.
- Offline behaviour specified per target class, including cached-grant and actuation-while-offline rules.
- Security analysis: impersonation, rogue providers, bridge compromise, capability confusion.
- Ceiling-model composition stated for each mechanism.
- Follow-on design tickets filed from the Decomposition sketch (or the sketch revised with reasons).
Decomposition sketch
Follow-on design tickets to be filed from this issue (indicative; revise during the work):
- Design: provider declaration model — manifest contents, signing, versioning, dynamic vs static capabilities.
- Design: discovery & negotiation protocols — visibility / minimisation rules, negotiation shape, stale-provider handling.
- Design: capability grants for providers — least-privilege scoping, observation vs actuation classes, approval flows by sensitivity, attenuation.
- Design: constrained-device providers — ESP32 + MQTT bridge instantiation, topic mapping, bridge trust, device identity / ceiling provisioning.
- Design: host providers — terminal (client and server modes) and website instantiations, sandbox and lifecycle rules.
- Design: embedded providers — Bevy engine integration and smartphone instantiation, OS-permission composition, session-bound lifecycles.
- Design: offline & degraded operation for providers — buffering, backfill, cached grants, per-class actuation rules.
- Design: provider security model — impersonation, rogue providers, capability confusion, and ceiling-composition audit.
Open questions
- Is a provider's identity its own first-class identity, the owner's identity, or a delegated / pseudo identity — and does the answer differ for a $5 sensor vs a phone?
- How much declaration verification is worth it: is an unverified-but-signed claim enough for v1, with attestation left as a later capability?
- Can negotiation be one protocol across an in-process Bevy plugin and a multi-hop MQTT bridge, or does the model need transport profiles — and where exactly is that line?
- What is the default discoverability of a new provider: invisible until granted, visible-but-metadata-minimised within its world, or visible to the server only?
- Actuation while offline under a standing grant: is there any target class where this is acceptable, and who is accountable for an action taken on a stale grant?
- When a provider is a website tab or a game session, do grants outlive it — and what does a consumer holding a grant to a dead provider experience?
- Does the MQTT bridge become a trusted central point that the rest of the model must route around, or is bridge trust acceptable if it is explicit and scoped per device?
Extension of #789. Framing per Drew: a huge part of the project — the core feature; one model across ESP32/MQTT, terminal, game engines (Bevy), smartphone, and web.
Activity
dezren39 commentedon Nov 5, 2026
Gap pass (WS-F, 2026-11-04): this issue's decomposition sketch is now filed.
Each follow-on design ticket named in the sketch above was filed as its own issue (label
app/id), so the acceptance item “Follow-on design tickets filed from the Decomposition sketch” can now be checked:Exception, where applicable: any sketch item already answered by a later filing is noted in the pass worklog rather than duplicated. Design prioritisation is now independent per ticket; implementation timing is a separate decision.
dezren39 commentedon Nov 5, 2026
Research widening (Drew's 2026-11-04 ruling: the split filings were not enough — the option space itself is its own task) is filed as #5931: a capability-provider field survey covering the current field per provider class (terminal, smartphone/Android, web/browser, Bevy/engine, ESP32/MQTT/IoT) plus the cross-cutting layer (MCP, WASI component model, Cap'n Proto/CapTP, UCAN/Biscuit/macaroon capability tokens, sandbox hosts), each mapped against this issue's provider model and the #5545 writer-set shape. It is an option-space inventory, not a decision: every section ends in open questions for the owning design issue. Headline field movements since this bundle was written: Android now has a first-party apps-as-providers layer (AppFunctions / 'Android MCP', beta Oct 2026), the web platform has one in draft (WebMCP, W3C CG), and MCP's 2026-07-28 spec revision went stateless. Dead/changed options are flagged in #5931 §7 (archived AgentAPI, EMQX's BSL license change, Rune on hold, ESPHome Matter experimental, wasmCloud's thinning maintainer bench).
dezren39 commentedon Nov 5, 2026
Cross-link from the 2026-11-04 worlds mega-brief decomposition: the capability threads of that brief are filed under tracking issue #5955 — capability model (requested vs discovered-used sets, registry, custom-compiled platforms) #5958, capability-change notices #5959, permission UX #5960, programming model (platform/context passed into pure libraries) #5963, and the OCAP/Goblins/OCapN prior-art research #5989 (coordinates with this issue's survey #5931: that one covers provider classes, this one covers capability theory/protocols). This parent and its splits remain the design homes for provider classes; #5955's children cover the world-facing capability/permission surface.
dezren39 commentedon Nov 5, 2026
Wave-2 tie-in from the worlds/capabilities brief program (#5955) — conversation archaeology findings F1, F6, F12.
ses_ef03b7d73ffewFUtEk0FCMTiz5(2026-10-06), which named ocap permissions, Spritely Goblins, Keyhive, capstd/UCAN/Cap'n Proto RPC, and Veilid as the survey seed. That list was Drew-endorsed at the origin — treat it as the seed set, not something to rediscover.ses_e90f034cfffeTlNBwA9y89gMS2) — the id: Phase 13 F13.3 SSH-over-iroh reachability (and iroh-over-SSH fallback) #785–id: Phase 13 F13.8 multi-server, multi-client topology; client-only mode always supported #790 design line is this issue's direct predecessor work.CapabilityProvidergrep overpkgs/id/srcreturns nothing), and Drew's recorded priority today is "id: Phase 13 F13.7 client-side capability providers under the ceiling model #789 capability providers are core." The 2026-11-04 brief's context/platform-passing design (#5963) depends on id: Phase 13 F13.7 client-side capability providers under the ceiling model #789 and files under this issue and #5931, not as a parallel effort.Record:
workspace/scratch/worlds-capabilities-brief-2026-11-04/conversation-tie-ins.md(F1, F6, F12).dezren39 commentedon Nov 5, 2026
🤖 Agent note · picked up
Agent: queue worker (repo-worker-code), lane bf419306-c4ef-470f-a553-beabf93239de
Session / ID: task 10119
Found via: queue claim
Task: triage issue #5686 against its current design decomposition.
Expectation: confirm whether the parent design and child issues already cover the scope; avoid creating duplicate follow-up work.
Links: #5686
dezren39 commentedon Nov 5, 2026
🤖 Agent note · triage findings
Agent: queue worker (repo-worker-code), lane bf419306-c4ef-470f-a553-beabf93239de
Session / ID: task 10119
Finding: #5686 remains OPEN; no matching PR was found. This is a design parent, not a code-fix request. Its decomposition is already filed: provider declaration, discovery/negotiation, grants, constrained-device, host, embedded, offline/degraded, and security design issues #5898–#5905, plus cross-cutting field survey #5931. Related worlds/capability work is tracked under #5955 and its child issues.
Disposition: route further work through the existing design issues; do not create duplicate child tasks or an implementation PR. The #5686 thread says design prioritisation is independent per ticket, so #5931 is useful cross-cutting input but is not an ordering blocker for every child. The earlier #789 reference is closed, but does not close or supersede the still-open #5686 design acceptance.
Evidence: fresh REST issue/PR checks at 2026-11-05T13:55:58Z; current child issue states were checked this run.
Links: #5686 · #5898 · #5931 · #5955