feat(settings): give SETTINGS_CRYPTO_UNAVAILABLE a wire spelling - #8396
Conversation
Register the code in ERROR_CODE_LEDGER under @objectstack/service-settings,
map SettingsCryptoUnavailableError in settings-routes.ts's PUT handler to
500 SETTINGS_CRYPTO_UNAVAILABLE with details { namespace, key }, and re-point
the #8026 wire refusal pin to assert both code and status. Status stays 500
per the PM ruling: server misconfiguration, deliberately not 503 (no retry
succeeds until an operator wires a cryptoProvider).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Euoy6wyfzgiWtgCg4s6JK2
gen:docs via check:generated --fix — the one artifact it proved stale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoy6wyfzgiWtgCg4s6JK2
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 108 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
Fixes #8273
The #8026 fail-closed settings refusal (a declared-encrypted value refused when nothing able to encrypt it is wired) answered over REST on the generic
500 INTERNAL_ERRORarm, so a client could not distinguish "the deployment cannot encrypt secrets, reconfigure it" from "the server crashed". Every siblingSETTINGS_*error class already had a registered wire code; this one was the odd one out.What changed
packages/spec/src/api/error-code-ledger.zod.ts):SETTINGS_CRYPTO_UNAVAILABLEregistered under@objectstack/service-settings, alphabetized with the otherSETTINGS_*rows, comment carrying the 500-not-503 rationale and the operator fix (ADR-0112: no silent fourth state).settings-routes.tsPUT handler):SettingsCryptoUnavailableErrornow answers500 SETTINGS_CRYPTO_UNAVAILABLEwithdetails: { namespace, key }— the located refusal, never the value. Mirrors the siblingSETTINGS_*mappings; the generic arm keeps catching everything else.cryptoProvider, so inviting one would be dishonest. The registered code carries the meaning; the status stays honest. Implementation surfaced no reason to prefer 503 (the ledger carries no status/retry-semantics contract on 5xx rows; statuses live at the mapping sites).settings-crypto-fail-closed.test.ts"the refusal on the REST boundary"): now asserts BOTHcode: 'SETTINGS_CRYPTO_UNAVAILABLE'ANDstatus: 500on the wire envelope, plusdetails, the operator's fix in the message, the no-secret-leak check and the nothing-persisted check.check:generated --fix(onlygen:docswas stale: the new code in the ledger reference, envelope enum count 264 to 265).SettingsCryptoUnavailableError(settings-service.types.ts): the "Wire spelling" section said "not mapped, registration out of scope" — updated to describe the shipped mapping. One doc-comment-only edit beyond the dispatched file surface, made so the class does not document the pre-SETTINGS_CRYPTO_UNAVAILABLEhas no wire spelling — the fail-closed settings refusal answers a generic 500 a client cannot branch on #8273 behavior as current.@objectstack/spec+@objectstack/service-settings. Additive wire refinement, not breaking — no ADR-0087 disposition needed (gate green).Verification
@objectstack/spectests: 389 files / 10325 passed.@objectstack/service-settings: 23 files / 451 passed +tsc --noEmitclean.@objectstack/rest(downstream envelope path): 110 files / 1817 passed.SETTINGS_CRYPTO_UNAVAILABLE_Xin the handler failstscwithnot assignable to parameter of type 'ErrorCode'— proving the consumer reads the rebuilt spec.d.ts; restored from the branch.check:generatedall 13 green (docs regenerated),check:error-code-casing,check:route-envelope,check:nul-bytes,check:adr-anchors,check:i18n,check:merge-driver,check:adr-0087-registration, changeset gates, and the full re-derived family list fromdispatch-gates.mjs— all pass locally.Out of scope, as dispatched: the Setup UI consumer branch (objectui) is untouched; rendering on the new code is filed as objectstack-ai/objectui#4570.
Generated by Claude Code