# Bounded Bridge
Crosswake exposes one typed, versioned, request/reply-only bridge. It stays deliberately
small even after Phase 5, and its public framing is family-first rather than
command-first:
- `app.info.get`
- `haptics.impact`
- `permissions.status`
- `files.pick`
- `transfer.download`
- `transfer.export`
- `transfer.import`
- `transfer.upload.prepare`
The public families behind that posture are `app_info`, `haptics`, `permissions.status`, and, later,
`share`. This bounded bridge contract stays family-first. Concrete bridge commands remain lower-level protocol details. Everything
else is denied. The bridge is not navigation authority, not render synchronization,
and not a generic plugin bus. `deep_link` remains manifest-first shell activation truth, not route-local bridge or navigation authority.
## Request Envelope
Every request carries:
- `protocol`: `crosswake.bridge`
- `version`: bridge protocol version
- `command`: one of the bounded commands above
- `capability`: must match the command's manifest-backed capability id
- `route_id`: requested route identity
- `active_route_id`: current active route identity
- `origin`: caller origin
- `native_runtime_version`: shipped shell runtime version
- `correlation_id`: request/reply correlation id
- `capabilities`: capability versions available in the shell
- `installed_packs`: installed pack versions available in the shell
- `payload`: command payload
## Enforcement
Before any side effect runs, Crosswake checks:
- The active route matches `route_id`
- The route exists in the manifest
- The origin is allowlisted for the route
- The bridge protocol and native runtime versions are compatible
- The command is in the bounded Phase 3 allowlist
- The route declares the capability
- The manifest capability registry provides the capability version
- The shell exposes that capability version
- The route's declared packs are compatible with the shell
If any check fails, Crosswake returns a typed denial reply and executes no side effect.
## Transfer Boundary
The transfer commands stay semantic and route-local.
- `transfer.import` means the route explicitly asked to import user-chosen media or files.
- `transfer.export` means the route explicitly asked to hand owned content out.
- `transfer.download` means the route explicitly asked for a download seam.
- `transfer.upload.prepare` means staged local media is ready to enter a foreground-first upload path.
Transfer execution is foreground-first. States remain explicit: `queued`, `preparing`,
`transferring`, `awaiting_network`, `verifying`, `complete`, `failed`, and `canceled`.
Crosswake does not promise silent background reconciliation or generic file authority.
The bridge examples that remain honest in this posture are family-first:
- `app_info` for one-shot app metadata reads
- `haptics` for low-frequency confirmation signals
- `permissions.status` for one-shot prerequisite checks scoped to the `notifications` alias only
- `share` as a future semantic handoff family once Crosswake publishes a truthful
route-local share contract beyond compatibility-only command seams
## Denial Reasons
Bridge denials reuse the shared shell denial vocabulary:
- `compatibility_mismatch`
- `undeclared_capability`
- `unavailable_capability`
- `origin_denied`
- `inactive_route`
- `pack_incompatible`
## Reply Shape
Successful replies return:
- `protocol`
- `version`
- `command`
- `route_id`
- `correlation_id`
- `status: "ok"`
- `payload`
Denied replies return the same fields with `status: "deny"` plus a nested typed denial payload containing the stable reason, code, message, route id, and optional hint.