# Release readiness

The SDK builds a local `t3-0.3.0.tar` archive for the `t3` release on Hex.
The release owner is `dl-alexandre`. Guest sharing remains outside the validated
0.1.0 release scope by the maintainer's decision.
The CI workflow builds and tests only: it contains no publishing step, account
credentials, T3 tokens or live-environment configuration.

## Resume and bounded work validation (0.3.0, unpublished)

All 96 local tests passed (six opt-in live tests excluded), including cursor
checkpoint/ACK ordering, busy queue admission, worker ordering/failure/timeout,
and ticket cache TTL/invalidation. Live read-only probes confirmed shell/thread
`afterSequence` resume, completion markers, full-active-shell omission options,
bearer ticket reuse and rejection after parent revocation. A supervised Reader
resumed its consumed sequence with a cached ticket after a forced disconnect.
Temporary sessions were revoked. The 0.3.0 archive also compiled with fresh
dependencies and native code in an isolated production build; Cursor, WorkQueue,
Reader, LocalAuth and the stream-contract guide were present.

This corrects the earlier assumption that all RPC tickets are single-use.
Bearer tickets are reusable until server/parent expiry; DPoP proofs retain their
anti-replay requirement. Ticket caching remains opt-in and disabled by default.
See [stream contracts](docs/STREAM_CONTRACT.md) and
[authentication](docs/AUTHENTICATION.md). No durable audit stream or generic
cross-stream total ordering is claimed. This version is not yet published.

## Board reader validation (0.2.0)

The board additions passed 84 local tests with six opt-in live tests excluded.
Focused fixture tests exercised reconnect/re-subscribe, fresh credential callback
invocation, catch-up reads, consumption-before-ACK, ended streams, stalled health
reads and shutdown. Board reducers covered project-only enrichment snapshots,
host isolation and historical run/message updates. Formatting, compilation,
ExDoc with warnings as errors and the local Hex archive build passed. The 0.2.0
archive also compiled with fresh dependencies in an isolated production build;
all three new APIs, both board guides and runtime catalogs were present.

Live read-only probes against T3 Code 0.1.1 confirmed shell/thread snapshot
payloads, local session caching, distinct RPC tickets and normalization of shell
rows. A forced RPC disconnect recovered through `T3.RPC.Reader`, obtained a fresh
ticket and received a new shell subscription snapshot. All temporary service
sessions were revoked. Thread update-envelope examples are contract-derived;
no live thread mutation was performed. See [the board guide](docs/BOARD_READER.md)
and [recorded payloads](docs/BOARD_EVENTS.md).

## CI coverage

The project targets OTP 29. `.mise.toml` pins OTP 29.1.2 and Elixir 1.20.5
(compiled for OTP 29). The GitHub Actions workflow checks this same pair on:

- Ubuntu 24.04.
- macOS 15, including Exile's native build.

Every pairing compiles and tests with warnings treated as errors. The primary
Linux job also checks formatting, prints the offline interface inventory, builds
ExDoc with warnings treated as errors and builds the local Hex archive. Formatting
uses one Elixir release because formatter output can vary between versions.
Dependency/build caches are separated by operating system, architecture and both
runtime versions. Jobs use GitHub-hosted runners, which include the C compiler and
`make` required by Exile. Linux and macOS are the supported native CLI platforms.

The action references are pinned to reviewed upstream commits. Version sources:
[setup-beam compatibility and inputs](https://github.com/erlef/setup-beam),
[Elixir 1.20.5 release assets](https://github.com/elixir-lang/elixir/releases/tag/v1.20.5),
[checkout](https://github.com/actions/checkout), and
[cache](https://github.com/actions/cache), and
[OTP 29.1.2](https://github.com/erlang/otp/releases/tag/OTP-29.1.2).

The repository is public at `dl-alexandre/t3-elixir`. Both platform jobs passed
for commit `6c78657a9317f0a13afa2b8401ee77b4c548b153` in
[the recorded CI run](https://github.com/dl-alexandre/t3-elixir/actions/runs/42066189074).

## Recorded local validation

On 2026-11-05, all 67 local tests passed on this Mac with Elixir 1.20.5 /
OTP 29.1.2 in a fresh build directory; four live tests were excluded from that
local suite. The remote matrix result is recorded separately above.
OTP 27/28 are outside this project's current support target.

The same versions are the local global Mise defaults. Existing shells with
inherited version-specific PATH entries need a Mise environment refresh.

All four opt-in live smoke checks passed against T3 Code 0.1.1 on 2026-11-05:
public environment metadata, authenticated HTTP shell snapshot, authenticated
WebSocket RPC server configuration, and external OAuth MCP discovery/project
and thread reads. The native checks ran together (three passed, MCP skipped);
the OAuth MCP check ran separately after read-only approval (one passed, three
skipped). The temporary native credential was revoked after validation.

Two additional disposable attachment tests passed against the same server:
text and PNG upload, byte-for-byte capability download, and pending attachment
deletion. Media ticket issuance returned HTTP 200. Temporary native credentials
were revoked after each run.

Browser media validation also passed using a disposable server tab: a scoped
media ticket authenticated the raw WebSocket; JPEG frames were received and
acknowledged; a file-picker multipart upload returned HTTP 204 and the page read
the exact uploaded text; a browser download matched the expected bytes. The tab
and its downloads were removed, and temporary credentials were revoked.

The initial device discovery HTTP 503 was caused by the device hub not running.
Refreshing through T3's device tool installed/started the required hub 0.19.1;
the SDK device discovery endpoint then returned HTTP 200. No devices were
available, so simulator/emulator media remains unverified. Guest sharing was
disabled and T3 Connect authorization was missing, so guest-share SSE remains
unverified. Other mutation workflows beyond pending attachment deletion remain
unverified.

The archive was extracted into a clean temporary directory, resolved fresh
dependencies and compiled with `MIX_ENV=prod` and warnings as errors. Exile rebuilt
its native code; all packaged catalogs loaded and the packaged CLI ran
`t3 --version` successfully. Archive inspection found the required docs/notices
and no build artifacts or credential-pattern matches.

CI also passed for commit `197c5d3f1730a2a46855d0d22ea28b57b2aaed1c` in
[the subsequent run](https://github.com/dl-alexandre/t3-elixir/actions/runs/42071214563). See
[LIVE_TESTING.md](LIVE_TESTING.md) for exact variables and limits.

## Before publishing a release

1. The chosen Hex package and OTP application name are `t3`, next version `0.3.0`.
   Recheck name availability before first publication; a lookup does not reserve it.
2. The SDK repository is `https://github.com/dl-alexandre/t3-elixir`. Source and
   homepage links and GitHub maintainer identity are configured in `mix.exs`.
   Confirm the intended Hex owner and repository visibility before publication.
3. Review `LICENSE`, the included upstream MIT notices, dependency licenses,
   `README.md`, `INTERFACES.md`, and the changelog for the final package identity.
4. Push the repository and confirm all CI matrix jobs pass. Check the declared
   minimum locally or in CI; do not raise or lower it based only on a successful
   run with the developer's newer Elixir version.
5. Run opt-in live checks with explicitly supplied, appropriately scoped test
   credentials. Verify authenticated HTTP/RPC, upload/download, guest-share SSE
   and media flows relevant to the release. Local fixtures prove transport
   behavior, not every operation's live business semantics. Do not enable live
   checks in fork pull-request CI or log tokens, cookies, callbacks or proof data.
6. Decide the tested T3 version/revision policy and document any compatibility
   exceptions. Reconcile the pinned catalogs with the actual release target.
7. Run the local release checks below and inspect the archive contents. Unpack
   it into a clean directory and compile in production to catch missing runtime
   catalogs and private files.
8. Confirm the account/organization that will own the Hex package. Authenticate
   interactively on the publishing machine when ready. Publishing is a separate,
   explicit user action; neither CI nor this checklist authorizes publication.
9. Only after that explicit decision, publish the intended version and docs,
   verify the public package, and create the matching repository release/tag.

## Local checks

```sh
mix deps.get
mix format --check-formatted
mix compile --warnings-as-errors
mix test --warnings-as-errors
mix t3.interfaces
mix docs --warnings-as-errors
mix hex.build
```

`mix hex.build` creates a local archive and never publishes it. The release
workflow leaves credential entry and final publication outside automation. The
repository and package identity are configured. Verify CI and live integration
results before the separate decision to publish.
