API errors are shaped once, at the boundary, and never re-read or re-shaped by inner layers.
ApiErrorresponses carry an in-process marker; a JSON content type alone no longer bypasses shaping. Unexpected untyped server errors get the canonical public message, and storage-full guidance is exempt.- Error JSON from the site process is validated before the marker is restored: extra fields, malformed codes, oversized bodies and private unexpected server messages are rejected; accepted codes, storage guidance and headers are kept. Unmarked JSON errors are canonicalized, storage-full envelopes keep only the defined recovery message, and forged guidance falls back to it. The inner CMS shaper is removed for composed routers and kept for a standalone CMS.
- The main dashboard API handlers return
ApiError. Shared tuple conversion preserves public client refusal text, redacts unexpected server details and gives 507 the fixed storage recovery guidance; buffered legacy responses use the same conversion. - Git API handlers and
admitted_sitereturnApiErrortoo, redacting internal push and transport details; the deliberate missing-remote setup instruction stays a typed public message.
ONE-DOOR, subunit 4d. Plan: https://tangled.org/notplants-bot.bsky.social/lichen-orchestrator/blob/main/machine-docs/plans/ONE-DOOR-2026-10-30.md
This is a reading copy: only this subunit's product changes, applied in order on its base. Nothing here is to be merged.
Source PRs on lichen.page.review (product), in order, with their original descriptions #
-
#3567
s/939-od-u4d-shape-product— mark shaped API errors and redact untyped server failuresApiError responses carry an in-process marker so repeated boundary layers do not read or reshape them. A JSON content type alone no longer bypasses shaping. Unexpected untyped server errors receive the canonical public message; storage-full guidance remains exempt. Wire-boundary validation and layer consolidation follow in the next part.
-
#3569
s/941-od-u4d-wire-product— validate site error envelopes at the process crossingValidate bounded error JSON from the site process before restoring the shaped-error marker. Reject extra fields, malformed codes, oversized bodies and private unexpected server messages; preserve accepted codes, storage guidance and headers. Remove the inner CMS shaper for composed routers while retaining it for standalone CMS construction.
-
#3571
s/943-od-u4d-handlers-product— return typed errors from front server API handlersMain dashboard API handlers return the existing ApiError. Shared tuple conversion preserves public client refusal text, redacts unexpected server details and gives 507 the fixed storage recovery guidance. Buffered legacy responses reuse the same conversion. Git-specific handlers and the compatibility admitted-site helper follow separately.
-
#3573
s/945-od-u4d-git-errors-product— use typed errors for dashboard git operationsGit API handlers and admitted_site return ApiError, using shared conversion for upstream refusals. Internal push and transport details are redacted; the deliberate missing-remote setup instruction remains a typed public message.
-
#3575
s/947-od-u4d-privacy-product— refuse untrusted JSON and forged storage error textUnmarked JSON errors are canonicalized rather than copied into a public message. At the process crossing, storage-full envelopes retain only the defined recovery message; forged guidance falls back to that safe message. Typed in-process errors remain unchanged.
Commits #
- bf95b232f OD 4d: od-u4d-shape-product (#3567)
- de683fd3f OD 4d: od-u4d-wire-product (#3569)
- 2beb2bf9d OD 4d: od-u4d-handlers-product (#3571)
- 5ea636d08 OD 4d: od-u4d-git-errors-product (#3573)
- 400db8432 OD 4d: od-u4d-privacy-product (#3575)
Count and shas #
count-product-code-lines c6bd2b5b14bd..400db843293f: NET +87 · counted +144 -57 · moved out of the counted set +0 · comment-only deletions flagged 2 · macros flagged 0 · tests-folder code flagged 0
Base c6bd2b5b14bd81dda051267ecac45be741cb404b (tip of s/938-od-u4c-rotation-tests). Head 400db843293f514479b4d079bdbbb81061c2625f. 6 files changed.
Check #
Every changed file is a file one of the product PRs changed, and each is identical at the head to the same file at the last product branch s/947-od-u4d-privacy-product.