feat: 0.1.0
Some checks failed
distribution-gate / distribution-gate (push) Failing after 1m56s

This commit is contained in:
eric
2026-04-04 18:41:34 +02:00
parent 32147d4552
commit ebb6b488fe
48 changed files with 2541 additions and 139 deletions

145
docs/distribution.md Normal file
View File

@@ -0,0 +1,145 @@
# Distribution Contract for `codex-controller-loop`
## v1 Contract
This document defines the first stable, versioned distribution contract for the Rust controller binary. It is the canonical compatibility and consumption reference for external projects.
## 1) Contract version and release identity
- Contract version: `distribution-contract@1.0`
- Release artifact identity is immutable for a given tuple:
- `artifact_version` (semver)
- `git_rev` (full SHA, immutable reference)
- `toolchain` and `build_profile`
- `target`
- `dist_revision` (incrementing revision when rebuilds occur for the same release tuple)
- Consumers must pin by immutable tuple, never by moving tags.
## 2) Canonical artifact entrypoint
- Primary entrypoint: `codex-controller-loop` CLI.
- Canonical binary names:
- `codex-controller-loop` (single binary)
- Canonical distribution entrypoint index: `dist/index.json`.
- Deprecated compatibility entrypoint (removed after 2026-07-01): `dist/{distribution_contract_version}/index.json`.
## 3) Canonical dist layout and naming
- `dist/` is the only published artifact namespace.
- Directory template (contract version stable):
- `dist/{distribution_contract_version}/{artifact_version}/{target}/{profile}/{toolchain}/{gitsha}/{dist_revision}/`
- Example: `dist/1.0.0/0.1.0/x86_64-unknown-linux-gnu/release/1.84.0/ab12cd34/r1/`
- Canonical artifact filename:
- `codex-controller-loop-v{version}-{target}-{profile}-{rust}-{gitsha}-{dist_revision}.{ext}`
- `version` = semver release (e.g. `1.4.2`)
- `target` = Rust target triple
- `profile` = `release` or `debug`
- `rust` = rustc version string used in build
- `gitsha` = short git commit hash of source revision
- `dist_revision` = `r1`, `r2`, ... for immutable re-build iterations
- `ext` = container format used by release pipeline (e.g. `tar.gz`)
- Canonical generator entrypoint:
- `scripts/release-orchestrator.py` (single orchestrator)
- Controlled by `scripts/release-orchestrator.config.json`
- Index manifest output: `dist/index.json`
- Deterministic provenance snapshot in generated index:
- Each index artifact row is keyed by `version + target + profile + toolchain + gitsha + dist_revision`
- `artifact_file`, `manifest_file`, `checksums_file`, `artifact_sha256`, and `source_date_epoch` are emitted
## 8) Consumer integration examples
Use the canonical index first, then fail fast if no rows match the requested immutable tuple. Optional legacy fallback is accepted only during migration.
```bash
VERSION=0.1.0
TARGET=x86_64-unknown-linux-gnu
PROFILE=release
TOOLCHAIN=1.84.0
GITSHA=ab12cd34
DIST_REVISION=r1
INDEX=dist/index.json
if [ ! -f "$INDEX" ]; then
INDEX=dist/1.0.0/index.json
echo "warning: using deprecated index path, remove by 2026-07-01"
fi
ARTIFACTS=$(jq -r --arg version "$VERSION" --arg target "$TARGET" --arg profile "$PROFILE" \
--arg toolchain "$TOOLCHAIN" --arg git "$GITSHA" --arg dist "$DIST_REVISION" \
'.releases[] | select(.version==$version) | .targets[] | select(.target==$target) | .profiles[] | select(.profile==$profile) | .artifacts[] | select(.toolchain|startswith($toolchain)) | select(.git_rev|startswith($git)) | select(.dist_revision==$dist) | .artifact_file' "$INDEX")
COUNT=$(printf "%s\n" "$ARTIFACTS" | awk 'NF {count += 1} END {print count + 0}')
if [ "$COUNT" -ne 1 ]; then
echo "expected exactly one artifact for immutable tuple" >&2
exit 1
fi
ARTIFACT_FILE=$(printf "%s" "$ARTIFACTS")
echo "resolved artifact: $ARTIFACT_FILE"
PACKAGE_DIR="${ARTIFACT_FILE%/*}/package"
CHECKSUMS="$PACKAGE_DIR/checksums.json"
python - <<PY
import hashlib, json, pathlib
artifact = pathlib.Path("${ARTIFACT_FILE}")
checksums = json.loads(pathlib.Path("${CHECKSUMS}").read_text())
actual = hashlib.sha256(artifact.read_bytes()).hexdigest()
if actual != checksums["artifact_sha256"]:
raise SystemExit("artifact checksum mismatch")
print(f"artifact sha256: {actual}")
PY
```
## 4) Release compatibility matrix
| Platform | OS | Arch | Binary compatibility | Runtime assumptions | Notes |
| --- | --- | --- | --- | --- | --- |
| Linux | Linux | `x86_64` / `aarch64` | Recommended | UTF-8 locale and terminal (TTY) | Required for TUI rendering |
| macOS | Darwin | `aarch64` / `x86_64` | Recommended | UTF-8 locale and terminal (TTY) | Build validation expected |
| Windows | Windows | `x86_64` | Planned / not guaranteed | UTF-8 locale and terminal (TTY) | Future support candidate |
- Rust compatibility: Release pipelines are required to document exact `rust` toolchain versions per artifact.
- Source compatibility is guaranteed only for the same `distribution_contract_version` and `artifact_version` tuple.
## 5) Checksums and integrity
- Every release artifact must include `checksums.json`, `manifest.json`, and `provenance.json`.
- All checksums use SHA-256.
- Consumers treat a release as valid only if:
1. Artifact checksum matches manifest entry.
2. Manifest has reproducibility metadata matching expected tuple (version, target, profile, toolchain, git rev).
## 6) Retention and migration
- The canonical contract file is immutable once published for a release version.
- Backward compatibility matrix changes require a migration note in the contract changelog.
- Deprecated/removed platform support is announced via the changelog and removed only after a deprecation cycle.
- Contract index migration note: `dist/{distribution_contract_version}/index.json` is a temporary compatibility alias and is retired on **2026-07-01**.
## 7) Changelog and compatibility governance
- Compatibility assumption changes require a changelog entry in `docs/distribution-changelog.md`.
- Contract fields are first-class API: any consumer-facing contract change must update:
- `docs/distribution.md`
- `docs/distribution-contract.json`
- `docs/distribution-changelog.md`
## 8) Source-of-truth documents
Machine-readable contract file: `docs/distribution-contract.json`
The JSON contract is the machine-readable interface; this ADR should be treated as the human-readable interpretation.
## 9) Operational governance and release hygiene
- Release ownership handoff is explicit and bounded:
- The active release steward must own the distribution contract updates for the PR.
- Ownership is transferred only after `docs/distribution.md`, `docs/distribution-changelog.md`, and `docs/distribution-contract.json` are updated together.
- Handoff requires at least one release cycle of overlap so downstream consumers have a recovery window.
- Deprecation workflow is fixed:
- Legacy index path support remains for the documented minimum notice period.
- Any compatibility assumption change requires a changelog entry and a migration step before sunset.
- Minimum retention window:
- Keep at least six release generations in the contract retention policy.
- Do not remove deprecated aliases before the contract's documented notice date and retention cleanup policy are both met.