T-saur

Logo

T-saur (.tsr): a content-addressed, deterministic archive format built for AI agents. Rust, Apache-2.0 OR MIT.

View the Project on GitHub iulianbondari/t-saur

Publication and release process

Two procedures: A is done once, when the repository goes public; B is done for every version. Both are executed by the maintainer, by hand, with the checks written next to each step; nothing here is automated beyond the workflows in .github/workflows/.

A. Publication (once)

Precondition: no open pull request (a history rewrite invalidates open branches).

A1. Clean history

The maintainer’s working material (docs/research/, benchmarks/check_names.sh) was removed from the tree on 2026-09-25 (docs/PROVENANCE.md) but is still present in earlier commits. Before the repository becomes public the history is rewritten once, while the repository is still private (the only situation in which a forced update of main is acceptable here).

Rehearsed on 2026-09-25 in a scratch clone with git-filter-repo 2.x:

git clone --no-single-branch https://github.com/iulianbondari/t-saur rewrite && cd rewrite
BEFORE=$(git rev-parse main^{tree})
git filter-repo --path docs/research --path benchmarks/check_names.sh --invert-paths --force
test "$(git rev-parse main^{tree})" = "$BEFORE" && echo "tree identical"        # must print
test "$(git log --all --oneline -- docs/research benchmarks/check_names.sh | wc -l)" -eq 0
git log --oneline main | wc -l                                                    # 33 in the rehearsal
git rev-list --max-parents=0 main                                                 # the new import commit

Rehearsal result: tree at the tip identical, 33 commits at the time, zero commits touching the removed paths, new root 29bc672 in place of 16eeeec. Executed on 2026-09-25 on the 43-commit history (docs/PROVENANCE.md has the record), with a mailmap that also normalised the author and committer identities. Then:

  1. git remote add origin https://github.com/iulianbondari/t-saur && git push --force origin main (the ruleset is not active yet; this is the one forced push, recorded here).
  2. Delete the merged branches that GitHub kept, if any (git push origin --delete <branch>), so that no ref points at the old history.
  3. Record in docs/PROVENANCE.md: the rewrite, the date, the old and new root commits, and the tree hash that proves the tip is unchanged. Commit through a pull request as usual.
  4. Let the CI run on main once (push event: all three systems) and check that it is green.
  5. Refresh the local mirror (git fetch origin && git reset --hard origin/main in a clean clone; the private development mirror keeps its own history).

Steps 1 to 5 were executed on 2026-09-25 (the CI run on the rewritten main was green on the three systems).

A1b. A new repository for the public history

A forced update of main does not remove the pull-request refs (refs/pull/<n>/head) that GitHub keeps, and through them the pre-rewrite commits and the removed notes stayed reachable in the development repository. The public repository is therefore a new one, under the same name, and the development repository keeps everything else:

  1. Wait until no session or workflow is writing to the development repository.
  2. Settings → General → Rename the development repository to t-saur-dev; it stays private (pull requests #1 to #19, the CI runs and the old history stay there).
  3. Create t-saur empty and private: no README, no license, no .gitignore (the tree brings its own).
  4. From a fresh clone of t-saur-dev at the tip of main:

    git clone --branch main --single-branch https://github.com/iulianbondari/t-saur-dev pub && cd pub
    git rev-parse main main^{tree}; git rev-list --count main; git rev-list --max-parents=0 main
    test "$(git log --all --oneline -- docs/research benchmarks/check_names.sh | wc -l)" -eq 0
    git log --all --format='%an <%ae>%n%cn <%ce>' | sort -u          # only the published identities
    git remote set-url origin https://github.com/iulianbondari/t-saur
    git push -u origin main                                           # main only, no tags, no other branch
    
  5. Verify from a fresh clone of t-saur: same tip, tree, count and root as printed in step 4; git ls-remote shows refs/heads/main and nothing else.
  6. Record the result in docs/PROVENANCE.md (“Published as a new repository”) through a pull request in the new repository, then continue with A2 there. A new repository starts with GitHub’s defaults, so every setting of A2 is set again, not merely confirmed.

Executed on 2026-09-25: t-saur-dev main 410a58b → t-saur main 3e7f728, tree identical, 57 commits; in step 4 the mailmap of A1 was applied once more to the fourteen commits made after the rewrite (docs/PROVENANCE.md has the table). The review issue of A3 was re-created as issue #1 of the new repository and the first workflow run was started by hand.

A2. Visibility, rules, preview

  1. GitHub → Settings → General → Danger zone → Change repository visibility → Public.
  2. Apply the ruleset: Settings → Rules → Rulesets → Import a ruleset with .github/rulesets/main.json (or gh api -X POST repos/iulianbondari/t-saur/rulesets --input .github/rulesets/main.json). Check afterwards that a test pull request shows the three required checks.
  3. Settings → General → Social preview → upload docs/brand/tsaur-social-preview.png (1280 × 640). The option appears only on a public repository.
  4. Set the settings chosen on 2026-09-25 for the development repository: release immutability on, rebase merging off, “always suggest updating pull request branches” on, automatic deletion of head branches on, Dependabot alerts, dependency graph and malware alerts on, security and version updates off (updates go through pull requests and the gate), workflow permissions read-only (the workflows declare what they need).
  5. Settings → Advanced Security → Private vulnerability reporting → Enable: SECURITY.md and the issue template send reporters there, and it is off by default on a newly public repository.
  6. Repository page → About → topics (archive-format, archiver, compression, rust, content-addressed, deduplication, erasure-coding, ai-agents, mcp, post-quantum-cryptography, blake3, zstd) and, if wanted, a homepage.
  7. Wikis stay off (documentation lives in docs/); Discussions are the maintainer’s call.
  8. Start the workflow once by hand (workflow_dispatch on main) so that the public repository has its own green run on the three systems.

A3. Independent review

Open an issue “Independent review of 1.0.0-rc” in the public repository that links docs/review/REVIEW-PACKAGE.md and the verification reports, states the scope (the same as the package’s §2) and what the reviewer gets (credit in CHANGELOG.md and the report published under docs/review/). The review is the evaluator’s own work; the producer’s checks are not a substitute.

A4. Two-device measurements

Run docs/design/TWO-DEVICE-BENCHMARK-PLAN.md §0 on two real machines of the maintainer (one Ethernet run, one Wi-Fi run; --plain once for comparison). Commit the generated RESULTS-two-devices.md as benchmarks/RESULTS-two-devices.md with the commit hash of the binaries. A run with both roles on one machine is labelled by the tool as a tooling check and does not count.

B. Cutting a release (every version)

  1. Gate. On the release commit: python tools/release_gate.py --robustness-seconds 60 --report docs/review/RC<n>-VERIFICATION-REPORT-<platform>.md on at least Windows and Linux, both release binaries built first; all steps must pass. Any golden test failure is a format event: stop, record the first differing bytes, decide.
  2. Version. Bump version in tsaur/Cargo.toml ([workspace.package]), version and date-released in CITATION.cff, the heading in CHANGELOG.md; cargo metadata --locked must still succeed with Cargo.lock unchanged except for the workspace crates. Pull request, CI green, merge.
  3. Tag. git tag -a v<version> -m "T-saur <version>" <merge commit> && git push origin v<version>. The tag starts .github/workflows/release.yml: lite packages for the three systems, tests run on each, SHA256SUMS, and a draft release.
  4. Check the draft. Download each package, verify it against SHA256SUMS, unpack in a clean directory and run python tools/check_guide.py --tsaur <unpacked binary>; compare the sizes with dist/PACKAGES.md of the local gate run. Fill the release notes from CHANGELOG.md; state that the full build is available from source only (docs/DISTRIBUTION-POLICY.md).
  5. Publish the draft. Release immutability is on: the assets and the tag cannot change afterwards; a mistake means a new patch version.
  6. Registries: cargo publish -p tsaur-core then cargo publish -p tsaur from the tagged commit (the maintainer’s crates.io account, a token scoped to publish-new/publish-update and to the two crates, or trusted publishing from the release workflow once configured); PyPI and npm follow the bindings on the roadmap. Never publish from a dirty tree or an untagged commit. The release candidate 1.0.0-rc.1 was published on 2026-09-26 from 13c24b5 (main, not a tag: the one exception, made to hold the crate names and to open docs.rs; the .cargo_vcs_info.json in each .crate records the commit).
  7. After. ROADMAP.md and docs/V1-CONTRACT.md §5 updated with what actually ran; the next ## [Unreleased] section opened in CHANGELOG.md.

C. What must never happen