Skip to content

design(id): client-side capability providers — one provider model for ESP32/MQTT, terminal, Bevy, smartphone, and web #5686

Open

Description

@dezren39

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.

  1. 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.
  2. 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.
  3. 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).
  4. Smartphone — OS permission systems (location, sensors, notifications) composed with id grants: two gates, both must pass; background execution limits; provider lifecycle tied to app state; battery-aware rates.
  5. 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):

  1. Design: provider declaration model — manifest contents, signing, versioning, dynamic vs static capabilities.
  2. Design: discovery & negotiation protocols — visibility / minimisation rules, negotiation shape, stale-provider handling.
  3. Design: capability grants for providers — least-privilege scoping, observation vs actuation classes, approval flows by sensitivity, attenuation.
  4. Design: constrained-device providers — ESP32 + MQTT bridge instantiation, topic mapping, bridge trust, device identity / ceiling provisioning.
  5. Design: host providers — terminal (client and server modes) and website instantiations, sandbox and lifecycle rules.
  6. Design: embedded providers — Bevy engine integration and smartphone instantiation, OS-permission composition, session-bound lifecycles.
  7. Design: offline & degraded operation for providers — buffering, backfill, cached grants, per-class actuation rules.
  8. 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

  1. added
    priority/normalOrdinary priority (the default)
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/lLarge: multi-day or open-ended; expect staged check-ins
    mode/onlineFully doable remotely: design, config, code, cloud
    kind/designA design proposal (design-architect): multi-step, phased, decision-bearing
    on Nov 4, 2026
  2. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    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.

  3. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    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).

  4. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    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.

  5. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    Wave-2 tie-in from the worlds/capabilities brief program (#5955) — conversation archaeology findings F1, F6, F12.

    Record: workspace/scratch/worlds-capabilities-brief-2026-11-04/conversation-tie-ins.md (F1, F6, F12).

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 5, 2026
  7. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 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

  8. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/lLarge: multi-day or open-ended; expect staged check-inskind/designA design proposal (design-architect): multi-step, phased, decision-bearingmode/onlineFully doable remotely: design, config, code, cloudpriority/normalOrdinary priority (the default)source/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions