# Device capability API

Status: engineering draft

## Rule

A hardware or software feature is not complete until another program can:

1. discover it;
2. read its availability and power cost;
3. inspect its input/output schema;
4. invoke or subscribe to it;
5. receive deterministic errors;
6. reproduce the operation in a simulator.

## Common operations

- `capability.list()` — descriptors for every built-in and PhoneBus feature.
- `capability.get(id)` — one descriptor and live availability.
- `capability.state(id)` — cached state; MUST NOT wake expensive hardware unless requested.
- `capability.invoke(id, operation, input, budget)` — explicit operation.
- `capability.subscribe(id, event, policy)` — event stream with rate and energy limits.

## Transport profile

The semantic contract is transport-independent. Initial mappings:

- local firmware: compact CBOR RPC;
- USB debug/automation: newline-delimited JSON RPC;
- LAN/backend: HTTPS + WebSocket events;
- constrained mesh: capability-specific CBOR envelopes, never transparent arbitrary RPC.

## Required descriptor fields

`id`, semantic version, kind, availability, power class, permissions, operation schemas, timeout, stable errors.

## Capability families

- `display.eink`: render card, partial refresh, full refresh, set ambient page.
- `input.ano`, `input.tail`, `input.voice`: state and events.
- `audio.capture`, `audio.playback`: framed streams and levels.
- `camera.frame`: still capture only in V1.
- `light.work`, `light.rgb`: level, color, thermal state.
- `power.battery`, `power.charge`, `power.solar`: telemetry and policies.
- `gnss.position`, `map.cache`: cached location and offline map assets.
- `radio.lte`, `radio.wifi`, `radio.ble`, `radio.lora`: status and bounded operations.
- `message.inbox`, `feed.rss`, `call.sip`: simple communication surfaces.
- `storage.file`: sandboxed artifacts and logs.
- `phonebus.slot.*`: enumeration, descriptor, power gate and module operations.

## Power-aware invocation

Every request may carry:

```json
{"deadline_ms": 3000, "energy": "low", "allow_radio_wake": false}
```

The runtime MUST reject an impossible request with `energy_budget_exceeded`; it MUST NOT silently switch to an expensive mode.

## Error vocabulary

`capability_missing`, `capability_offline`, `degraded`, `invalid_input`, `permission_denied`, `busy`, `timeout`, `energy_budget_exceeded`, `radio_unavailable`, `storage_full`, `not_supported`.

## Example

See [capabilities.example.json](./capabilities.example.json) and validate it with [capability.schema.json](./capability.schema.json).
