Helix CLI Session Contract v1
This document defines the black-box contract for the Helix CLI session lifecycle. It is enforced as bytes-on-disk, not as internal implementation behavior.
Scope
Contracted lifecycle:
simulate— produce a.helixsession from a configrun— alias ofsimulate(must be identical)report— produce deterministic HTML reports from a sessionexport— produce deterministic exported artifacts (JSON + PNG + provenance sidecar)simulate --append— append runs to an existing session in order
Guarantees
Under deterministic mode (PYTHONHASHSEED=0 + HELIX_DETERMINISTIC=1):
- Alias parity:
simulateandrunproduce byte-for-byte identical.helixsessions for the same config. - Deterministic artifact trees:
reportandexportare deterministic across repeated runs. - Filtered report determinism:
report --run-id <id>emits only the requested run’s report with stable output. - Export provenance coupling: exports include a PNG provenance sidecar that correctly hashes the emitted PNG.
- Append semantics:
simulate --appendpreserves run order (session evolution is deterministic).
Failure behavior (golden paths)
Contracted failures must be deterministic:
- Non-zero exit codes for invalid inputs.
- Stable error messages (at least at the “reason substring” level).
- Predictable partial outputs (e.g., created directories without a verdict when pack selection fails).
Contract hash normalization (v1)
The cross-platform gate compares a single contract hash derived from the full output tree. This is intentionally stricter than “does it run” and intentionally broader than “does one file match”.
Hash inputs:
- All files under the contract test’s output root directory are included.
- Paths are hashed by their relative POSIX path (stable across OS runners).
Per-file normalization rules:
- Non-PNG files: digest is
sha256(file_bytes). - PNG files (
*.png): digest issha256(decoded_RGBA_pixels + {size, mode}).- This ignores platform-specific PNG encoding differences (metadata/chunk ordering/compression), while still treating the image as deterministic data.
- PNG provenance sidecars (
*.png.provenance.json):- First, validate the sidecar’s
artifact_sha256exactly matchessha256(png_file_bytes)(byte-level binding). - Then, hash a canonicalized JSON payload where
artifact_sha256is rewritten to the PNG pixel digest (sha256_pixels:<…>), so the cross-platform comparison is pixel-stable.
- First, validate the sidecar’s
Tree hash:
- Build a JSON object
{relative_path: per_file_digest}with keys sorted. - Compute
sha256(canonical_json_bytes)where canonical JSON usessort_keys=Trueand separators(",", ":").
If any of the above normalization rules change, that is a spec change and requires a new contract version (v2), not an edit-in-place of v1.
Contract bump workflow (v1 → v2)
This contract is designed to be hard to change by accident.
To intentionally change behavior:
- Add new versioned files:
tests/e2e/test_cli_session_contract_v2.pydocs/cli/session_contract_v2.md
- Update documentation pointers:
mkdocs.yml(nav entry for the new version)docs/governance_contract.md(reference the new version)
- Add a changelog entry in
CHANGELOG.md.
Enforcement:
- The CI guard
tools/check_cli_session_contract_bump.pyforbids editing/deleting existingvNcontracts. - The cross-platform workflow always runs the latest
vNviatools/run_cli_session_contract.py.
Enforcement
Source of truth:
tests/e2e/test_cli_session_contract_v1.py
Cross-platform gate (Linux/macOS):
.github/workflows/cli-session-contract.yml
Any intentional behavioral or artifact-shape change to this lifecycle should be treated as a breaking change and versioned as a new contract (e.g., “v2”) rather than silently drifting “v1”.