Files
agentic-dev-template/docs/library-decisions/_template.md
Danijel Martinek f8908e5e4b feat(scripts): add library-decisions trace schema + template
Creates the shared schema module for library evaluation traces
(ADR-022 §4): Zod-validated frontmatter with all 8 filter fields and
enum constraints, plus parseTrace/validateTrace exports and a custom
YAML frontmatter parser for the nested trace format.

Also adds docs/library-decisions/_template.md with all 11 required
headings (8 Filter + 3 Prompt) in machine-checkable ADR-022 order.

Adds zod as a root devDependency so the script is runnable directly
from the workspace root without a package context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:10:06 +00:00

3.8 KiB

package, version, tier, decision, date, deciders, adr, filter-results, verification-commands, accepted-cves
package version tier decision date deciders adr filter-results verification-commands accepted-cves
<name> <semver range> app | feature | core approved | rejected <YYYY-MM-DD>
<author>
...
adr-NNN | null
license types maintenance boundary-fit shadow-check eu-residency cve-scan named-consumer
<SPDX id> native | "@types/<x>" | none active | dormant | abandoned pass | fail pass | fail | "shadows <x>" ok | n/a | self-hostable | fail clean | "<advisory-id>" | fail pass | fail
<literal command that produced each filter result>

Filter: license

Allowed licences: MIT, Apache-2.0, BSD-*, ISC, MPL-2.0. Record the SPDX identifier from package.json or npx license-checker. Anything outside the allowlist is an automatic reject.

Filter: types

Confirm TypeScript types are available (native = ships its own .d.ts; @types/<x> = community types package exists; none = no types → auto-reject).

Filter: maintenance

Check last release date and recent PR/issue activity. active = last release < 18 months AND activity < 12 months. dormant = stable but not actively developed (acceptable for finished libraries). abandoned = auto-reject.

Filter: boundary-fit

Confirm the dependency does not violate ESLint boundary-tag rules for the target tier (ADR-006, ADR-010, ADR-017). E.g., a Sentry SDK added to a feature package is an auto-reject because ADR-017 §4 reserves vendor SDKs for core.

Filter: shadow-check

Check whether this library duplicates a must-have already locked in the workspace (e.g., proposing valibot when zod is locked, tsyringe when Inversify is locked by ADR-002). A parallel adoption is shadows <x> and an auto-reject; a replacement requires a dedicated ADR.

Filter: eu-residency

If the library transmits user data, telemetry, or business state to a vendor-controlled endpoint by default, the vendor must offer an EU data region. Self-hostable packages and build-time-only tools are n/a.

Filter: cve-scan

Run pnpm audit --audit-level=moderate. clean = no advisories at adoption time. Record any accepted advisory IDs in the accepted-cves frontmatter field and explain the risk acceptance here.

Filter: named-consumer

Answer: "Who calls this code path today, or who is blocked waiting for it?" Hypothetical future callers are not consumers. This filter is the direct response to the 2026-05-14 OpenAPI near-miss (ADR-022 §Context).

Prompt: replaces

What existing library or approach does this replace? New-and-old running in parallel is a smell — name the thing being retired and its retirement plan, or explain why parallel adoption is intentional and time-bounded.

Prompt: migration-cost-out

What does ripping this back out look like 18 months from now? Is the removal mechanical (swap one package, update call sites), hard (scattered integration points, data format dependencies), or impossible (vendor lock-in, protocol coupling)? Higher migration cost raises the bar for adoption.

Prompt: alternatives-considered

Name at least two alternatives evaluated before choosing this library. For core-tier adoptions, this section is also duplicated into the companion ADR. If no alternatives exist, explain why (e.g., the library is the de-facto standard with no viable substitutes).