# ADR 0086: Lifecycle composition is explicit and ordered

> Source: https://github.com/max-listov/stitchkit/blob/master/docs/decisions/0086-lifecycle-composition-is-explicit.md

---

# ADR 0086 — Lifecycle composition is explicit and ordered

## Context

Applications repeatedly assembled `auth → policy → audit identity` chains. Flat
hooks remain the correct execution model, but hand-written forwarding duplicated
ordering, fallthrough and result-transform semantics.

## Decision

`composeLifecycleHooks(...hooks)` and `composeToolLifecycle(...hooks)` compose
the existing phase interfaces. Request/authorization/before phases run in
declaration order. A returned `Response` short-circuits `onRequest`; `onError`
continues until one hook returns a `Response`. Result transforms feed the current
value to the next hook, and `undefined` preserves it. A throw stops the chain and
is handled by the existing outer error boundary. The same context and
`AbortSignal` object is passed through unchanged.

The composers install no policy, catch no domain errors, and introduce no
middleware engine.

## Consequences

- Applications declare policy order once and keep each rule independently
  testable.
- Existing lifecycle error and observability ownership is unchanged.
- HTTP and tool composers stay separate because their phase contracts differ.
