* Pin authenticated historical release catalog (bd-9q3.1) Establish the exact 122-version SumDB-backed source universe and record proxy prereleases, archived repository-only tags, current repository-tag drift, and optional release asset provenance. Offline validation pins the complete reviewed catalog identity. Agent-Signature: codex-unknown-model-unknown-reasoning on behalf of CI Bot * Simplify validateCatalog into phase helpers Extract validateCatalog's validation phases into validateVersionEntries, validateEntryProvenance, validateTagDrift, validateSourceRelations, and validateExclusions, dropping its cyclomatic/cognitive complexity from 43/43 to 11/8. Behavior and error paths are unchanged: the pinned catalog digest and offline hermetic validation still pass. Also derive the proxy @v/list URL from modulePath so version listing and module downloads cannot drift to different module identities. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(review): dedupe bd init legacy-upgrade guard; document release catalog anchor Maintainer review fixups for PR #5100 (adopt-pr review loop, attempt 1). cmd/bd/init.go: remove the duplicate guardLegacyUpgradeWorkspace block in bd init. After the rebase onto feature/v12-u0-history-20260719 the base already carried the guard, so the PR's added block was a byte-identical second call that re-ran the read-only workspace classification twice and misrepresented the diff intent. A single guard call before the existing-workspace safety checks is retained; behavior is unchanged (reviewer-confirmed idempotent). scripts/migration-test/catalog/README.md: document that the pinned release catalog is currently a self-validated reference anchor (pinned SHA-256 identity + strict offline validator + go test ./... digest gate) whose intended consumer is the stacked v1.2 upgrade-census / runtime-schema coverage work, since no migration-test harness consumes it yet. Addresses the two minor findings from the Claude + Codex review synthesis (decision: approve; scorecard 971/1000). Contributor commits preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(migration-test/catalog): correct semver prerelease ordering versionCompare tie-broke same-core versions with strings.Compare, so v1.2.3-rc.10 sorted before v1.2.3-rc.2 and a stable release sorted before its own prereleases. generate and validate share this comparator, so a wrong canonical order self-validates against the pinned digest and the anti-tamper check cannot catch it. Replace the lexicographic tiebreak with a SemVer 2.0.0 section 11 prerelease comparator (numeric-aware identifier comparison, numeric < alphanumeric, longer set wins, stable > prerelease) and add regression coverage including rc.2 vs rc.10. The checked catalog's canonical order and pinned digest are unchanged: its only same-core group, v1.1.0-rc.1/-rc.2, sorts identically. Maintainer adoption fixups for PR #5100 review: - tighten origin-ref provenance from any refs/ prefix to the exact refs/tags/<version> or refs/heads/main shapes actually used - key the digest-pinned Catalog/Entry/SourceZip/AssetRecord composite literals to avoid silent field-shift on a future struct reorder - drop the inert GONOSUMDB= env entry and print the recomputed SHA-256 from generate to make deliberate digest updates less error-prone Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Historical release catalog
../release-catalog.json pins the exact historical release universe used by the
v1.2 upgrade census: 122 stable module versions authenticated through the Go
proxy and SumDB, each with module / go.mod / source-zip / proxy-origin
provenance, explicit proxy prerelease and repository-only tag exclusions, and
the current repository tag drift.
The catalog command in this directory both regenerates and validates that
artifact (usage: catalog generate|validate <manifest.json>):
go run ./scripts/migration-test/catalog validate scripts/migration-test/release-catalog.jsonruns the strict offline validator: schema checks, semantic validation, canonical byte-form, and the pinned SHA-256 identity digest. Even a well-formed substitution is rejected until that digest is deliberately updated.go run ./scripts/migration-test/catalog generate scripts/migration-test/release-catalog.jsondeterministically rebuilds the catalog from the live Go proxy and GitHub release APIs (network plusgo/ghrequired). This is a manual maintenance path, not a CI step.
Status: self-validated reference anchor
Today the catalog is a reviewed-identity anchor. Its only automated enforcement
is TestCheckedCatalogIsCanonicalAndComplete in main_test.go, which runs
under go test ./... and holds the checked JSON to the pinned digest and its
invariants. Nothing in the migration-test harness (run.sh,
historical-dolt-upgrade-test.sh, legacy-bridge-test.sh) consumes it yet.
The intended consumer is the upgrade-coverage work stacked on top of this
change: runtime schema observations and family/path qualification will drive
upgrade tests against this finite, reproducible version universe. Until that
lands, regenerate deliberately with generate when upstream history changes —
drift from live upstream is not detected automatically.