feat(spec,core,runtime,docs)!: ADR-0112 batch 1 — one error-code vocabulary, SCREAMING_SNAKE, schema-enforced (#3841) - #3988
Merged
Conversation
…bulary, SCREAMING_SNAKE, schema-enforced (#3841) - Rename all 53 StandardErrorCode members to SCREAMING_SNAKE in place; HttpStatusErrorCodeMap (#3842's designated sweep point) follows, so derived wire codes change case (permission_denied -> PERMISSION_DENIED). - Add ERROR_CODE_LEDGER (spec/api/error-code-ledger.zod.ts): 130+ service codes registered per owning package, harvested from every non-test emitter; ErrorCode = StandardErrorCode ∪ registered. - Tighten ApiErrorSchema.code from z.string() to ErrorCode — the envelope conformance suites now assert values, not just shape. - Widen FieldErrorSchema.code to z.string() (ADR-0112 D6): field-level codes are a separate vocabulary; #3977 owns its catalog. - ANONYMOUS_DENY_CODE 'unauthenticated' -> 'UNAUTHENTICATED' (promoted into error.code on the dispatcher surface, so it must be catalogued). - Rewrite error-catalog.mdx to the two-tier model and lock its headings to the enum with a new spec test; update the error-handling guides. - Regenerate json-schema manifest, api-surface, docs references. Batches 2 (lowercase emitter sweep) and 3 remain per the ADR's Rollout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MaSQn77TT5fUgHK9CesaDK
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 4 package(s): 120 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…erived-code casing in api index Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MaSQn77TT5fUgHK9CesaDK
…casing Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MaSQn77TT5fUgHK9CesaDK
… ADR-0112 casing check:skill-refs and check:skill-examples gates — the skill reference index derives from spec schemas (new error-code-ledger page), and the prose-example compiler caught one remaining lowercase member literal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MaSQn77TT5fUgHK9CesaDK
os-zhuang
marked this pull request as ready for review
July 30, 2026 01:42
os-zhuang
pushed a commit
that referenced
this pull request
Jul 30, 2026
…nd refresh the console pin (#3843) Merging main brought in ADR-0112 batch 1 (#3841 (#3988)) and #3842, both of which landed while this PR was in review. Two of this PR's stated decisions were premised on #3841 being UNDECIDED, so they no longer hold. `ApiErrorSchema.code` is now the closed `ErrorCode` union, not `z.string()`, so the nine lowercase codes this PR deliberately carried over failed schema parse — which failed its own conformance suites (6 in service-datasource, 1 in service-settings). Re-spelled per ADR-0112, with generic conditions going to the STANDARD catalog rather than becoming registered synonyms of it, which is what the ledger asks for: datasource_admin_unavailable → SERVICE_UNAVAILABLE (standard) external_service_unavailable → SERVICE_UNAVAILABLE (standard) not_found / PACKAGE_NOT_FOUND → RESOURCE_NOT_FOUND (standard) PUBLISH_FIELDS_MISSING → MISSING_REQUIRED_FIELD (standard) INTERNAL → INTERNAL_ERROR (standard) datasource_admin_error → DATASOURCE_ADMIN_ERROR (registered) external_import_error → EXTERNAL_IMPORT_ERROR (registered) PUBLISH_MANIFEST_INVALID → PACKAGE_MANIFEST_INVALID (registered) PUBLISH_FAILED → PACKAGE_PUBLISH_FAILED (registered) PACKAGE_DELETE_PARTIAL / PACKAGE_DELETE_FAILED / SETTINGS_ACTION_FAILED Which service is unavailable is carried by `message` — the ledger explicitly asks generic conditions to reuse the catalog instead of registering a per-service 503. The seven registered codes go into ERROR_CODE_LEDGER under their owning packages, including a new @objectstack/service-datasource entry. Also bumps .objectui-sha a136322 → e651c93 now that objectui#2972 has merged, so the bundled Setup console carries the envelope tolerance this change needs. The pin only moves two commits because main had already refreshed it to a136322 — an earlier attempt from this branch's stale base would have swept in eleven unrelated frontend commits including two breaking ones. The route-envelope guard, the conformance suites and their doc comments are updated to match. Guard: 8 modules, 5 conformant / 2 ratcheted / 1 exempt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CYbS3kS8xzsHNXFTzp4e2z
This was referenced Jul 30, 2026
os-zhuang
pushed a commit
that referenced
this pull request
Jul 30, 2026
…nd refresh the console pin (#3843) Merging main brought in ADR-0112 batch 1 (#3841 (#3988)) and #3842, both of which landed while this PR was in review. Two of this PR's stated decisions were premised on #3841 being UNDECIDED, so they no longer hold. `ApiErrorSchema.code` is now the closed `ErrorCode` union, not `z.string()`, so the nine lowercase codes this PR deliberately carried over failed schema parse — which failed its own conformance suites (6 in service-datasource, 1 in service-settings). Re-spelled per ADR-0112, with generic conditions going to the STANDARD catalog rather than becoming registered synonyms of it, which is what the ledger asks for: datasource_admin_unavailable → SERVICE_UNAVAILABLE (standard) external_service_unavailable → SERVICE_UNAVAILABLE (standard) not_found / PACKAGE_NOT_FOUND → RESOURCE_NOT_FOUND (standard) PUBLISH_FIELDS_MISSING → MISSING_REQUIRED_FIELD (standard) INTERNAL → INTERNAL_ERROR (standard) datasource_admin_error → DATASOURCE_ADMIN_ERROR (registered) external_import_error → EXTERNAL_IMPORT_ERROR (registered) PUBLISH_MANIFEST_INVALID → PACKAGE_MANIFEST_INVALID (registered) PUBLISH_FAILED → PACKAGE_PUBLISH_FAILED (registered) PACKAGE_DELETE_PARTIAL / PACKAGE_DELETE_FAILED / SETTINGS_ACTION_FAILED Which service is unavailable is carried by `message` — the ledger explicitly asks generic conditions to reuse the catalog instead of registering a per-service 503. The seven registered codes go into ERROR_CODE_LEDGER under their owning packages, including a new @objectstack/service-datasource entry. Also bumps .objectui-sha a136322 → e651c93 now that objectui#2972 has merged, so the bundled Setup console carries the envelope tolerance this change needs. The pin only moves two commits because main had already refreshed it to a136322 — an earlier attempt from this branch's stale base would have swept in eleven unrelated frontend commits including two breaking ones. The route-envelope guard, the conformance suites and their doc comments are updated to match. Guard: 8 modules, 5 conformant / 2 ratcheted / 1 exempt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CYbS3kS8xzsHNXFTzp4e2z
This was referenced Jul 30, 2026
os-zhuang
added a commit
that referenced
this pull request
Jul 30, 2026
…ode vocabulary (#3843 follow-up) (#4009) Comment-only follow-up to #3972 (#3843). No behaviour change. Two sentences in package-envelope.conformance.test.ts's header were written while #3841 was still undecided, and #3843 landed after ADR-0112 settled it: - "why #3841 still owns the vocabulary" — it does not; ADR-0112 (#3988) closed it and ApiErrorSchema.code is a closed union now. - "this module needed MINTED codes" — half true. It had nothing to carry over (its `error` strings were human messages), but only four of the codes here are registered; the three generic conditions reuse the standard catalog, which is what the ledger asks for. Rewritten to state the actual split and why it makes the assertions below load-bearing: an unregistered code fails parse, so BaseResponseSchema.safeParse is what would catch an invented one. package-routes.ts already carried the corrected note; this was the test file missed beside it. Carries an empty changeset — the PR gate requires one, and this releases nothing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements batch 1 of ADR-0112's Rollout (settling #3841).
What
StandardErrorCode: all 53 members renamed in place to SCREAMING_SNAKE (validation_error→VALIDATION_ERROR), including The dispatcher puts the HTTP status inerror.codeand parks the real code indetails— pinned in #3687, still unfixed #3842's two new members (method_not_allowed→METHOD_NOT_ALLOWED,precondition_required→PRECONDITION_REQUIRED).ERROR_CODE_LEDGER(packages/spec/src/api/error-code-ledger.zod.ts, ADR-0112 D3): every SCREAMING code emitted anywhere inpackages/(harvested from all non-test emitters), registered under its owning package with admission rules test-enforced (error-code-ledger.test.ts: casing, per-package uniqueness, no shadowing of the standard catalog).ErrorCode= standard ∪ registered.ApiErrorSchema.code:z.string()→ErrorCode(D4). The fix(service-storage,service-i18n): emit the declared error envelope, not a bare{ error }(#3675) #3687/fix(service-storage): emit the declared success envelope on all eight routes (#3689) #3837/The dispatcher puts the HTTP status inerror.codeand parks the real code indetails— pinned in #3687, still unfixed #3842 conformance suites now assert code values with zero test changes — verified: service-storage (222), service-i18n (63), runtime (888) all green against the tightened schema.FieldErrorSchema.code: widened toz.string()with a banner pointing at Field-level error codes are four vocabularies with no schema — needs its own catalog (ADR-0112 D6 follow-up) #3977 (D6) — field-level codes are a separate vocabulary the enum never described.ANONYMOUS_DENY_CODE:'unauthenticated'→'UNAUTHENTICATED'— The dispatcher puts the HTTP status inerror.codeand parks the real code indetails— pinned in #3687, still unfixed #3842 promotes it intoerror.codeon dispatcher surfaces, so it must be catalogued for the tightened schema to hold. The RESTenforceAuthflat body changes spelling with it.error-catalog.mdxrewritten to the two-tier model, all four error-handling guides moved to the single vocabulary; generated references/manifest/api-surface regenerated.Interplay with #3842 (landed mid-flight)
#3842 moved the semantic code into
error.codeand leftHttpStatusErrorCodeMapas the deliberate one-file sweep point for this decision ("#3841 owns reconciling the two"). This PR is that sweep: derived codes change case on the wire (permission_denied→PERMISSION_DENIED, etc.). Per the batch-1 consumer check (and the ADR's harvest), no in-repo consumer branches on the lowercase spellings; every existing consumer branch (console attachment panel, dogfood suite, client tests) reads codes this PR leaves byte-identical.Deviations from the ADR letter (recorded)
error-catalog-docs.test.ts) locks its headings 1:1 to the enum instead of full generation — the drift-proofing without losing the prose. The schema-level reference (references/api/errors.mdx) remains fully generated.//one-liners only where the name doesn't speak for itself, rather than a mandatory summary field.Test evidence
Follow-ups (not this PR)
error:-position code strings found in the harvest (4b).error.typeas a code carrier where left, delete the client's multi-location probe, fix the client'scategory/retryablenesting read, dedupe the connector-sideErrorCategory/RetryStrategytwins.Closes #3841.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MaSQn77TT5fUgHK9CesaDK
Generated by Claude Code