Compose Pipeline

Order-aware middleware composer. Replaces the per-project pattern of N separate app.use(mw) calls — where mount order silently matters (apiEncrypt must precede body-parser; body-parser must precede idempotency-key + csrf; csrf must precede require-auth) — with a single declarative pipeline that documents the order + detects conflicts at registration time.

## What this primitive owns

- **Single mount point**: one app.use(pipeline) instead of N. - **Order documented in code**: the entry array IS the order; reading the registration tells the reviewer the canonical order without grepping app.use calls. - **Conflict detection at registration**: duplicate names refused; duplicate explicit positions refused; non-monotonic positions refused (a later entry with a smaller position is a mis-registration). - **Canonical-position warnings**: when an entry's name matches a known framework primitive's recommended position (apiEncrypt → 10, bodyParser → 20, csrf → 30, idempotency → 30, rateLimit → 40, requireAuth → 50, handler → 60, errorHandler → 90), the composer emits an system.middleware.compose.canonical_mismatch audit at warning when the operator-supplied order deviates. Refusal is opt-in via opts.strict: true; default is warn-and-continue so operators with intentional non-canonical ordering aren't blocked.

## What this primitive does NOT own

- **The middlewares themselves** — the composer is a sequencer, not a registry. Each middleware retains its own b.middleware.X(opts) factory + behavior. - **Async-context propagation** — async middleware works (the composer awaits the previous next() via Promise wrap), but primitives that need AsyncLocalStorage should attach it at the middleware itself, not the composer. - **Error handling** — the composer dispatches through next(err) in the standard way; operators register a tail error-handler (name: "errorHandler") for the canonical position 90 slot.

## Audit

Each composed pipeline is registered at boot time with a unique pipelineId (sha3-512 of the sorted entry names) and emits a system.middleware.compose.pipeline_built audit with the entry list and canonical-mismatch flags. Per-request dispatch is NOT audited (would blow up the audit pipeline volume) — composers that need per-request observability compose b.observability inside their own middleware.

b.middleware.composePipeline(entries, opts?) #

stable0.9.43
{
  strict:  boolean,    // refuse on canonical-position mismatch (default false: warn-and-continue)
  name:    string,     // optional pipeline name for audit
}

Compose an ordered middleware pipeline into a single Express-shaped middleware. Each entries[i] is { name: string, mw: function, position?: number }. Returns the composed (req, res, next) => void middleware. Throws at registration time on duplicate names, duplicate positions, non-monotonic positions, or (with strict) canonical-position mismatches.

var pipeline = b.middleware.composePipeline([
  { name: "apiEncrypt", mw: apiEncryptMw },
  { name: "bodyParser", mw: bodyParserMw },
  { name: "csrf",       mw: csrfMw },
  { name: "idempotency", mw: idempotencyMw, position: 35 },
  { name: "requireAuth", mw: requireAuthMw },
]);
app.use(pipeline);

Last updated 2026-08-08T16:39:49.652Z by seeder.