# 4. Zero runtime dependencies

**Status:** Accepted · 2025

## Context

`package.json` dependencies are a long-term liability: each one is a
supply-chain attack surface, a breaking-change source, and a peer-dep
compatibility puzzle. For a CLI tool that installs itself into user shells
and runs with write access to `~/.claude/` and `~/.copilot/`, the blast
radius of a compromised dependency is large.

At the same time, some conveniences - JSON Schema validators (`ajv`), YAML
parsers (`yaml`), templating engines - would be trivial to pull in and would
shorten a few scripts.

## Decision

`@mmerterden/multi-agent-pipeline` ships with **zero runtime dependencies**.
Devs can add dev dependencies freely (ESLint, Prettier, c8), but the
published package (the `pipeline/` tree, `install.js`, `index.js`) must
import only from Node.js core modules.

Consequences:

- `validate-triage.mjs`, `validate-{reviewer,analysis,planning}.mjs`,
  `write-state.mjs`, `migrate-state.mjs` all hand-roll their JSON Schema
  validation. Slower to write, but zero attack surface.
- `validate-schemas.mjs` is a shallow checker - catches "the schema file is
  itself malformed", doesn't deep-validate every instance. That's what the
  runtime validators are for.
- Install is fast: `npm install` against the published package is a single
  tarball, no transitive resolution.

## Consequences

Positive:

- No supply-chain surface in the published package.
- No Node version interop headaches - Node 18+ core APIs are stable enough.
- `npx @mmerterden/multi-agent-pipeline install` runs instantly from cold.

Negative:

- Some scripts are longer than they'd be with a library.
- Hand-rolled validators can drift from the JSON Schema they claim to enforce.
  Mitigated by smoke tests: each validator has a matching `smoke-*.sh` with
  ≥10 assertions covering the enum / edge paths.
- Adding a new validator requires writing the boilerplate by hand.

## Alternatives Considered

**Pull in `ajv` for real schema validation:** clean and standard. Rejected
because of supply-chain surface + bundle bloat (adds ~200 kB gzipped).

**Optional deps - use `ajv` if installed, fall back otherwise:** too clever.
"Sometimes validated, sometimes not" is worse than either extreme.

**Bundle dependencies into the published tarball:** would remove the install-
time resolution but keep the code surface. Defeats the point.
