Release runbook
Only a clean, reviewed commit on main may become a release. Production
publishing uses GitHub Actions OIDC Trusted Publishing; API tokens and local
uploads are prohibited.
Repository release coordinates are defined in
.github/release-config.json. Its stable package version and GitHub Project 2
release fields are one reviewed release control. The Project fields are the
owner, Project number and title, Release iteration, Priority, Status, and
Validation; no successor tracker issue is required. The release workflow
requires the configured version, pyproject.toml, desktop/package.json, and
the packaged sidecar build identity to match exactly before either pre-tag
packaging or tagged publication can proceed. Readiness and publication use the
configured Project values instead of inferring release state from an issue
number or version string.
The published v0.4.0 release continues to use its preserved milestone/tracker
evidence. Schema 2 is the v0.5.0-and-later control plane: its selected Project
iteration, currently v0.5.0 — Foundation, is authoritative for future
release readiness.
Future deployment-runtime release gate
ADR-0026 is an accepted runtime target, not a current availability claim. The source-level profile control plane and the unwired #363 host-control foundation do not make a container or remote runtime available. Each runtime remains unavailable until its row below and the common conditions pass. A gate or subset assigned to one profile does not block an independent profile whose own row is complete.
| Profile | Required threat-model evidence |
|---|---|
| Local Desktop containers | G0, G5, and the Local Desktop container-acquisition, native-image, lifecycle, rollback, uninstall, and support-lifetime parts of G7. Remote edge, identity, and host-operations evidence from G6 is not applicable. |
| Connect Remote | G0; the enrolled-client, endpoint, TLS, session, authorization, and client-side portions of G6; and the desktop-client acquisition, integrity, upgrade, rollback, and support-lifetime parts of G7. Local Docker/runtime evidence from G5 and Host Remote operations are not applicable. |
| Host Remote | G0, the hosting edge, identity, authorization, enrollment, custody, external-scan, backup, and recovery parts of G6, and the host image/runtime distribution, startup, shutdown, upgrade, rollback, uninstall, runbook, capacity, and support-lifetime parts of G7. Local Desktop supervisor evidence is not applicable. |
Every required gate or subset needs linked implementation evidence, no untriaged Critical or High finding, and approval by a reviewer other than the implementer. The common conditions are:
- Every claimed OS, architecture, Docker Engine API, Compose version, and runtime is tested natively. Emulation is labeled and does not establish native support. Colima/Lima is the open-source macOS default; Docker Desktop is optional and separately licensed.
- ADR-0026’s startup, shutdown, CPU, memory, PID, storage, inode, log, connection, worker, job, request-size, image-size, listener, and zero-network budgets pass on the release candidate for that profile.
- OCI digests, checksums, dependency licenses, SBOM, and provenance are verified; images and artifacts contain no credentials, genealogy data, or Docker authority; and any later artifact-signing boundary is documented.
- Operator documentation covers profile intent, the renderer and Docker trust boundaries, listeners, TLS, authentication, secret and SQLCipher-key custody, restore drills, upgrades, rollback, uninstall, capacity, monitoring, incident response, and recovery. Host Remote remains a single-household, self-supported profile with no project-operated SLA.
The sanitized native macOS arm64
issue-363-macos-arm64-container-supervisor.json
record is partial G5/G7 source-foundation evidence only. It binds one
isolated Colima profile, app-owned context and Unix socket to the expected
Engine identity; exercises hardened start, stop, repair, preserving uninstall,
deleting uninstall, and exact owned-resource cleanup; and confirms that the
default Docker context and engine remain unchanged. It does not prove an
application image, runtime acquisition, secret broker, family-tree grant,
authenticated workload, storage migration or recovery, quantitative budget,
interruption path, release-candidate integration, or any additional native OS,
architecture, Engine, or Compose row. It cannot independently satisfy a
profile gate.
Failure of any condition blocks the affected profile without blocking the existing local CLI, REPL, or released bounded desktop shell.
Private Project read token
Project 2 is private. Configure the repository Actions secret
ANCESTRYLLM_PROJECT_READ_TOKEN with a classic personal access token for an
account that can view the Project and has only the read:project scope needed
for this query. The release workflows retain github.token for repository and
Actions operations, but supply the named secret only to the Project GraphQL
read. A missing or unusable secret fails the Project gate closed.
Release Project gate proof runs for every push to protected main, checks
that the checkout and origin/main are the triggering commit, validates the
configured release coordinates, and performs the authenticated Project query.
It verifies pagination and target-iteration field schema without claiming that
the in-development iteration is ready to release; a deterministic regression
then proves the strict verifier rejects an open P0 item. Release readiness
and the tag workflow continue to use the strict live gate. The proof has no
pull-request or manual trigger, so a fork or Dependabot pull request cannot receive the secret.
While the triggering commit remains the tip of main, use GitHub’s rerun
mechanism to retry its immutable run. If main advances, the earlier candidate
and its proof are superseded; require a successful proof from the newer tip
instead. The exact-main run for each candidate is the hosted proof; do not
create the secret in a pull request or place the token in repository files.
Version 1 security dependency gate
config/version-1-security-policy.json is the reviewed source of truth for
Version 1 security issue ownership, release iterations, native GitHub
dependencies, their iteration order, and the #131 release-evidence consumer.
config/release-project-query-v1.graphql is the only permitted Project query
for that gate. Proof, readiness, and release workflows must use both files
without embedding a divergent query or inferring policy from issue titles,
bodies, labels, or comments.
When the plan changes, update the issue number, owner, iteration, dependency
edge, iteration order, and consumer in the same reviewed pull request wherever
they are affected. Apply the corresponding owner, Project field, and native
blocked by relationship in GitHub, then run the exact checked-in query through
scripts/verify_release_project.py. Do not represent a required dependency
only in prose. The verifier rejects missing or reversed edges, cycles,
prerequisites scheduled after dependents, premature closure, incomplete
pagination, and unknown policy fields.
The generated schema-v1 report is deterministic and binds its normalized
issues and edges to the canonical policy SHA-256. Release evidence records its
digest and accepts the version-1-security-dependencies gate only when its
Project, repository, checked issues, dependencies, policy digest, and #131
consumer match the checked-in policy exactly. Keep the report as readiness
evidence and pass that same artifact to the tag workflow; never reconstruct it
from mutable issue prose. Authorized maintainer changes and GitHub’s Project,
issue-dependency, API, and token enforcement remain trusted. Missing access or
incomplete hosted data blocks release.
Binary-signing version boundary
AncestryLLM will not sign project-produced release artifacts or release tags
until the first full version release, v1.0.0. Every stable 0.x installer
must therefore use binarySigningMode: "unsigned", and every stable 0.x
release tag must use releaseTagMode: "unsigned-annotated". Developer ID,
notarization, Authenticode, detached GPG, ad hoc signing, and Git tag-signing
credentials must not be used for an official pre-1.0 release.
Starting with v1.0.0, full trusted platform signing and a signed annotated release tag are mandatory; unsigned or self-signed release binaries and an unsigned release tag are rejected. This release-output boundary does not relax repository identity controls such as signed commits on the protected branch.
Every pre-1.0 release must disclose its binarySigningMode and
releaseTagMode in release evidence and release notes, warn that the operating
system may show an unknown-publisher or equivalent prompt, and retain all
checksum, SBOM, provenance, exact-head, installation, and installed-runtime
gates. Deferring signing is not a waiver of those gates. The macOS desktop
verification workflow may apply an ephemeral ad hoc signature solely to launch
an unpublished fuse-mutated test bundle on a hosted runner; that bundle must
never be distributed, imported into a release, or accepted as release-signing
evidence.
v0.5.0 supported offline shell
v0.5.0 is a supported offline three-OS Electron shell. Its installer matrix is macOS 15 arm64, macOS 15 x64, Windows 11 ARM64, and Ubuntu 24.04 x64. The matching-architecture DMGs cover the supported macOS 15/26 range. Its release scope is Home, Diagnostics, Settings, capability onboarding, and a private loopback sidecar, distributed as manual full installers under the pre-1.0 binary-signing policy above. It excludes genealogy jobs, chat providers, cloud accounts, updater behavior, and background release channels.
One-time repository setup
- Protect
mainwith a ruleset that requires CI, CodeQL, signed commits, and every review conversation to be resolved before merge, and that prevents force pushes and deletion. - Enforce tag immutability with a ruleset for
v*.*.*: prevent tag update and deletion, and restrict creation to the maintainer. - Create GitHub environments
desktop-prerelease,testpypi, andpypi. Thedesktop-prereleaseenvironment is used only for unsigned official0.xinstaller builds and contains no signing credentials. In preparation for releasing v1.0.0, but not for any0.xrelease, createdesktop-signing, protect it with required maintainer approval, allow it only from the protectedmainbranch, and store every installer-signing secret there. Only a reviewed v1.0.0-or-later manually dispatched pre-tag job may receive those credentials. Tag-triggered import and publication jobs must never receive them. For the current one-maintainer release, configuresodejmas the required reviewer forpypi; self-approval must remain permitted so the production deployment does not deadlock. Requiring a reviewer other than the workflow initiator is a future hardening step after a second maintainer exists. - Register pending Trusted Publishers on TestPyPI and PyPI for
sodejm/AncestryLLM, workflowrelease.yml, and the matching environment. Keep publishing OIDC-only; no API token or token secret is a permitted fallback. - Before releasing v1.0.0, configure the release-signing Actions secrets.
They are not required or permitted for any
0.xrelease. UseAPPLE_CERTIFICATE_BASE64,APPLE_CERTIFICATE_PASSWORD,APPLE_API_KEY_BASE64,APPLE_API_KEY_ID, andAPPLE_API_ISSUERfor the Developer ID identity and Apple notary API key;WINDOWS_CERTIFICATE_BASE64andWINDOWS_CERTIFICATE_PASSWORDfor the Authenticode identity; andLINUX_GPG_PRIVATE_KEY_BASE64andLINUX_GPG_PASSPHRASEfor the detached Debian-package signature. Configure repository Actions variablesAPPLE_TEAM_ID,WINDOWS_SIGNING_CERTIFICATE_THUMBPRINT,LINUX_GPG_SIGNING_FINGERPRINT, andLINUX_GPG_PUBLIC_KEY_BASE64with the approved public signer identities and Linux public key. Use the complete certificate thumbprint and complete Linux signing-key or signing-subkey fingerprint. For v1.0.0 and later, builder and validation jobs both fail unless the observed signer matches the approved public identity; Linux validation imports only the public key into a fresh keyring. Grant each private credential only the purpose named here, rotate it outside the workflow, and never put its decoded value in an artifact or repository file. Follow the repeatable macOS setup and verification procedure inDEPLOYMENT.md; do not construct ad hoc upload commands containing private values. - Confirm the repository can use GitHub’s hosted
windows-11-armrunner. Desktop verification asserts Windows 11 and an ARM64 host before using native ARM64 Python and Node.js to build and validate the shipped Windows ARM64 application. The locked desktop profile contains the base runtime and sidecar packager only. Every third-party Python dependency must have a prebuilt wheel; a missing wheel fails installation rather than starting a source compiler or external library toolchain. Only the local AncestryLLM application code is built. The installer builder records ARM64 for both host and artifact architecture in the release receipt. No self-hosted runner registration or lifecycle is required. - Enable GitHub immutable releases.
- Enable automatic deletion of merged pull-request branches.
These hosted controls are not created or changed by the repository workflows. An authorized maintainer must approve and verify each one in GitHub, PyPI, and TestPyPI before the first production release.
Hosted control verification checklist
Before the readiness run, verify and record each control in the selected GitHub Project 2 release evidence, with the verifier, date, and a settings-page link or redacted screenshot:
- the
mainruleset requires the named CI and CodeQL checks, signed commits, resolved review conversations, and blocks force pushes and deletion; - the
v*.*.*tag ruleset restricts creation and blocks update and deletion; - the
pypienvironment hassodejmas the required reviewer, while self-approval remains enabled for the current one-maintainer release; - for a v1.0.0-or-later release, the
desktop-signingenvironment requires maintainer approval, is limited to the protectedmainbranch, contains the installer-signing secrets, and is not used by any tag-triggered job; for a0.xrelease,desktop-prereleasecontains no signing credentials; - the TestPyPI and PyPI Trusted Publishers match repository
sodejm/AncestryLLM, workflowrelease.yml, and their exact environments, and no API-token publishing secret or fallback is configured; and - for v1.0.0 or later, the nine private release-signing secrets and four public
signer-identity variables are configured, access-restricted, and current;
the GitHub-hosted
windows-11-armvalidation row is required for every version; and - GitHub immutable releases and automatic pull-request branch deletion are enabled.
Any missing or mismatched control blocks readiness. After a second maintainer is available, separately approve and verify the change that disables initiator self-approval; do not make that change during the one-maintainer release.
Prepare and approve
- Complete every P0 GitHub Issue in the exact configured GitHub Project 2
Release iteration. A selected P0 issue must be closed with ProjectStatus: DoneandValidation: Verified. The workflow reads canonical Issue content by repository and issue number, rather than a Project item’s cached display title. Every item that explicitly names the configuredRelease iterationmust provide all four configured Project fields; legacy items outside that iteration may be incomplete. It paginates the Project item connection and follows nativeblockedBydependencies: an open dependency blocks release, while a closed historical or externally tracked dependency outside the selected iteration is accepted. A dependency in the selected iteration must beDoneandVerified. A truncated dependency response, missing Project access, malformed target-iteration field, or duplicate target-iteration item also blocks release. Close an item only after its implementation, documentation, regression tests, dead-code review, and required hosted checks are complete. - For every candidate
feature/*,bugfix/*, orhotfix/*branch and worktree, first confirm a clean status withgit status --short, then audit reachability and unique commits withgit rev-list --left-right --count main...<branch>andgit log main..<branch>. Only remove the worktree and use normalgit branch -d <branch>when it is clean and its work is fully reachable frommain; then confirm the remote branch was deleted. Never use-Dto make this check pass. Preserve and record any dirty or active worktree, graph-unique commits, unmerged branch, or abnormal deletion failure for explicit follow-up. A squash merge can leave graph-unique branch commits even when its tree exactly matchesmain; record that tree comparison and preserve the local branch instead of treating identical content as reachability or forcing deletion. The lifecycle attestation confirms the audit and every cleanup that was safe, not deletion of preserved history. -
Finalize the dated changelog, curated
docs/release-notes/<version>.md, and versioned findings/interoperability records underdocs/release-evidence/<version>/. Every finding needs an owner and expiry; every importer needs a dated evidence link, and only fictional-data manual imports may be marked verified.Use
uv version --shortas a read-only confirmation of the project version. Do not useuv version <version>to perform the release bump: the release contract spans.github/release-config.json,pyproject.toml, anddesktop/package.jsonplus the packaged sidecar/build identity. Update and verify those owned values together, regenerate the lock throughmake lock, and let the release-configuration verifier reject any drift. - Approve and merge a release-only preparation PR through the protected
mainruleset, after required checks pass and conversations are resolved. - Run the release-configuration verifier and confirm the exact configured
GitHub Project 2 P0 gate: every selected issue is
DoneandVerified, and each dependency in the selected iteration is closed and verified. Closed historical dependencies outside that iteration do not need to be added to the release Project. - Run
Release readinesswith the exactmaincommit and semantic version, and affirm the branch/worktree lifecycle audit input, backed by the documented reachability, unique-commit, cleanup, and preservation record. - Confirm the successful exact-head
Desktop sidecaraggregate is for the same commit and contains all six unpublished native-package rows. This is an input to the installer gate, not release-installer evidence by itself. - Review the evidence artifact and confirm every required job succeeded.
Every readiness, build, and release job that executes uv first uses the
verified uv bootstrap. Confirm the
bootstrap-verification gate in gates.json is verified, and that the
release manifest records the expected policy digest, uv release asset,
GitHub CLI verifier archive, source repository and commit/ref, signer workflow,
OIDC issuer, and SLSA predicate. A missing, failed, timestamp-invalid, or
identity-mismatched schema-v1 receipt blocks release. The stock-pip wheel and
sdist consumer smoke tests remain separate because they validate supported
installation paths; they cannot build or authorize a release.
At the exact approval points, a maintainer approves the release-preparation PR;
the readiness operator attests the cleanup audit and approves its evidence; the
maintainer approves creation and push of the annotated release tag; and sodejm approves
the pypi environment deployment. For this one-maintainer release, that final
approval may be self-approval by the workflow initiator. A separate explicit
approval is required for the GitHub-only fallback described below.
The workflow rechecks the exact configured GitHub Project 2 release gate and refuses any incomplete selected P0 item or target-iteration dependency. Closed historical dependencies outside that iteration are accepted. Local worktrees are machine-specific, so their cleanup is an explicit operator attestation recorded in the evidence bundle.
P0 is reserved for work that must complete before publication. An umbrella,
roadmap, or tracker designed to close after the release must be P1 or outside
the selected iteration; the verifier has no issue-number exception. This keeps
the P0 gate fail-closed while retaining post-release follow-up in Project 2.
The readiness workflow is the authoritative product-quality and security gate.
It records the exact commit, run URL, and complete gate inventory in
gates.json. The tag workflow rechecks the Project-native release gate,
requires that exact approved record, and imports the successful pre-tag
desktop-release-distributions artifact for the tag commit. It verifies the
GitHub Actions artifact digest plus the artifact’s internal manifest and
checksums before any asset is published. It never rebuilds approved installers
after the tag is pushed and does not repeat pytest, lint, type checking,
dependency audit, or Semgrep after accepting the exact successful readiness
and installer evidence.
The tag workflow is the only installer publisher. The installers are built and
validated by a manually dispatched pre-tag run, but cannot be
published until the v0.4.0 release is complete and the v0.5.0 tag gates pass.
Before the final release distribution can be assembled or any release asset can be published, it
requires all four installer rows. The Required native verification column is
version-aware: 0.x requires installation and installed-runtime execution but
does not require a trusted signature; v1.0.0 and later additionally require the
listed trusted-signing checks.
| Release row | Installer | Required native verification |
|---|---|---|
| macOS 15 arm64 | DMG | install/launch for 0.x; at v1.0.0+, approved Apple Team ID, Developer ID signature, hardened runtime, minimal entitlements, Gatekeeper, notarization, and stapling |
| macOS 15 x64 | DMG | install/launch for 0.x; at v1.0.0+, approved Apple Team ID, Developer ID signature, hardened runtime, minimal entitlements, Gatekeeper, notarization, and stapling |
| Windows 11 ARM64 | NSIS EXE | native build/install/launch on GitHub-hosted windows-11-arm; at v1.0.0+, approved certificate thumbprint and valid Authenticode signature |
| Ubuntu 24.04 x64 | DEB | install/launch on clean Ubuntu 24.04; at v1.0.0+, adjacent .deb.asc detached GPG signature from the approved public-key fingerprint |
Every row builds and smoke-tests the matching native sidecar, installs or
mounts the complete installer, launches the installed application with no
system Python, Node.js, or pnpm available on PATH, and emits an exact-head
receipt and CycloneDX SBOM. The aggregator rejects a missing row, failed gate,
wrong commit or version, duplicate asset name, malformed SBOM, symlink, or
digest mismatch. Native validation receipts also bind the canonical actual OS
derived from the host probe; aggregation and tag import require the exact six
intended-and-actual OS rows. Only after aggregation does the workflow regenerate the
complete release-evidence.md, create the one SHA256SUMS file, and attest
dist/*, so the evidence manifest, checksums, and provenance cover the Python
wheel and sdist together with every desktop installer, any required detached signature,
combined SBOM, desktop manifest, and exact-head evidence document.
Tag and publish
From a clean checkout whose HEAD is the approved main commit, derive the
version-dependent release-tag mode and create an annotated tag. Pre-1.0 tags
must be unsigned; v1.0.0-and-later tags must be signed. Confirm the release
commit first with git log --show-signature -1, then:
release_version="$(jq -er '.release' .github/release-config.json)"
release_tag="v${release_version}"
desktop_release_run="<successful pre-tag release workflow run ID>"
desktop_release_artifact="<desktop-release-distributions artifact ID>"
desktop_release_digest="sha256:<GitHub Actions artifact SHA-256>"
release_tag_mode="$(.venv/bin/python scripts/release_signing_policy.py \
--version "${release_version}" --tag-mode)"
.venv/bin/python scripts/verify_release_configuration.py \
--config .github/release-config.json \
--version "${release_version}"
tag_args=(
-m "AncestryLLM ${release_version}"
-m "Desktop-Release-Run-ID: ${desktop_release_run}"
-m "Desktop-Release-Artifact-ID: ${desktop_release_artifact}"
-m "Desktop-Release-Artifact-Digest: ${desktop_release_digest}"
)
if [[ "${release_tag_mode}" == "unsigned-annotated" ]]; then
git tag --no-sign -a "${tag_args[@]}" "${release_tag}" HEAD
else
git tag -s "${tag_args[@]}" "${release_tag}" HEAD
git tag -v "${release_tag}"
fi
git push origin "${release_tag}"
Push only the release tag. The tag-triggered workflow verifies the required
annotated-tag mode, exact readiness evidence, and exact pre-tag installer artifact;
the three Desktop-Release-* tag-message fields are mandatory and bind the
approval to one successful manual release-workflow run, one artifact ID, and
GitHub’s exact SHA-256 artifact digest. Obtain them from that run’s summary and
independently confirm them in the Actions artifact metadata before tagging.
The summary normalizes the upload-artifact output to the required
sha256:<64 lowercase hex> form; do not remove the sha256: prefix.
Release construction installs the locked build group and the security
group needed for SBOM generation, with no provider extras. Stock-pip wheel
and source-distribution smoke jobs remain unchanged because they validate the
published consumer experience rather than authorize a build.
Setuptools remains the production backend. The locked uv_build candidate and
make evaluate-uv-build exist only for the fail-closed 0.6 comparison recorded
in the uv_build evaluation; its incompatible result
does not authorize a backend change or weaken any release check.
Release construction uses SHA-pinned actions/setup-python with Python 3.12,
then the verified repository contract requires exactly uv 0.12.1, selects
only that system interpreter, and disables Python downloads. The workflow calls
the same make package and make sbom interfaces used locally after its narrow
locked synchronization.
The workflow then attests the combined artifacts; prepares a draft GitHub
Release; publishes to TestPyPI with attestations: false because TestPyPI does
not provide PyPI’s PEP 740 Integrity API; it verifies only the exact TestPyPI
artifact hashes; and pauses for required production approval. Production PyPI
publishing explicitly requests attestations: true. The workflow then verifies
the PEP 740 provenance for both the wheel and source distribution, including
exact repository, workflow, environment, filename, and SHA-256 identity, with
the pinned pypi-attestations==0.0.30 verifier. It preserves the provenance and
verifier output as evidence and fails closed. The workflow installs this tool
from the locked, non-default release-verifier dependency group so ordinary
release construction does not inherit its platform-specific build
dependencies. Full local make setup intentionally synchronizes all groups;
the production verification job remains isolated to release-verifier alone.
After production PyPI publishing, the supported platform/Python wheel-and-sdist
install smoke matrix runs before
the immutable GitHub Release. The attached SHA256SUMS covers
every release asset except the checksum file itself. No other workflow or
manual upload may publish an installer.
Documentation publication gate
The release workflow enforces documentation publication for the exact release
commit before the immutable GitHub Release is published. The
verify-docs-publication job runs as a required predecessor to
publish-github-release and performs two checks:
GitHub Pages (always required)
The Deploy documentation site (jekyll-gh-pages.yml) workflow must have a
successful completed run for the release commit SHA. This workflow runs
automatically on every push to main; if the release commit landed on main
and Pages deployment succeeded, the gate passes automatically. If the gate
fails, confirm that jekyll-gh-pages.yml completed successfully on main for
that commit, wait for any in-progress deployment to finish, and re-run the
release workflow.
Wiki synchronization (required when docs/** changed)
If the release commit modified any file under docs/, the Sync Wiki
(sync-wiki.yml) workflow must also have a successful completed run for that
commit. If docs/ was not changed in the release commit, Wiki sync is treated
as not required and the gate passes without checking it. If the gate fails
because Wiki sync is missing or failed, confirm that sync-wiki.yml completed
successfully on main for that commit and re-run the release workflow.
Both checks use exact commit SHA matching and query only status=success runs;
a workflow that is in progress or failed does not satisfy the gate.
Verify a downloaded installer
Download the target-matched full installer and the release’s SHA256SUMS from
the same immutable GitHub Release. Verify the checksum before opening the
installer. For a 0.x release, require binarySigningMode: "unsigned" and
releaseTagMode: "unsigned-annotated", and expect an operating-system
unknown-publisher or equivalent prompt; do not infer a trusted identity from
an unsigned binary. For v1.0.0 and
later, inspect the Developer ID signature and notarization/stapling on macOS,
require a valid Authenticode signature on Windows, and verify Ubuntu’s adjacent
.deb.asc with the documented release key. Do not install when a required
identity, digest, or signature check fails.
Manual upgrade and rollback
Quit AncestryLLM, download and verify the new target-matched full installer, then install it over the existing application and relaunch. The installer replaces application files but retains the OS-managed AncestryLLM data and configuration directories. Confirm the displayed version and healthy Diagnostics after relaunch. Recovery or rollback uses the same process with a previous full installer whose checksum and version-required signature still verify.
v0.5.0 has no updater feed, no background update, no staged rollout, and no
automatic rollback. Do not publish latest*.yml, blockmaps, or another update
channel, and do not represent manual reinstall behavior as an updater.
Failure and recovery
Retry only transient failed jobs. Never make an upload idempotent by silently skipping or overwriting an existing file.
If initial draft creation stops after a partial asset upload, verify that the release is still a draft and that the tag is unchanged, delete only that unpublished draft, and rerun the workflow. Draft reuse is accepted only when its title, body, complete asset inventory, checksum manifest, and every asset hash already match the workflow build exactly.
If PyPI remains unavailable after an approved retry, stop the failed workflow.
Only when the maintainer explicitly approves a GitHub-only release may the
draft be published, and only when the failure is external to the product and
artifacts, every non-index release gate passed, and the prepared draft still
contains the exact workflow-built assets. Download the release-distributions
artifact from that run and the draft assets into separate directories, then
require:
python scripts/verify_release_assets.py \
--expected /path/to/release-distributions \
--actual /path/to/draft-download
Before publishing the immutable draft, edit its body to state
PyPI: unavailable, link the failed workflow run, and remove every PyPI or
TestPyPI verification claim. Record that explicit approval in the tracking
issue. Do not use an API-token fallback, upload replacement files, or claim
that the GitHub-only release is available from a Python package index.
If a product or artifact defect makes a published version unusable, preserve its tag and release evidence, yank the PyPI version when appropriate, document the reason, and publish the next patch version. Never force-push or recreate a release tag. Historical 0.2.0 notes and evidence remain immutable when preparing later releases.