feat(versioning): snapshot corpus per spec version
mdBook / build (push) Canceled after 0s
mdBook / deploy (push) Canceled after 0s

A frozen spec is only meaningful if it's paired with the corpus
that was current at release time — otherwise a v0.1.0 reader
follows "see corpus/payloads/ack/" and lands on a file whose
test vectors may have changed since v0.1.0 was cut.

Three changes:

1. `cut-version` now copies BOTH src/ AND corpus/ into the
   snapshot directory. A release is the pair, not just the text.

2. The corpus URL rewriting in cut-version now retargets
   /tree/main/corpus -> /tree/main/versions/<v>/corpus (and the
   blob variant). This lets the link resolve on GitHub from main
   alone — no git tag required, since the frozen copy is a real
   path under main. Downgrades the "tag is REQUIRED" message from
   last commit back to "optionally tag the commit".

3. The frozen corpus's spec_ref fields get rewritten too: from
   `src/04-payload-ack.md` to `versions/<v>/04-payload-ack.md`,
   so a reader following a test vector lands on the spec text the
   vector was paired with at release time.

versions/v0.1.0/ regenerated from scratch via `just cut-version v0.1.0`
to pick up the corpus snapshot + the new sed patterns. The release
is now self-consistent: v0.1.0 spec links go to v0.1.0 corpus, which
links back to v0.1.0 spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.7 committed 2026-05-12 10:38:02 -06:00
1 parent f83d4088e3
commit 9232c16f7c
71 files changed
+5924 -28

No files matched your search

+21 -9
View File
@@ -65,7 +65,12 @@ cut-version VERSION:
exit 1
fi
mkdir -p versions
# Snapshot both the spec text AND its paired test corpus, so the
# release is a self-contained pair. The site infrastructure
# (book.toml, theme, scripts, tools) stays unversioned at the
# repo root and applies to every build.
cp -R src "versions/{{VERSION}}"
cp -R corpus "versions/{{VERSION}}/corpus"
# Freeze the version marker in the snapshot. src/ keeps the literal
# `latest (main)` so the rolling /latest/ build stays accurate.
sed -i 's|`latest (main)`|`{{VERSION}}`|' "versions/{{VERSION}}/00-overview.md"
@@ -74,16 +79,23 @@ cut-version VERSION:
echo "snapshot still says 'latest (main)'. Check that src/00-overview.md" >&2
echo "contains the marker line ('**Spec version:** \`latest (main)\`')." >&2
fi
# Repoint corpus links to this version's GitHub tree. The spec keeps
# CHANGELOG links pointing at main (more useful — full history) by
# only matching .../tree/main/corpus and .../blob/main/corpus.
find "versions/{{VERSION}}" -name '*.md' -exec sed -i \
-e 's|/tree/main/corpus|/tree/{{VERSION}}/corpus|g' \
-e 's|/blob/main/corpus|/blob/{{VERSION}}/corpus|g' \
# Repoint corpus URLs in the snapshot's spec text from main/corpus
# to main/versions/<v>/corpus — the frozen copy lives in the repo
# at a stable path on main, so the GitHub links resolve without
# needing a git tag. -maxdepth 1 keeps the substitution off the
# corpus *.json files (they get their own pass below).
find "versions/{{VERSION}}" -maxdepth 1 -name '*.md' -exec sed -i \
-e 's|/tree/main/corpus|/tree/main/versions/{{VERSION}}/corpus|g' \
-e 's|/blob/main/corpus|/blob/main/versions/{{VERSION}}/corpus|g' \
{} +
echo "Snapshotted src/ -> versions/{{VERSION}}"
# Repoint spec_ref inside the frozen corpus to this version's
# frozen spec, so a reader following a test vector lands on the
# spec text the vector was paired with at release time.
find "versions/{{VERSION}}/corpus" -name '*.json' -exec sed -i \
's|"spec_ref": "src/|"spec_ref": "versions/{{VERSION}}/|g' \
{} +
echo "Snapshotted: src/ + corpus/ -> versions/{{VERSION}}/"
echo
echo "Next steps:"
echo " - git add versions/{{VERSION}} && commit (e.g. \"release {{VERSION}}\")"
echo " - git tag {{VERSION}} # REQUIRED so the corpus links in /{{VERSION}}/"
echo " # resolve on GitHub (they point at tree/{{VERSION}}/...)"
echo " - optionally tag the commit: git tag {{VERSION}}"