# 020.0-DEV-SURFACE-DEPRECATED-DEPENDENCIES: Surface Deprecated Dependencies Loudly

## Release Goal

**Release 0.13: Deprecation Visibility**

Surface dependencies that have been marked **deprecated** on the npm registry. Default on across all output formats so a deprecated dependency reaches the maintainer's eye without flag-juggling. Advisory-only: the tool surfaces the verbatim npm message and stops there — the human (or an LLM acting for them) decides the response.

## How This Story Contributes

`dry-aged-deps` surfaces dependency-health signals — update age, known vulnerabilities (fixable and unfixable), override hygiene, and un-landable peer graphs. It does not surface when a dependency has been **deprecated**. A deprecated dependency is a standing risk: often unmaintained, sometimes superseded by a named replacement the maintainer wrote into the deprecation message. Today that signal is only visible as `npm warn deprecated …` noise during `npm install`, or by running `npm view <pkg> deprecated` by hand per package — neither of which scales or ties back to the tool's report.

This story adds a complementary surface so deprecation enters the maintainer's normal review loop, mirroring the unfixable-vulns (016.0) and un-landable (019.0) informational-section pattern. It is the sibling of un-landable detection: both answer "what should the human know about this dependency?" and both are advisory.

## User Story

**Format**: So that I can plan a migration off an abandoned or superseded package, as a developer, I want `dry-aged-deps --check` to surface deprecated dependencies with their verbatim npm message, by default, in every output format — without the tool ever acting on the deprecation for me.

**INVEST Criteria Compliance**:

- **Independent**: Rides the existing per-package `npm view` registry read (story 002); no new external tooling and no extra request.
- **Negotiable**: Advisory-only is the chosen scope; whether deprecation should additionally influence the `--update` apply path is deferred (ADR-0023 Decision 2 rejected option).
- **Valuable**: Closes a visibility gap for a distinct risk class (deprecation is not a CVE) that the maintainer must see to plan a migration.
- **Estimable**: Reuses the fetch layer and the formatter-section pattern; new code is the widened fetch projection + a section in each formatter.
- **Small**: Single feature across a few slices. No new external dependency.
- **Testable**: Detection is mechanical (registry `deprecated` field present on the latest version); each output format gets its own test, plus an advisory-only `--update`-unchanged behavioural test.

## Acceptance Criteria

- [ ] **REQ-DEPRECATION-DETECT**: Read the latest (update-candidate) version's `deprecated` field from the registry by widening the existing per-package `npm view <pkg> time` call to `npm view <pkg> time deprecated` — one call, no extra round-trip. Absent when the package is not deprecated.
- [ ] **REQ-DEPRECATION-TABLE**: Table output appends a dedicated `Deprecated dependencies:` section after the existing outdated table. Non-tabular (each package's `name@version` then its verbatim message on its own line) because the message does not fit a padded column. Existing outdated-table columns are unchanged.
- [ ] **REQ-DEPRECATION-JSON**: JSON output gains a top-level `deprecated` array of `{ name, version, message }` objects. Existing `rows` / `packages` fields are unchanged.
- [ ] **REQ-DEPRECATION-XML**: XML output gains a top-level `<deprecated>` element with one `<package name version>` child per deprecated package, carrying the message as a `<message>` element.
- [ ] **REQ-DEPRECATION-VERBATIM**: The npm deprecation message is surfaced verbatim in every format. The tool does NOT parse it, extract a replacement package, summarise it, or emit a recommendation. If a maintainer named a replacement or migration URL in the message, the human reads it and decides.
- [ ] **REQ-DEPRECATION-ADVISORY-ONLY**: The surface is advisory-only. Deprecation does NOT influence age/security filtering, does NOT change what `--update` applies, and does NOT alter the exit-code contract (ADR-0003 / ADR-0004). A `--check` run whose only signal is a deprecated package still follows the existing exit-code rules; deprecation never widens the exit-1 trigger.
- [ ] **REQ-DEPRECATION-SCHEMA-COMPAT**: The JSON `deprecated` array and XML `<deprecated>` element are additive and omitted when empty, keeping the schemas backward-compatible — existing consumers that ignore unknown fields continue to operate unchanged (ADR-0002).

## Related

- **ADR-0023** — Surface deprecated dependencies advisory-only in a dedicated section (governing decision).
- **RFC-005** — Surface deprecated dependencies loudly (implementation vehicle).
- **P029** — Detect deprecated dependencies and surface them loudly (driving Known Error).
- **JTBD-011** — See deprecated dependencies so I can plan a migration.
- **016.0** (unfixable vulns) / **019.0** (un-landable updates) — sibling advisory-only informational-section stories this mirrors.
