Appearance
ADR-0006: Accept yaml@^2.8 as First Runtime Dependency (Amendment to ADR-0002)
- Status: Accepted
- Date: 2026-04-15
- Supersedes: None
- Amends: ADR-0002
Context and Problem Statement
Phase 4 introduces .nubos-pilot/roadmap.yaml as the canonical source-of-truth for roadmap data. The schema contains nested sequences, mixed scalar types, and per-phase plans sub-objects that go well beyond what a hand-rolled regex parser can robustly handle. lib/frontmatter.cjs (the hand-rolled parser) already hits its design ceiling on Task-Frontmatter multiline sequences — extending it further to parse the full roadmap YAML would reimplement a real YAML 1.2 parser in-repo, which is strictly worse than vendoring a 50KB battle-tested library.
ADR-0002 §"Escape hatch for future exceptions" explicitly foresees this: "if a concrete future feature genuinely requires a runtime dep that builtins cannot satisfy, the exception is introduced by a new ADR […] that either supersedes ADR-0002 wholesale or amends it narrowly with a name-scoped exemption." This ADR is the first exercise of that escape hatch.
Scope
- This amendment permits EXACTLY ONE additional runtime dependency:
yaml@^2.8. package.json.dependenciesis limited to{"yaml": "^2.8.0"}— no other key permitted.- No further runtime deps may be added without a new ADR amendment that either supersedes ADR-0002 again, or amends it with a second narrowly-scoped exemption.
devDependenciesremain unconstrained by this amendment.
Decision Drivers
- Concrete need —
roadmap.yamlships nested sequences (milestones → phases → plans) that the hand-rolled regex parser cannot express. - Pre-sanctioned by CLAUDE.md — the project's tech-stack document explicitly identifies
yaml@^2.8as the acceptable escape-hatch dependency. - Install-footprint minimal —
yaml@^2.8has zero transitive dependencies and ships ~50KB of JS. - Type safety —
YAML.parseyields typed scalars (number, string, boolean, null, arrays of same). - Round-trip support — supports CST-preserving
YAML.parseDocumentfor future phases that need to edit YAML while preserving comments.
Considered Options
- Option A — Keep regex parser, extend it to handle nested sequences. Reject: every step lands in a hand-rolled YAML 1.2 implementation.
- Option B — Write a minimal purpose-built YAML subset parser. Reject: effort exceeds the install-surface cost of vendoring
yaml@^2.8. - Option C — Accept
yaml@^2.8as the first and only additional runtime dependency. Chosen. - Option D — Move the roadmap source-of-truth back to Markdown. Reject: Phase-4 decisions lock
roadmap.yamlas source-of-truth specifically because Markdown cannot express the structured plan-object data.
Decision Outcome
Chosen: Option C — accept yaml@^2.8 as the first runtime dependency, because the concrete need is documented in Phase-4 decisions, CLAUDE.md pre-sanctions this specific dep, and the narrow name-scoped amendment preserves ADR-0002's forcing function against "just add a dep" drift.
Audit rule: Any PR that adds a key to package.json.dependencies beyond yaml MUST be blocked unless it ships with a new ADR amendment that supersedes this one or adds a second narrowly-scoped exemption.
Consequences
- Good —
roadmap.yamlparsing is now robust across nested sequences and YAML 1.2's full scalar type system. - Good — future phases that need structured YAML can reuse
yaml@^2.8without another amendment. - Good — the install-footprint remains effectively flat —
yaml@^2.8has zero transitive dependencies. - Bad —
npx nubos-pilotnow performs one actual download at install time on a fresh machine. The "zero-deps ≈ zero failure modes" property is slightly weakened — but only by the thinnest possible amount. - Bad — the escape-hatch is no longer purely theoretical — future PR authors have a concrete precedent to cite. Mitigated by the Scope clause pinning this to EXACTLY ONE dep.
- Neutral — workflow patterns remain unchanged.
More Information
- Amended ADR: ADR-0002.
- CLAUDE.md: §"Supporting Libraries" → row "yaml
^2.8.0" pre-sanctions this dependency. - Upstream:
yamlnpm package — maintained by Eemeli Aro, version 2.x is YAML 1.2 compliant, zero transitive deps.
This ADR does not describe CI enforcement. The dep-growth block (PR blocker on any new dependencies key beyond yaml) is deferred to a later deploy/CI phase, identical to ADR-0002's deferral.
