GitHub releases and UCB AAO deposits
Documentation index ·
Generation pipeline ·
Prerequisites and hardware ·
v20260813 Stage 16 source release ·
v20260811 Stage 15 source release ·
v20260810 Stage 14 source release ·
v20260808.1 corrected release notes ·
v20260808 superseded attempt ·
v14 AAO release record ·
v13 AAO publication ·
v13 to v14 consumer layout ·
since the v13 release ·
v20260807 release notes ·
v12 S3 publication ·
v20260806 release notes
Cartofreako has two deliberately different release concepts:
- Releasing on GitHub publishes a date-named source tag and a GitHub release. A generated XZ bundle may be attached as a static GitHub asset, but it is not required for a source-only release.
- Releasing to UCB Active Archive Object Storage (AAO) via S3 deposits an independently versioned generated-assets tree under an immutable Cloudian prefix. It publishes the completion marker last and produces a transport receipt, verification record, and canonical check-in report.
The first operation never invokes, authorizes, or implies the second. There is
no umbrella release Make target. release-github has no S3 dependency, and
release-ucb-aao-s3 is deliberately a separate, top-level, interactive-only
target.
For example, the Stage 16 source-only GitHub release uses:
git tag v20260813 HEAD
make release-github \
GITHUB_RELEASE_TAG=v20260813 \
GITHUB_RELEASE_TITLE='v20260813 — Stage 16 assessments and 2026-08-13 orbital capture' \
GITHUB_RELEASE_NOTES=docs/pages/releases/v20260813.md
Release gate
Both release targets require the deterministic gate chain first:
make all-experiments-resilient
The gate runs, in order: make clean (implied by the
all-experiments-fetch prerequisite), every external fetch, the resilient
full-asset build (all-resilient), and every non-release experiment.
release-github and release-ucb-aao-s3 both list
all-experiments-resilient as a prerequisite, so invoking either release
target re-runs the entire gate chain — a release is always a full rebuild by
design.
The recommended release sequence is therefore:
make all-experiments-resilient
git status --porcelain
git add <any tracked diffs> && git commit -m '...'
git tag <release-tag> HEAD
make release-github \
GITHUB_RELEASE_TAG=<release-tag> \
GITHUB_RELEASE_TITLE='...' \
GITHUB_RELEASE_NOTES=docs/pages/releases/<release-notes>.md
Because the gate re-runs when release-github is invoked, the recipe’s
clean-worktree and tag-points-at-HEAD checks remain meaningful: any tracked
evidence regenerated by the gate must already be committed before the release
recipe verifies the tree.
An eventual generated-assets deposit is a later, separately authorized human
operation. Cartofreako supplies its reviewed profile, staged tree, and receipt
path; the target delegates credentials, immutable grouped transfer,
marker-last publication, and download verification to the shared
alpha60-clusterops/bin/load-s3-aao implementation:
make release-ucb-aao-s3 \
UCB_AAO_RELEASE_PROFILE=docs/releases/v14-aao-upload-profile.json \
UCB_AAO_RELEASE_DATA_ROOT=build/s3-release-v14 \
UCB_AAO_RELEASE_RECEIPT=reports/cartofreako-v14-aao-upload-receipt.json
The AAO target must be the only requested Make goal and must run in an interactive terminal. The shared engine still requires the exact destination confirmation. Do not call it from CI, another Make target, a GitHub release script, or an unattended agent workflow.
Treat GitHub assets and AAO objects as immutable snapshots. Never replace an uploaded file with different bytes under the same tag and filename. Publish a new tag and asset name when either the source or generated payload changes.
The GitHub Pages gallery is backend-selectable at build time. The live
default is the committed top-of-tree snapshot under assets.tot/
(browse tier: thumbnails, screen-1080p WebP, and full-resolution WebP),
recorded in .github/deploy-backend; switching that file to aao makes the
deployment resolve imagery from the immutable Berkeley S3 prefix
cartofreako/v14/, which exposes the lifecycle/projection/format products
tree, machine-readable artifact and pass indexes, and the versioned runtime
while retaining the manifest and a last-written completion marker. Follow the
v14 AAO release record; the GitHub source tags remain
unchanged. Successful applied uploads finish by generating the Devastation
Pacific Active Archive HTML/PDF report and rendered QA pages. Reports are
local delivery artifacts outside the immutable prefix and Git; their
verification and delivery record belongs in the versioned publication notes.
Shared transport and documentation authority
Future releases use the declarative
alpha60-clusterops shared AAO interface,
whose profile
and receipt
schemas define the cross-project transport contract. Shared implementation
commit cebba0d8144f46f75997f568e7f5b3a36e4161ef is the first version adopted
by this repository.
alpha60-clusterops is authoritative for |
Cartofreako is authoritative for |
|---|---|
| Credential prompts, empty rclone configuration, exact-prefix inspection, immutable grouped copies, marker-last publication, remote checks, and transport receipts | Source/tag/package identity, exact counts and pass requirements, the tracked release profile and validator, gallery URLs, report design, recipients, and observed v13 evidence |
| Profile and receipt schemas, baseline report/automatic-delivery policy, and future shared-engine corrections | Versioned S3 prefix, pilot identities declared by the profile, Devastation Pacific report contents, and delivery evidence |
The Cartofreako adapter never opens a desktop mailer. It writes a Gmail outbox request after report generation; after inspecting every QA page, the authenticated release orchestrator consumes that request and sends the canonical PDF automatically, without a second operator confirmation. The orchestrator records actual delivery separately from upload completion.
The v13 prefix itself was applied and fully read back by uploader 6 before the shared engine existed. Uploader 7 is the validated migration adapter over the same sealed 830-object staging tree. Do not republish v13 to exercise it; Cartofreako v14 was the first applied use of the shared interface.
v20260808.1 corrective release procedure
Stage 13 uses corrective source tag v20260808.1, static asset
assets.generated.v13.tar.xz, and the projection-first 909-file artifact
tree. Before packaging, run the native, browser/WebAssembly, and exact artifact
checks recorded in the corrected release notes. The release
render must contain 211 SVGs, 84 adjacent resource SVG gzip companions, 211
PDFs, 211 full-size PNGs, and 192 thumbnails. Every projection and format must
contain exactly one Cloud-atmosphere and one Fiber Synthesized product.
The immutable v20260808 attempt contains only the 885-file clean graph. It
was stopped before S3 publication and is marked superseded; do not replace its
GitHub asset or move its tag.
Create the reproducible archive only after the source commit is final. The
archive timestamp is the tagged commit time; ownership and modes are
normalized, and every member remains under assets.generated/:
release_tag=v20260808.1
release_commit=$(git rev-parse "$release_tag^{commit}")
source_date_epoch=$(git show -s --format=%ct "$release_commit")
tar --sort=name \
--mtime="@$source_date_epoch" \
--owner=0 --group=0 --numeric-owner \
--mode='u+rwX,go+rX,go-w' \
--format=posix \
--pax-option=delete=atime,delete=ctime \
--create --file=- assets.generated | \
xz --threads=4 -9e > assets.generated.v13.tar.xz
The Stage 13 package used four XZ worker threads so compression remained inside the release environment’s 64 GiB execution limit. This affects only compression resources; the normalized archive members and reproducibility contract are unchanged.
Preflight the sealed package and record its digest and byte counts in
v20260808.1.md:
xz --test assets.generated.v13.tar.xz
test "$(tar --list --file=assets.generated.v13.tar.xz | sed -n '1p')" = \
'assets.generated/'
test "$(tar --list --file=assets.generated.v13.tar.xz | \
sed -n '/\/$/!p' | wc -l)" -eq 909
sha256sum assets.generated.v13.tar.xz
Push the already-created source tag explicitly. The release notes intentionally begin with body text; GitHub supplies the one and only announcement title:
git push origin main
git push origin refs/tags/v20260808.1
gh release create v20260808.1 \
--repo bdekoz/cartofreako \
--verify-tag \
--title 'v20260808.1 — complete generated assets v13 and Stage 13' \
--notes-file docs/pages/releases/v20260808.1.md \
'assets.generated.v13.tar.xz#Projection-organized SVG, PDF, PNG, and thumbnail bundle (XZ)'
Download the GitHub object into a fresh directory and compare it to the local package before constructing the S3 release:
release_verify_dir=$(mktemp -d /tmp/cartofreako-v20260808.1.XXXXXX)
gh release download v20260808.1 \
--repo bdekoz/cartofreako \
--pattern 'assets.generated.v13.tar.xz' \
--dir "$release_verify_dir"
test "$(sha256sum assets.generated.v13.tar.xz | awk '{print $1}')" = \
"$(sha256sum "$release_verify_dir/assets.generated.v13.tar.xz" | awk '{print $1}')"
xz --test "$release_verify_dir/assets.generated.v13.tar.xz"
Historically, v13 built the immutable S3 staging tree and ran its exact local validation through the release-local adapter:
scripts/build-generated-assets-s3-release.sh
scripts/upload-generated-assets-s3-release.sh --validate-only
The historical applied v13 run used uploader 6 with
--apply --verify-download; its observed result is in
aao-v13.md. Because cartofreako/v13/ is complete and
immutable, do not rerun an applied command against it. The release-local
uploader 7 remains migration evidence: it validated the Cartofreako product
and then delegated transport to alpha60-clusterops/bin/load-s3-aao.
For v14 and later, keep product validation and post-transfer report generation in Cartofreako, but do not maintain another S3 transport implementation here. After building the staged tree, running the version-specific Cartofreako validator, and reviewing the new profile, the applied transfer is the separate human-only Make target:
make release-ucb-aao-s3 \
UCB_AAO_RELEASE_PROFILE=docs/releases/v14-aao-upload-profile.json \
UCB_AAO_RELEASE_DATA_ROOT=build/s3-release-v14 \
UCB_AAO_RELEASE_RECEIPT=reports/cartofreako-v14-aao-upload-receipt.json
The Make recipe is only a guarded wrapper over
alpha60-clusterops/bin/load-s3-aao --apply --verify-download. The
release-local profile declares the staged tree, immutable destination, groups,
pilots, metadata, and completion marker; the shared engine owns credentials,
dry runs, exact-prefix authorization, upload, and verification. Validation,
dry-run, and applied-upload receipts need separate filenames so a later
preflight cannot overwrite the canonical completion evidence. Copy and
deliberately update the profile’s data root, immutable prefix, and pilot names;
never reuse or repair cartofreako/v13/.
Do not move v20260808.1 or replace either public artifact after publication.
A later correction requires a new source tag, generated-assets version, and
S3 prefix.
v20260807 release procedure
The Stage 12 release keeps the date-based source tag and independently versions the generated static bundle:
tag: v20260807
commit: 2bd3d760fef540addfcbb4f8002ef7b283d8000f
asset: assets.generated.v12.tar.xz
sha256: dc1d761def31d77a05a7cc42f9bc0705ee864046f2e235f50c701c9c42fe960a
Run the immutable-object and package preflight from the repository root:
test "$(git rev-parse \
2bd3d760fef540addfcbb4f8002ef7b283d8000f^{commit})" = \
2bd3d760fef540addfcbb4f8002ef7b283d8000f
test -f assets.generated.v12.tar.xz
printf '%s %s\n' \
dc1d761def31d77a05a7cc42f9bc0705ee864046f2e235f50c701c9c42fe960a \
assets.generated.v12.tar.xz | sha256sum --check -
xz --test assets.generated.v12.tar.xz
test "$(tar --list --file=assets.generated.v12.tar.xz | wc -l)" -eq 679
test "$(tar --list --file=assets.generated.v12.tar.xz | sed -n '1p')" = \
'assets.generated/'
Create and push the lightweight tag at the pinned source revision. Fetch only the branch here: historical local tags may intentionally differ from their remote counterparts and are outside this release’s scope.
release_commit=2bd3d760fef540addfcbb4f8002ef7b283d8000f
git fetch --no-tags origin main
git tag v20260807 "$release_commit"
git push origin refs/tags/v20260807
test "$(git rev-list -n 1 v20260807)" = "$release_commit"
The notes file intentionally begins with body text. The GitHub release name supplies the single displayed title:
gh release create v20260807 \
--repo bdekoz/cartofreako \
--verify-tag \
--title 'v20260807 — generated assets v12 and Stage 12' \
--notes-file docs/pages/releases/v20260807.md \
'assets.generated.v12.tar.xz#Generated SVG, PDF, PNG, and Cahill-Keyes thumbnail bundle (XZ)'
Download the uploaded bytes into a new directory and verify them independently of the source copy:
release_verify_dir=$(mktemp -d /tmp/cartofreako-v20260807.XXXXXX)
gh release download v20260807 \
--repo bdekoz/cartofreako \
--pattern 'assets.generated.v12.tar.xz' \
--dir "$release_verify_dir"
printf '%s %s\n' \
dc1d761def31d77a05a7cc42f9bc0705ee864046f2e235f50c701c9c42fe960a \
"$release_verify_dir/assets.generated.v12.tar.xz" | sha256sum --check -
xz --test "$release_verify_dir/assets.generated.v12.tar.xz"
Do not move v20260807 after publication. Later documentation commits may
describe the release, but the tag, announcement, and manifest must continue to
identify 2bd3d760fef540addfcbb4f8002ef7b283d8000f.
v20260806 release procedure
This historical tag follows the existing lightweight, date-based convention. It must continue to resolve to its pinned source commit even though the runbook was committed later:
tag: v20260806
commit: cfe1f8ff15feadec8f3a0c88a9d66648040e61dd
asset: assets.generated.v10.tar.xz
sha256: 5256927f2ac7702d35b1450a45d8bca69b47dc2e9e13b2def1160231e5b8705a
Run the preflight from the repository root:
test "$(git rev-parse HEAD)" = \
cfe1f8ff15feadec8f3a0c88a9d66648040e61dd
test -f assets.generated.v10.tar.xz
printf '%s %s\n' \
5256927f2ac7702d35b1450a45d8bca69b47dc2e9e13b2def1160231e5b8705a \
assets.generated.v10.tar.xz | sha256sum --check -
xz --test assets.generated.v10.tar.xz
test "$(tar --list --file=assets.generated.v10.tar.xz | wc -l)" -eq 433
The documentation working tree does not have to be at the release commit to publish the already-pinned source revision. In that case, replace only the first preflight assertion with this object check:
test "$(git rev-parse \
cfe1f8ff15feadec8f3a0c88a9d66648040e61dd^{commit})" = \
cfe1f8ff15feadec8f3a0c88a9d66648040e61dd
Create and push the lightweight tag explicitly. --verify-tag below then
prevents GitHub CLI from silently creating a tag at another revision:
release_commit=cfe1f8ff15feadec8f3a0c88a9d66648040e61dd
git fetch origin --tags
git tag v20260806 "$release_commit"
git push origin refs/tags/v20260806
test "$(git rev-list -n 1 v20260806)" = "$release_commit"
Publish the source tag and static bundle as one GitHub release:
The notes file intentionally begins with body text rather than repeating the
release title as a Markdown heading. GitHub renders the --title value above
the notes body.
gh release create v20260806 \
--repo bdekoz/cartofreako \
--verify-tag \
--title 'v20260806 — generated assets v10 and Stage 10' \
--notes-file docs/pages/releases/v20260806.md \
'assets.generated.v10.tar.xz#Generated SVG, PDF, and PNG bundle (XZ)'
Finally, download the uploaded bytes into a new directory and verify them independently of the source copy:
release_verify_dir=$(mktemp -d /tmp/cartofreako-v20260806.XXXXXX)
gh release download v20260806 \
--repo bdekoz/cartofreako \
--pattern 'assets.generated.v10.tar.xz' \
--dir "$release_verify_dir"
printf '%s %s\n' \
5256927f2ac7702d35b1450a45d8bca69b47dc2e9e13b2def1160231e5b8705a \
"$release_verify_dir/assets.generated.v10.tar.xz" | sha256sum --check -
xz --test "$release_verify_dir/assets.generated.v10.tar.xz"
gh release view v20260806 --repo bdekoz/cartofreako --web
Do not move v20260806 to a documentation commit after publishing. A later
documentation-only commit may describe the release, but the public tag and
the manifest in v20260806.md must continue to identify
cfe1f8ff15feadec8f3a0c88a9d66648040e61dd.