Skip to content

Commit d31e4cb

Browse files
committed
docs(error-catalog): add README with index + contribution checklist
Makes the directory self-documenting for first-time contributors: - One-line index of all 9 catalog entries with HTTP status and trigger - 4-step recipe for adding a new error code when the spec grows - Filename convention note (UPPER_SNAKE for files, lower_snake for URLs) - Source-of-truth declaration: spec is canon, website is downstream No content changes to the existing catalog files.
1 parent 017a632 commit d31e4cb

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

spec/error-catalog/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Error catalog
2+
3+
Each file in this directory documents one JECP error code. Hub-emitted error envelopes include `error.details.documentation_url` deep-linking to a rendered version of the matching file at `https://jecp.dev/errors/<lowercase-code>` (with optional `#anchor` for sub-categorized codes).
4+
5+
These pages are the canonical source. The public website at jecp.dev is downstream — when the spec and the website disagree, the spec wins.
6+
7+
## Index
8+
9+
| File | HTTP status | When it fires |
10+
|---|---|---|
11+
| [`CAPABILITY_DEPRECATED.md`](CAPABILITY_DEPRECATED.md) | 410 | Capability past sunset date. `details.successor` names the replacement when one exists. |
12+
| [`DUPLICATE_REQUEST.md`](DUPLICATE_REQUEST.md) | 409 | The idempotency `id` was reused for a different request body. |
13+
| [`INPUT_SCHEMA_VIOLATION.md`](INPUT_SCHEMA_VIOLATION.md) | 400 | Action input failed the capability's published JSON Schema. `details.errors[]` enumerates each failed assertion. |
14+
| [`INSUFFICIENT_BALANCE.md`](INSUFFICIENT_BALANCE.md) | 402 | Agent's wallet balance is below the action's quoted price. |
15+
| [`INSUFFICIENT_BUDGET.md`](INSUFFICIENT_BUDGET.md) | 402 | `mandate.budget` cap was below the action's quoted price even though the wallet has funds. |
16+
| [`PROVENANCE_MISMATCH.md`](PROVENANCE_MISMATCH.md) | 403 | `mandate.provenance_hash` failed verification. Six subcause anchors (`wire_malformed`, `clock_skew`, `hmac_mismatch`, `nonce_replay`, `v1_legacy_mismatch`, `v1_unavailable`). |
17+
| [`RATE_LIMITED.md`](RATE_LIMITED.md) | 429 | Agent or source IP exceeded the per-window quota. `details.retry_after_seconds` mirrors the `Retry-After` header. |
18+
| [`UNSUPPORTED_MEDIA_TYPE.md`](UNSUPPORTED_MEDIA_TYPE.md) | 415 | Request `Content-Type` was not `application/json`. |
19+
| [`URL_BLOCKED_SSRF.md`](URL_BLOCKED_SSRF.md) | 422 | Agent-controlled URL hit the SSRF deny-list. Six reason anchors (`parse_error`, `scheme`, `host_syntax`, `resolved_to_deny_cidr`, `dns_resolve_failed`, `connect_pin_violation`). |
20+
21+
## Adding a new error code
22+
23+
When the spec adds a new error code:
24+
25+
1. Define the code, HTTP status, and any structured `details` fields in `spec/03-errors.md`.
26+
2. Add a catalog file here. Follow the structure used by the existing files:
27+
- Header `# \`CODE_NAME\``
28+
- Frontmatter quote block: public URL, spec source pointer, last-updated date.
29+
- **What it means** — one paragraph, HTTP status, and when the error fires.
30+
- **Response envelope** — a concrete JSON example.
31+
- **Fix in 30s** — concrete recovery action(s).
32+
- **Why the Hub …** — design rationale (helps operators predict behavior).
33+
- **Related errors** — cross-links to adjacent codes.
34+
3. If the code has sub-categories (a closed-registry `subcause` or `reason` field), include an anchored section per value so the deep-link form `https://jecp.dev/errors/<code>#<sub>` lands at the right row.
35+
4. Mirror the entry on the public website at `jecpdev/website/errors/<code>.html` for browser-readable rendering.
36+
37+
## File naming
38+
39+
Filenames use `UPPER_SNAKE_CASE.md` — matching the code itself. The website route uses `lower_snake_case` for the public URL (so `URL_BLOCKED_SSRF.md` is mirrored at `https://jecp.dev/errors/url_blocked_ssrf`). This split is intentional: the catalog file mirrors the wire constant; the URL mirrors web convention.

0 commit comments

Comments
 (0)