01 · Accumulation and discharge
Failure ownership follows the component tree.
Expected failures are part of the contract. Unexpected exceptions are not. Procedures return anticipated failures as tagged values. Unexpected server exceptions are reported through server-only observability with their private cause and exposed to the client only as a sanitized server/internal failure.
Procedure and middleware failures accumulate with server and client boundary failures to form the operation's closed union.
A shell claims tags at a position in the React tree. Shells form an explicit parent chain, so a derived shell carries every claim made above it. Its hooks subtract those tags, leaving the component with only its remaining failures; unclaimed failures stay in the union and must be handled.
How shells claim failures →// SERVER — the layer proves write access
const rename = server.procedure()
.use(requireWriteAccess)
// context.writer + WriteAccessRequired
.errors({ DocLocked })
.mutation(({ context, input }) =>
context.docs.rename(input, context.writer))
// REACT — the shell owns the access failure
const rename = WriteAccessShell.useMutation(
client.doc.rename,
)
// this component handles DocLocked