feat(archive): link each main-spec requirement to the change that introduced it
Problem
Main specs in openspec/specs/ say what the system must do. The why (the proposal and design) lives in openspec/changes/archive/<date>-<name>/, and nothing connects the two. Months later, someone reading a requirement has no path back to the decision behind it, so the spec reads like a stale copy of the code.
Proposal
When openspec archive writes an ADDED or MODIFIED requirement into a main spec, stamp it with the change it came from, using the metadata-line format the parser already supports:
### Requirement: Rate limit API keys
**Source**: 2026-09-17-add-rate-limits
The API SHALL reject more than 100 requests per minute per key.
extractRequirementBodyinsrc/core/parsers/requirement-text.tsalready skips**Key**:metadata lines, so validation and requirement text don't change.- A later MODIFIED change replaces the line with its own change name.
- Existing specs stay valid without it. Nothing gets backfilled.
- Agents and people can follow the source name to the archived proposal and design when they need the reasoning.
Why it fits
It doesn't add an artifact, command or workflow. It connects two things OpenSpec already keeps, main specs and the change archive, so a long-lived spec explains why the code is the way it is instead of repeating what the code does.
Note: this will change archive output fixtures and parity hashes, so expect that in the implementation PR.
Source: Fission-AI/OpenSpec