Last updated: 2026-09-05
How SAFi's code moves from development to something a production deployment can verify. This is the operator- and contributor-facing description of the process; the developer-side boundary rules live in the Developer Guide, section 19.
| Tier | What it is | Who should use it |
|---|---|---|
dev branch |
Active development. Changes land here first, tested but still settling. | Contributors and the curious. |
main branch |
Stable. Advances only by deliberate promotion from dev after work has soaked. |
Evaluations, development against SAFi. |
| Official releases | Tags cut from main, each publishing its TCB Fingerprint. |
Production. |
git clone gives you main, which is kept stable and is fine for trying
SAFi out. Production installs should use the latest release instead, because
only a release is verifiable: its notes publish the TCB Fingerprint of the
exact code it contains, and no branch offers that anchor.
Releases target an 8-week cadence (anchored on v1.4.1, August 2026). The
final week of each cycle is a freeze: a last promotion from dev to main,
then fixes only until the tag is cut. A target is not a contract; if a cycle
ends with something half-settled, the release waits for it rather than
shipping it.
Releases use three-part semantic versions (vMAJOR.MINOR.PATCH, e.g.
v1.5.0), tags lowercase, release titles matching their tags. The parts
carry governance meaning, so the number answers the operator's real
question: do I need to re-verify and re-pin?
- PATCH (
v1.5.1): fixes only. Normally the TCB Fingerprint is unchanged, so a pinned deployment can take the patch without updatingSAFI_EXPECTED_FINGERPRINT. When a fix must touch the Core Loop, the release notes say so loudly and the fingerprint changes. - MINOR (
v1.5.0): the regular cadence releases. Features and reviewed Core Loop changes; expect a new TCB Fingerprint and read the upgrade notes. - MAJOR (
v2.0.0): breaking for operators. Manual migration steps, API breaks, or changes to what the Core Loop covers.
Releases before this convention used two-part versions (v1.4); from
v1.5.0 on, versions are always three parts.
- A tag on
main, with notes covering what changed and any upgrade steps. - A
TCB Fingerprint:line: the SHA-256 root fingerprint over the Core Loop files (the Trusted Computing Base), computed from the tagged tree's own integrity manifest. This value is what makes the release the production tier. - A registry entry: the same fingerprint appended to the official release
list at
https://selfalignmentframework.com/tcb/releases.json, the machine-readable source of truth for the "Verify this Install" button.
Anyone can check what a deployment is running, without the vendor's help:
python scripts/verify_integrity.pyThe script hashes the Core Loop against the shipped manifest, checks the
structural invariants (no model call inside a deterministic faculty, phase
order intact), and prints the tree's TCB Fingerprint. Compare that value
against the TCB Fingerprint: line on an official release: a match means
the deployment runs that release's Core Loop, byte for byte. The same
fingerprint is stamped into every governance record the deployment
produces, so the comparison also works retroactively, from the audit trail
alone.
Operators can additionally pin their deployment: set
SAFI_EXPECTED_FINGERPRINT in .env to the fingerprint copied from the
release you installed. Every boot then re-checks the running code against
the value you verified, a mismatch is logged loudly, and
SAFI_ENFORCE_INTEGRITY=strict refuses to start on one. Update the pin
when you upgrade; that update is you re-performing the check against the
new release's published value.
The site at https://selfalignmentframework.com/tcb/ publishes the append-only list of official release fingerprints. Each new release adds one entry; no entry is ever removed, so an old install remains recognisable as authentic for as long as it runs.
The list is signed. The whole file is signed with the project's registry
signing key (minisign, legacy raw-message format), and the signature is
published next to it as releases.json.minisig. The public half of the key
is published on the site as TCB_KEY.pub and committed to the repository
at safi_app/api/tcb_key.pub; the two copies are byte-identical (compare
SHA-256). The git history is the anchor outside the website: someone who
controls only the site cannot mint a new list, because they do not hold the
secret key, and a deployment whose pinned key differs from the publisher's
rejects the list instead of trusting it.
The product's Verify this Install button (Org settings, org admin role)
reads this registry directly. It hashes the deployment's Core Loop, fetches
the list, and checks the signature against the pinned key before trusting a
single fingerprint. It then reports one of five verdicts: authentic
(signature verified and fingerprint in the list), unreleased (intact but
not in the list, i.e. a dev snapshot or a fork), modified,
unverifiable (no verdict is possible: the local check failed, or the list
was reachable but did not authenticate), or offline (the list could not
be fetched; never a pass). Every check is written to the compliance log.
A reachable site serving a list that does not authenticate is always
unverifiable, never offline and never a pass.
Adding the entry is part of the release, not a follow-up. On the site repository:
- Append
{"tag", "date", "fingerprint"}tostatic_site/tcb/releases.json. - Sign the result with the owner's secret key:
python scripts/tcb_sign.py static_site/tcb/releases.json \ ~/.safi/tcb-sign.key ~/.safi/TCB_KEY.pubThe script bumps thesequencefield, signs, and verifies before finishing. A release is a new sequence, never an edit of an old entry. - Publish
releases.jsonandreleases.json.minisigtogether, then rebuild and deploy the static site.
The secret signing key lives offline (default ~/.safi/tcb-sign.key,
chmod 600), never in the repository and never on the web host.
Anyone can re-verify a published list without the product:
curl -O https://selfalignmentframework.com/tcb/releases.json \
-O https://selfalignmentframework.com/tcb/releases.json.minisig \
-O https://selfalignmentframework.com/tcb/TCB_KEY.pub
minisign -Vm releases.json -p TCB_KEY.pubThat performs the same authenticity check the button performs locally: file bytes, not a view of them.
The AGPL permits running modified SAFi, including modified Core Loop code, with no functional restriction. What modification changes is certification, and there are exactly two states:
- Authentic: the deployment's TCB Fingerprint matches an official published release. Modified Core Loop changes reach this state one way: submitted upstream as a pull request, reviewed, accepted, and shipped in a release.
- Not authentic: everything else. A fork that keeps Core Loop changes private runs fully and governs fully, and its own records still attest to its own build, but it cannot use the SAFi name or claim authenticity (License & Governance Agreement, Section IV).
No local command crosses that line. Regenerating a manifest
(verify_integrity.py --update) only makes a tree consistent with itself.
Fixes land on dev like everything else and are promoted to main
immediately when urgent, followed by a point release when the fix touches
anything a production install runs. Point releases publish their own TCB
Fingerprint like any other release.