# Trace Template Use this file as the structural guide when writing a library decision trace. Copy the frontmatter block and all 11 headings. Replace placeholder values with real results. Trace path: `docs/library-decisions/-.md` --- ## Frontmatter — all filters evaluated ```markdown --- package: version: "" tier: app | feature | core decision: approved | rejected date: deciders: [, ...] adr: adr-NNN | null filter-results: license: types: native | "@types/" | none maintenance: active | dormant | abandoned boundary-fit: pass | fail shadow-check: pass | fail | "shadows " eu-residency: ok | n/a | self-hostable | fail cve-scan: clean | "" | fail named-consumer: pass | fail verification-commands: - - - - accepted-cves: [] --- ``` ## Frontmatter — partial trace (expensive filters short-circuited) When an expensive filter fails (Phase 2 short-circuit), set remaining filter fields to `skip`. The Zod schema validates approved traces end-to-end; `skip` is the accepted sentinel for unevaluated fields in rejected traces. Example: `maintenance: abandoned` → `cve-scan`, `eu-residency`, `named-consumer` skipped. ```markdown --- package: version: "" tier: feature | core decision: rejected date: deciders: [, ...] adr: null filter-results: license: MIT types: native maintenance: abandoned boundary-fit: pass shadow-check: pass eu-residency: skip cve-scan: skip named-consumer: skip verification-commands: - npm view time.modified accepted-cves: [] --- ``` --- ## Required headings (11 total, in this order) ### Filter sections (8) ```markdown ## Filter: license Record the SPDX identifier from `package.json` or `npx license-checker --packages `. Allowed: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0. Anything else → auto-reject (note the identifier and rejection reason). ## Filter: types Confirm TypeScript types are available. `native` = ships its own `.d.ts`; `@types/` = community types package exists and is current; `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. If skipped (earlier expensive filter failed), write: "Not evaluated — skipped due to rejection." ## Filter: boundary-fit Confirm the dependency does not violate ESLint boundary-tag rules for the target tier (ADR-006, ADR-010, ADR-017). Name the specific rule checked and the result. ## Filter: shadow-check Check whether this library duplicates a must-have already locked in the workspace. Locked must-haves: zod, inversify, payload, @trpc/server, superjson, reflect-metadata. `shadows ` → 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 and the integration must be configured to use it. Pure in-process libraries and build-time tools → `n/a`. If skipped, write: "Not evaluated — skipped due to rejection." ## Filter: cve-scan Run `pnpm audit --audit-level=moderate`. `clean` = no advisories at adoption time. Record accepted advisory IDs in the `accepted-cves` frontmatter field and explain the risk acceptance here. If skipped, write: "Not evaluated — skipped due to rejection." ## Filter: named-consumer Answer: "Who calls this code path today, or who is blocked waiting for it?" Hypothetical future callers are not consumers (ADR-022 §2.8 — the direct response to the 2026-05-14 OpenAPI near-miss). If skipped, write: "Not evaluated — skipped due to rejection." ``` ### Prompt sections (3) ```markdown ## 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? Rate: mechanical (swap package, update call sites), hard (scattered integration, data-format dependencies), or impossible (vendor lock-in, protocol coupling). Higher migration cost raises the adoption bar. ## 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. ```