← Docs
Helix CLI docs
Browse Helix CLI docs

Helix CLI Session Contract v3

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.

v3 is a contract bump over v2 with one additional product guarantee: exported artifacts embed the full scientific contract header (policy/semantics/determinism/backend fingerprint), including explicit downgrade markers when an escape hatch is used.

Scope

Contracted lifecycle:

  1. simulate — produce a .helix session from a config
  2. run — alias of simulate (must be identical)
  3. report — produce deterministic HTML reports from a session
  4. export — produce deterministic exported artifacts (JSON + PNG + provenance sidecar)
  5. simulate --append — append runs to an existing session in order

Guarantees

Under deterministic mode (PYTHONHASHSEED=0 + HELIX_DETERMINISTIC=1):

  • Alias parity: simulate and run produce byte-for-byte identical .helix sessions for the same config.
  • Deterministic artifact trees: report and export are 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 --append preserves run order (session evolution is deterministic).
  • Contract stamping: session and export provenance include contract_id + contract_hash so evidence bundles are portable across time/CI logs.
  • Scientific contract header stamping (new in v3):
    • *.export.json payloads include a top-level header that binds: policyHash, semanticHash, determinismClass, and backend fingerprint (backend.kind, backend.details).
    • Any explicit downgrade (e.g., D2 unpinned policy escape hatch) is emitted as an auditable entry under header.downgrades.
    • Any contract identity env fallback used by the writer is recorded as provenance_block.contract_env_fallback_keys.

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 stamp (v3)

Artifacts include:

  • .helix session header:
    • contractId (string, e.g. cli_session_contract_v3)
    • contractHash (string, v3 contract hash)
  • *.export.json provenance block:
    • contract_id
    • contract_hash
  • *.png.provenance.json:
    • contract_id
    • contract_hash

contract_hash is a constant shipped in code and updated only via the vN → vN+1 bump workflow.

Compatibility (downgrade story)

Artifacts are version-stamped. Verification tooling should never claim “OK” for an artifact governed by a newer contract than it understands.

If you try to verify a v3-stamped artifact with a tool that only supports v2, verification fails deterministically:

  • Exit code: non-zero
  • Error substring: unsupported cli session contract: cli_session_contract_v3 (tool supports up to v2)

This is intentional: older tools cannot safely validate newer contract semantics (normalization rules, lifecycle behavior, and failure taxonomy). The correct fix is to upgrade the Helix toolchain used for verification.

Downgrade is a tooling/verification compatibility story only; it does not “downgrade” the underlying simulation semantics or re-interpret artifacts to match older assumptions.

Contract hash normalization (v3)

The cross-platform gate compares a single contract hash derived from the full output tree.

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) except for contract-stamped JSON (below).
  • PNG files (*.png): digest is sha256(decoded_RGBA_pixels + {size, mode}).
    • This ignores platform-specific PNG encoding differences (metadata/chunk ordering/compression), while still treating the image as deterministic data.
  • Contract-stamped JSON (*.helix, *.export.json):
    • Parse JSON.
    • Strip contract_hash / contractHash keys (to avoid self-referential hashing).
    • Digest is sha256(canonical_json_bytes) where canonical JSON uses sort_keys=True and separators (",", ":").
  • PNG provenance sidecars (*.png.provenance.json):
    • First, validate the sidecar’s artifact_sha256 exactly matches sha256(png_file_bytes) (byte-level binding).
    • Then, hash a canonicalized JSON payload where:
      • artifact_sha256 is rewritten to the PNG pixel digest (sha256_pixels:<…>) (pixel-stable across OS),
      • contract_hash is stripped (to avoid self-referential hashing).

Tree hash:

  • Build a JSON object {relative_path: per_file_digest} with keys sorted.
  • Compute sha256(canonical_json_bytes) where canonical JSON uses sort_keys=True and separators (",", ":").

If any of the above normalization rules change, that is a spec change and requires a new contract version (v4), not an edit-in-place of v3.

Enforcement

Source of truth:

  • tests/e2e/test_cli_session_contract_v3.py

Cross-platform gate (Linux/macOS):

  • .github/workflows/cli-session-contract.yml