spec: link corpus references to GitHub, version-aware

Every "Test vectors: \`corpus/...\`" mention in the spec is now a
markdown link pointing at the corresponding file or directory on
GitHub. Each version build resolves its links to the correct git
ref:

  - /latest/ -> https://github.com/swaits/meshcore-spec/tree/main/corpus/...
  - /v0.1.0/ -> https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/...
  - future /vX.Y.Z/ -> /tree/vX.Y.Z/corpus/...

Two changes:

1. src/*.md (18 files): the inline-code corpus paths in each
   "Cross-References" section are now markdown links. Directories
   point at /tree/main/corpus/..., individual .json files point at
   /blob/main/corpus/.... CHANGELOG and other non-corpus main links
   are intentionally left pointing at main — the canonical history
   lives there regardless of which version you're reading.

2. justfile: `cut-version` now also runs a sed over the snapshot's
   *.md files replacing /tree/main/corpus -> /tree/<VERSION>/corpus
   and /blob/main/corpus -> /blob/<VERSION>/corpus. So a freshly-cut
   version is self-consistent.

versions/v0.1.0/* regenerated by re-running
`just cut-version v0.1.0` after the new src/ links + recipe sed
landed.

Tagging the release commit (`git tag v0.1.0`) is now REQUIRED — not
"optional" — because the rendered /v0.1.0/ pages reference
/tree/v0.1.0/corpus/... on GitHub. Without the tag the links 404.
cut-version's output now says so.

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:35:09 -06:00
1 parent b6c91505e1
commit f83d4088e3
38 files changed
+46 -38

No files matched your search

+9 -1
View File
@@ -74,8 +74,16 @@ 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' \
{} +
echo "Snapshotted src/ -> versions/{{VERSION}}"
echo
echo "Next steps:"
echo " - git add versions/{{VERSION}} && commit (e.g. \"release {{VERSION}}\")"
echo " - optionally tag the commit: git tag {{VERSION}}"
echo " - git tag {{VERSION}} # REQUIRED so the corpus links in /{{VERSION}}/"
echo " # resolve on GitHub (they point at tree/{{VERSION}}/...)"
+1 -1
View File
@@ -131,7 +131,7 @@ A conforming decoder MUST reject packets with any of the following:
- [Section 2: Header](02-header.md) — Header byte encoding details
- [Section 3: Path](03-path.md) — Path length encoding and path field
- Test vectors: `corpus/wire-format/framing/`, `corpus/wire-format/invalid/`
- Test vectors: [`corpus/wire-format/framing/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/wire-format/framing/), [`corpus/wire-format/invalid/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/wire-format/invalid/)
### Reference Implementation
+1 -1
View File
@@ -113,7 +113,7 @@ is an in-memory sentinel only and MUST NOT appear on the wire. A header of
- [Section 1: Wire Format](01-wire-format.md) — Overall packet structure
- [Section 3: Path](03-path.md) — Path encoding
- Test vectors: `corpus/wire-format/header/`
- Test vectors: [`corpus/wire-format/header/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/wire-format/header/)
### Reference Implementation
+1 -1
View File
@@ -143,7 +143,7 @@ this class of bug.
- [Section 1: Wire Format](01-wire-format.md) — Overall packet structure
- [Section 2: Header](02-header.md) — Header encoding
- [Section 15: Identity](15-identity.md) — Hash derivation from public keys
- Test vectors: `corpus/wire-format/path/`
- Test vectors: [`corpus/wire-format/path/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/wire-format/path/)
### Reference Implementation
+1 -1
View File
@@ -87,7 +87,7 @@ sender attribute each received ACK to a specific transmission attempt. See
- [Section 1: Wire Format](01-wire-format.md) — Packet framing
- [Section 11: Multipart](11-payload-multipart.md) — Multipart ACK encoding
- Test vectors: `corpus/payloads/ack/`
- Test vectors: [`corpus/payloads/ack/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/ack/)
### Reference Implementation
+1 -1
View File
@@ -115,7 +115,7 @@ preceding optional fields are present.
- [Section 15: Identity](15-identity.md) — Ed25519 key management
- [Section 14: Cryptography](14-crypto.md) — Signature operations
- Test vectors: `corpus/payloads/advert/`
- Test vectors: [`corpus/payloads/advert/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/advert/)
### Reference Implementation
+1 -1
View File
@@ -159,7 +159,7 @@ patterns include:
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC details
- [Section 15: Identity](15-identity.md) — ECDH shared secret computation
- Test vectors: `corpus/payloads/encrypted/`
- Test vectors: [`corpus/payloads/encrypted/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/encrypted/)
### Reference Implementation
+1 -1
View File
@@ -66,7 +66,7 @@ Header payload type field: `0x07` (ANON_REQ)
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Standard encrypted format
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- [Section 15: Identity](15-identity.md) — ECDH key exchange
- Test vectors: `corpus/payloads/anon-req/`
- Test vectors: [`corpus/payloads/anon-req/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/anon-req/)
### Reference Implementation
+1 -1
View File
@@ -72,7 +72,7 @@ secret. Only a successful MAC verification confirms the correct channel.
### Cross-References
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- Test vectors: `corpus/payloads/group/`
- Test vectors: [`corpus/payloads/group/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/group/)
### Reference Implementation
+1 -1
View File
@@ -82,7 +82,7 @@ hash is unique.
- [Section 3: Path](03-path.md) — Path length encoding
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Outer envelope format
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- Test vectors: `corpus/payloads/path-return/`
- Test vectors: [`corpus/payloads/path-return/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/path-return/)
### Reference Implementation
+1 -1
View File
@@ -97,7 +97,7 @@ At that point, `onTraceRecv` is called with:
### Cross-References
- [Section 16: Packet Hash](16-packet-hash.md) — TRACE packets include path_len in hash
- Test vectors: `corpus/payloads/trace/`
- Test vectors: [`corpus/payloads/trace/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/trace/)
### Reference Implementation
+1 -1
View File
@@ -112,7 +112,7 @@ intends to emit, not a guarantee that they will arrive.
### Cross-References
- [Section 4: ACK](04-payload-ack.md) — ACK CRC format
- Test vectors: `corpus/payloads/multipart/`
- Test vectors: [`corpus/payloads/multipart/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/multipart/)
### Reference Implementation
+1 -1
View File
@@ -60,7 +60,7 @@ formats are application-defined, but typically include:
### Cross-References
- [Section 17: Routing](17-routing.md) — Zero-hop delivery
- Test vectors: `corpus/payloads/control/`
- Test vectors: [`corpus/payloads/control/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/control/)
### Reference Implementation
+1 -1
View File
@@ -41,7 +41,7 @@ when received via direct routing. They are NOT flood-routed.
### Cross-References
- Test vectors: `corpus/payloads/raw-custom/`
- Test vectors: [`corpus/payloads/raw-custom/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/payloads/raw-custom/)
### Reference Implementation
+1 -1
View File
@@ -110,7 +110,7 @@ Output format:
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Usage in packet payloads
- [Section 15: Identity](15-identity.md) — Shared secret computation via ECDH
- Test vectors: `corpus/crypto/`
- Test vectors: [`corpus/crypto/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/crypto/)
### Reference Implementation
+1 -1
View File
@@ -81,7 +81,7 @@ Hex representation uses uppercase characters with 2 hex digits per byte.
- [Section 3: Path](03-path.md) — Hash size in path encoding
- [Section 5: Advertisement](05-payload-advert.md) — Signature usage
- [Section 14: Cryptography](14-crypto.md) — Shared secret usage
- Test vectors: `corpus/crypto/ed25519/`, `corpus/crypto/ecdh/`
- Test vectors: [`corpus/crypto/ed25519/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/crypto/ed25519/), [`corpus/crypto/ecdh/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/crypto/ecdh/)
### Reference Implementation
+1 -1
View File
@@ -59,7 +59,7 @@ function calculatePacketHash(packet):
### Cross-References
- [Section 10: Trace](10-payload-trace.md) — TRACE packet special handling
- Test vectors: `corpus/crypto/sha256/packet-hash.json`
- Test vectors: [`corpus/crypto/sha256/packet-hash.json`](https://github.com/swaits/meshcore-spec/blob/main/corpus/crypto/sha256/packet-hash.json)
### Reference Implementation
+1 -1
View File
@@ -89,7 +89,7 @@ implementations SHOULD request a larger MTU (up to 512 bytes).
### Cross-References
- [Section 1: Wire Format](01-wire-format.md) — Underlying packet format
- Test vectors: `corpus/companion/`
- Test vectors: [`corpus/companion/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/companion/)
### Reference Implementation
+1 -1
View File
@@ -173,7 +173,7 @@ Response codes: `response = command | 0x80`
- [Section 1: Wire Format](01-wire-format.md) — Packet format within data frames
- [Section 14: Cryptography](14-crypto.md) — Crypto operations via SetHardware
- Test vectors: `corpus/kiss/`
- Test vectors: [`corpus/kiss/`](https://github.com/swaits/meshcore-spec/tree/main/corpus/kiss/)
### Reference Implementation
+1 -1
View File
@@ -31,7 +31,7 @@ DongLoRa firmware and apps against live MeshCore deployments. Where DongLoRa
behavior diverges from upstream, this spec follows upstream and treats the
DongLoRa side as a follow-up bug, not a spec change.
Conformance against the [test corpus](https://github.com/swaits/meshcore-spec/tree/main/corpus)
Conformance against the [test corpus](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus)
is a useful signal but **not a substitute** for cross-checking against
upstream firmware. If you find a divergence from upstream, please
[file an issue](https://github.com/swaits/meshcore-spec/issues) — that is
+1 -1
View File
@@ -131,7 +131,7 @@ A conforming decoder MUST reject packets with any of the following:
- [Section 2: Header](02-header.md) — Header byte encoding details
- [Section 3: Path](03-path.md) — Path length encoding and path field
- Test vectors: `corpus/wire-format/framing/`, `corpus/wire-format/invalid/`
- Test vectors: [`corpus/wire-format/framing/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/wire-format/framing/), [`corpus/wire-format/invalid/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/wire-format/invalid/)
### Reference Implementation
+1 -1
View File
@@ -113,7 +113,7 @@ is an in-memory sentinel only and MUST NOT appear on the wire. A header of
- [Section 1: Wire Format](01-wire-format.md) — Overall packet structure
- [Section 3: Path](03-path.md) — Path encoding
- Test vectors: `corpus/wire-format/header/`
- Test vectors: [`corpus/wire-format/header/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/wire-format/header/)
### Reference Implementation
+1 -1
View File
@@ -143,7 +143,7 @@ this class of bug.
- [Section 1: Wire Format](01-wire-format.md) — Overall packet structure
- [Section 2: Header](02-header.md) — Header encoding
- [Section 15: Identity](15-identity.md) — Hash derivation from public keys
- Test vectors: `corpus/wire-format/path/`
- Test vectors: [`corpus/wire-format/path/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/wire-format/path/)
### Reference Implementation
+1 -1
View File
@@ -87,7 +87,7 @@ sender attribute each received ACK to a specific transmission attempt. See
- [Section 1: Wire Format](01-wire-format.md) — Packet framing
- [Section 11: Multipart](11-payload-multipart.md) — Multipart ACK encoding
- Test vectors: `corpus/payloads/ack/`
- Test vectors: [`corpus/payloads/ack/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/ack/)
### Reference Implementation
+1 -1
View File
@@ -115,7 +115,7 @@ preceding optional fields are present.
- [Section 15: Identity](15-identity.md) — Ed25519 key management
- [Section 14: Cryptography](14-crypto.md) — Signature operations
- Test vectors: `corpus/payloads/advert/`
- Test vectors: [`corpus/payloads/advert/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/advert/)
### Reference Implementation
+1 -1
View File
@@ -159,7 +159,7 @@ patterns include:
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC details
- [Section 15: Identity](15-identity.md) — ECDH shared secret computation
- Test vectors: `corpus/payloads/encrypted/`
- Test vectors: [`corpus/payloads/encrypted/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/encrypted/)
### Reference Implementation
+1 -1
View File
@@ -66,7 +66,7 @@ Header payload type field: `0x07` (ANON_REQ)
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Standard encrypted format
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- [Section 15: Identity](15-identity.md) — ECDH key exchange
- Test vectors: `corpus/payloads/anon-req/`
- Test vectors: [`corpus/payloads/anon-req/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/anon-req/)
### Reference Implementation
+1 -1
View File
@@ -72,7 +72,7 @@ secret. Only a successful MAC verification confirms the correct channel.
### Cross-References
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- Test vectors: `corpus/payloads/group/`
- Test vectors: [`corpus/payloads/group/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/group/)
### Reference Implementation
+1 -1
View File
@@ -82,7 +82,7 @@ hash is unique.
- [Section 3: Path](03-path.md) — Path length encoding
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Outer envelope format
- [Section 14: Cryptography](14-crypto.md) — Encrypt-then-MAC
- Test vectors: `corpus/payloads/path-return/`
- Test vectors: [`corpus/payloads/path-return/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/path-return/)
### Reference Implementation
+1 -1
View File
@@ -97,7 +97,7 @@ At that point, `onTraceRecv` is called with:
### Cross-References
- [Section 16: Packet Hash](16-packet-hash.md) — TRACE packets include path_len in hash
- Test vectors: `corpus/payloads/trace/`
- Test vectors: [`corpus/payloads/trace/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/trace/)
### Reference Implementation
+1 -1
View File
@@ -112,7 +112,7 @@ intends to emit, not a guarantee that they will arrive.
### Cross-References
- [Section 4: ACK](04-payload-ack.md) — ACK CRC format
- Test vectors: `corpus/payloads/multipart/`
- Test vectors: [`corpus/payloads/multipart/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/multipart/)
### Reference Implementation
+1 -1
View File
@@ -60,7 +60,7 @@ formats are application-defined, but typically include:
### Cross-References
- [Section 17: Routing](17-routing.md) — Zero-hop delivery
- Test vectors: `corpus/payloads/control/`
- Test vectors: [`corpus/payloads/control/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/control/)
### Reference Implementation
+1 -1
View File
@@ -41,7 +41,7 @@ when received via direct routing. They are NOT flood-routed.
### Cross-References
- Test vectors: `corpus/payloads/raw-custom/`
- Test vectors: [`corpus/payloads/raw-custom/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/payloads/raw-custom/)
### Reference Implementation
+1 -1
View File
@@ -110,7 +110,7 @@ Output format:
- [Section 6: Encrypted Payloads](06-payload-encrypted.md) — Usage in packet payloads
- [Section 15: Identity](15-identity.md) — Shared secret computation via ECDH
- Test vectors: `corpus/crypto/`
- Test vectors: [`corpus/crypto/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/crypto/)
### Reference Implementation
+1 -1
View File
@@ -81,7 +81,7 @@ Hex representation uses uppercase characters with 2 hex digits per byte.
- [Section 3: Path](03-path.md) — Hash size in path encoding
- [Section 5: Advertisement](05-payload-advert.md) — Signature usage
- [Section 14: Cryptography](14-crypto.md) — Shared secret usage
- Test vectors: `corpus/crypto/ed25519/`, `corpus/crypto/ecdh/`
- Test vectors: [`corpus/crypto/ed25519/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/crypto/ed25519/), [`corpus/crypto/ecdh/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/crypto/ecdh/)
### Reference Implementation
+1 -1
View File
@@ -59,7 +59,7 @@ function calculatePacketHash(packet):
### Cross-References
- [Section 10: Trace](10-payload-trace.md) — TRACE packet special handling
- Test vectors: `corpus/crypto/sha256/packet-hash.json`
- Test vectors: [`corpus/crypto/sha256/packet-hash.json`](https://github.com/swaits/meshcore-spec/blob/v0.1.0/corpus/crypto/sha256/packet-hash.json)
### Reference Implementation
+1 -1
View File
@@ -89,7 +89,7 @@ implementations SHOULD request a larger MTU (up to 512 bytes).
### Cross-References
- [Section 1: Wire Format](01-wire-format.md) — Underlying packet format
- Test vectors: `corpus/companion/`
- Test vectors: [`corpus/companion/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/companion/)
### Reference Implementation
+1 -1
View File
@@ -173,7 +173,7 @@ Response codes: `response = command | 0x80`
- [Section 1: Wire Format](01-wire-format.md) — Packet format within data frames
- [Section 14: Cryptography](14-crypto.md) — Crypto operations via SetHardware
- Test vectors: `corpus/kiss/`
- Test vectors: [`corpus/kiss/`](https://github.com/swaits/meshcore-spec/tree/v0.1.0/corpus/kiss/)
### Reference Implementation