← Docs
Helix CLI docs
Browse Helix CLI docs

Hub end-to-end v0 (Decision → Proof → Review → Approve → Proof)

This page is the minimal “DecisionOps loop” using local-only primitives.

0) Prepare a proposed bundle (no approvals)

Start from the shipped example bundle and strip approval receipts to create a “proposed” bundle:

rm -rf out/proposed_bundle
mkdir -p out
cp -R fixtures/hub_example_bundle_v1 out/proposed_bundle
rm -f out/proposed_bundle/receipts/approval_receipt_v1.json

./venv/bin/python - <<'PY'
import json
from pathlib import Path

p = Path("out/proposed_bundle/bundle_manifest_v1.json")
m = json.loads(p.read_text(encoding="utf-8"))
m.setdefault("receipts", {})["approval_receipt_digests"] = []
p.write_text(json.dumps(m, sort_keys=True, separators=(",", ":")) + "\n", encoding="utf-8")
PY

1) Verify and capture digests

helix hub verify bundle out/proposed_bundle --require-signatures

Record:

  • manifest: sha256:... (this is the proposed_bundle_digest)
  • core: sha256:... (bundles with different receipts can share the same core digest)

2) Create a Decision (local store)

Pick a local hub root:

export HUB_ROOT=var/hub_demo

Note: --hub-root can appear anywhere inside helix hub ... commands. These are equivalent:

helix hub --hub-root "$HUB_ROOT" decision export --format json
helix hub decision --hub-root "$HUB_ROOT" export --format json
helix hub decision export --hub-root "$HUB_ROOT" --format json

If --hub-root is specified more than once, the CLI fails closed.

Extract the policy + backend fingerprint digests from the bundle manifest:

./venv/bin/python - <<'PY'
import json
from pathlib import Path

m = json.loads(Path("out/proposed_bundle/bundle_manifest_v1.json").read_text(encoding="utf-8"))
print("policy_digest=" + m["inputs"]["policy_digest"])
print("backend_fingerprint_digest=" + m["producer"]["backend_fingerprint_digest"])
PY

Create the Decision (replace PROPOSED_BUNDLE_DIGEST with the manifest: ... value from step 1):

helix hub --hub-root "$HUB_ROOT" decision create \
  --decision-id DECISION123 \
  --workspace-id ws_example \
  --project-id proj_example \
  --decision-kind crispr.guide_selection \
  --subject '{"note":"synthetic"}' \
  --proposed-bundle-digest PROPOSED_BUNDLE_DIGEST \
  --policy-digest policy_digest_from_step_2 \
  --backend-fingerprint-digest backend_fingerprint_digest_from_step_2

3) Cache the proposed bundle by digest

The --decision-id flows resolve bundles from:

$HUB_ROOT/bundles/<bundle_digest_hex>/

Copy the proposed bundle into the cache:

export BUNDLE_HEX="${PROPOSED_BUNDLE_DIGEST#sha256:}"
mkdir -p "$HUB_ROOT/bundles/$BUNDLE_HEX"
cp -R out/proposed_bundle/* "$HUB_ROOT/bundles/$BUNDLE_HEX/"

4) Render a Proof pack

helix hub --hub-root "$HUB_ROOT" proof render \
  --decision-id DECISION123 \
  --out out/proof_v0 \
  --zip

Verify the included bundle:

cd out/proof_v0
helix hub verify bundle ./bundle --require-signatures

5) Render a Review pack

helix hub --hub-root "$HUB_ROOT" review render \
  --decision-id DECISION123 \
  --out out/review_v0

Open out/review_v0/index.html and inspect:

  • The approval_surface_digest and the surface JSON artifact it was computed from
  • The verifier status and mapped failure reasons (if any)
  • The copy-pasteable helix hub review approve ... command

6) Approve (emit receipt + updated bundle + update Decision)

helix hub --hub-root "$HUB_ROOT" review approve \
  DECISION123 \
  --bundle "$HUB_ROOT/bundles/$BUNDLE_HEX" \
  --signing-key tests/fixtures/validation_verdict_vectors/publisher.ed25519 \
  --key-id hub-test \
  --approver-subject sub_example_reviewer \
  --approver-email reviewer@example.com \
  --approver-display-name "Example Reviewer" \
  --attestation "Reviewed synthetic decision bundle; approval for demo."

Invariants:

  • The original proposed bundle directory is never modified in place.
  • Approval fails closed if the resulting approved bundle is not verifier-clean with --require-signatures.
  • Running approve twice is idempotent: the second run is a no-op.

7) Render Proof again (now bound to the approved bundle)

helix hub --hub-root "$HUB_ROOT" proof render \
  --decision-id DECISION123 \
  --out out/proof_v0_approved
cd out/proof_v0_approved
helix hub verify bundle ./bundle --require-signatures

8) Export Decisions (procurement report)

Export “approved decisions in a window” as a single deterministic CSV (sorted by approved_at_utc, then decision_id):

helix hub --hub-root "$HUB_ROOT" decision export \
  --format csv \
  --state approved \
  --approved-after 2026-01-01T00:00:00Z \
  --approved-before 2026-04-01T00:00:00Z \
  --out out/decisions_approved_q1.csv

Example CSV (truncated):

# helix.decision.export.v0
decision_id,decision_kind,state,created_at_utc,created_by_subject,...,approved_bundle_digest,policy_digest,backend_fingerprint_digest,approval_surface_digest,approval_receipt_digests,decision_digest
DECISION123,crispr.guide_selection,approved,2026-01-01T00:00:00Z,creator,...,sha256:<bundle>,sha256:<policy>,sha256:<backend>,sha256:<surface>,sha256:<receipt>,sha256:<decision>

Trust anchors:

  • approved_bundle_digest (the exact bundle bytes that were approved)
  • approval_surface_digest + approval_receipt_digests (who approved what surface)
  • decision_digest (stable Decision v1 identity)

If you store proof packs under $HUB_ROOT/proofs/by_bundle/<bundle_digest_hex>/, you can include proof pack resolution in the export:

helix hub --hub-root "$HUB_ROOT" decision export --format csv --state approved --include-proof --out out/decisions_approved_with_proof.csv

JSON export includes an explicit envelope with schema version + rows:

helix hub --hub-root "$HUB_ROOT" decision export --format json --state approved --out out/decisions_approved.json

9) Export a pilot evidence kit (single deliverable folder)

This emits a buyer-ready folder that contains:

  • README.md (verification instructions)
  • decisions.csv + decisions.json
  • proofs/<decision_id>.zip for each approved decision in the window
helix hub --hub-root "$HUB_ROOT" pilot export \
  --workspace ws_example \
  --project proj_example \
  --approved-after 2026-01-01T00:00:00Z \
  --approved-before 2026-04-01T00:00:00Z \
  --out out/pilot_evidence_kit \
  --zip