Skip to content

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.dependencies is 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.
  • devDependencies remain unconstrained by this amendment.

Decision Drivers

  • Concrete needroadmap.yaml ships 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.8 as the acceptable escape-hatch dependency.
  • Install-footprint minimalyaml@^2.8 has zero transitive dependencies and ships ~50KB of JS.
  • Type safetyYAML.parse yields typed scalars (number, string, boolean, null, arrays of same).
  • Round-trip support — supports CST-preserving YAML.parseDocument for 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.8 as 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.yaml as 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

  • Goodroadmap.yaml parsing 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.8 without another amendment.
  • Good — the install-footprint remains effectively flat — yaml@^2.8 has zero transitive dependencies.
  • Badnpx nubos-pilot now 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: yaml npm 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.