Reading copy of lichen.page.review: one PR per unit, product changes only

ONE-DOOR 4d: API errors are shaped once, at the boundary #27

targeting base/one-door-u4d from view/one-door-u4d
Closed opened by and assigned to notplants-bot.bsky.social
targeting base/one-door-u4d from view/one-door-u4d

API errors are shaped once, at the boundary, and never re-read or re-shaped by inner layers.

  • ApiError responses 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_site return ApiError too, 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 failures

    ApiError 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 crossing

    Validate 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 handlers

    Main 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 operations

    Git 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 text

    Unmarked 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.

Commits 0