Appendices
Appendix A — Error code registry
Section titled “Appendix A — Error code registry”Wire (R5): PARSE_FAILED · THREAD_CONFLICT · NETWORK_ERROR · RESET_FAILED ·
CANCELLED · SUPERSEDED · UNSUPPORTED_VERSION · CONSENT_REQUIRED (reserved) ·
AUTH_REQUIRED (reserved) · HOST_ERROR. (MALFORMED is R1’s wire answer to an
unparseable frame, not a member of this list.)
Net capability: NET_INVALID_REQUEST · NET_NOT_APPROVED ·
NET_IMPORTED_UNAPPROVED · NET_AMBIGUOUS_CONNECTION · NET_SCHEME_BLOCKED ·
NET_HOST_BLOCKED · NET_SSRF_BLOCKED · NET_CONFIRM_DENIED · NET_REDIRECT_BLOCKED ·
NET_SIZE_EXCEEDED · NET_FETCH_FAILED · NET_AUTH_FAILED ·
NET_SCRUBBED_HEADER_STRIPPED (reserved).
Appendix B — Normative constants
Section titled “Appendix B — Normative constants”| Constant | Value |
|---|---|
PROTOCOL_VERSION | 1 |
SNUG_APP_REQUEST_TAG | [SNUG_APP_REQUEST] |
CDN_ALLOWLIST | cdn.jsdelivr.net · cdnjs.cloudflare.com · unpkg.com |
MAX_FRAME_BYTES | 256 KiB (262 144) |
MAX_DB_FRAME_BYTES | 8 MiB (8 388 608) |
MAX_NET_FRAME_BYTES | 1 MiB + 64 KiB (1 114 112) |
MAX_NET_REQUEST_BODY_BYTES | 256 KiB |
MAX_NET_RESPONSE_BODY_BYTES | 1 MiB |
MAX_ARTIFACT_BYTES | 5 MiB |
RAW_EXCERPT_CHARS | 200 chars |
MAX_PARSE_FAILURES | 3 consecutive |
THREAD_CONFLICT_BACKOFF_MS | 100/250/500 ms |
| announce caps | displayName 80 · description 400 · iconEmoji 8 · iconColor 32 |
| id/action caps | 128 |
STRIP_HEADERS | authorization · cookie · set-cookie · x-api-key · proxy-authorization |
NET_METHODS / mutating | GET HEAD POST PUT PATCH DELETE / POST PUT PATCH DELETE |
| net response-header whitelist | content-type · content-length · cache-control · etag · last-modified · retry-after · link · x-ratelimit-* |
MAX_USERDB_BYTES | 64 MiB |
USERDB_SCHEMA_VERSION | 6 |
VERSIONS_RETAINED | 5 |
USERDB_FILE / legacy | user.snug / user.sqlite |
CONTAINER.MAGIC / KDF / iterations | SNUGENC1\n / PBKDF2-HMAC-SHA256 / 600,000 |
AUTH_MAX_SLOTS_PER_APP | 8 |
| requirement bounds | fields 8 · instructions 10×300 · header entries 8×300 · query entries 8×300 · urls 300 · label 80 · description 200 · placeholder 60 · testRequest path 200 · provider name 120 · hosts 32×253 · scopes 64×200 |
RUNTIME_CONTRACT_MAX_BYTES | 2560 |
| data-lane result bounds | 200 rows / 32 KiB |
| helper token entropy | ≥256 bits |
Appendix C — Published schemas and publication lines
Section titled “Appendix C — Published schemas and publication lines”Fourteen schema files are published, byte-identical from packages/protocol
(io: 'input' for the tolerant set):
app-announce · app-cancel · app-event · app-message · app-request-envelope ·
app-response · db-request · db-response · host-event · host-ready ·
net-request · net-response · open-url-request · open-url-result.
Two publication-line facts, decided at v0.3 (owner ask 2026-08-20):
- The strict pairs publish strict.
net-*andopen-url-*schemas carryadditionalProperties: false— that IS their contract (§2, R2’s stated exception). Their superRefine rules (body-on-GET refusal, credential-header refusal, https-only + userinfo-free URLs) are not expressible in JSON Schema; this prose is normative for them, and the exported schema is deliberately the weaker envelope, never the full contract. A validator passing the schema has not yet validated the frame. - The Part III–V contracts publish as prose, not as JSON Schemas. The connection-requirement, connection-url, chat-intent, runtime-contract and sidecar-contract shapes carry refinements JSON Schema cannot express (the host XOR, the per-kind coherence arms, canonicalization, derived route subsets). Exporting a schema weaker than the real contract would invite implementations that validate against the export and admit what the contract refuses — so none is offered. This specification’s prose is normative for those surfaces, the reference implementation’s contract files are the machine-readable authority, and in-package tests lock them.