INTERFACE=provenance-cli:rust/v1
FRONTEND=Rust
BACKEND=existing Python reference modules
MCP_REQUIRED=NO
NETWORK_REQUIRED=NO
RUST_CRATE_DEPENDENCIES=NONE
Phase 8 adds a terminal-native human/operator surface without changing the evidence contract.
The Rust binary is intentionally small. It performs command discovery, argv handling, project-root discovery, exit-code propagation, and the interactive slash-command palette.
Evidence operations remain in the existing reference modules:
provenance_core
provenance_store
provenance_custody
provenance_verify
The CLI does not implement a second verifier.
From the repository root:
cargo build --manifest-path provenance-cli/Cargo.toml --lockedThe binary is:
provenance-cli/target/debug/provenance
The initial implementation is checkout-native. It locates the repository automatically when run from the checkout/build tree. Set PROVENANCE_ROOT when invoking the binary from elsewhere.
PROVENANCE_ROOT selects where the implementation is loaded from; it does not change the caller's working directory. Relative --store, --custody, --file, and --destination paths are resolved relative to the directory from which the operator invoked provenance.
PROVENANCE_PYTHON may select the Python executable. The default is python3.
The initial surface is:
provenance record
provenance inspect
provenance verify
provenance finalize
provenance export
provenance package
provenance tui
All evidence commands take explicit local roots:
--store /path/to/store
--custody /path/to/custody
No daemon, MCP transport, HTTP server, cloud account, or provider login is required.
Example:
provenance record \
--store ./evidence \
--custody ./custody \
--file ./source.bin \
--actor operator:alice \
--operation file.captureOperator-supplied content and meaning is recorded as DECLARED evidence.
The CLI separately emits a unique retained invocation receipt as OBSERVED evidence with actor provenance-cli:rust/v1.
This preserves the distinction:
operator declaration
→ DECLARED
CLI receipt of invocation
→ OBSERVED
Identical declarations may deduplicate by content identity while separate CLI invocations remain separate recorded occurrences.
The --digest-only option retains the content identity and artifact metadata without retaining the source bytes.
Authentication is not implemented in Phase 8. Later provider-auth work must keep credentials outside ordinary evidence payloads.
Phase 8 does not create a separate CLI pending-evidence universe.
For compatibility with the merged Phase 7 implementation, CLI and MCP deliberately share the same hardened operational lock and working-state journal:
.provenance-mcp-working.lock
.provenance-mcp-working.json
provenance.mcp-working-state.v1
The names are historical. This state is operational metadata, not an MCP evidence format and not part of finalized evidence identity.
This sharing means:
MCP acknowledges A
CLI acknowledges B
↓
one serialized durable working set
↓
either interface may finalize A ∪ B
The CLI revalidates journal artifact membership, pending verification subjects, HEAD lineage, and retained object state through existing store contracts before proceeding.
provenance finalize \
--store ./evidence \
--custody ./custody \
--scope closed
provenance verify \
--store ./evidence \
--custody ./custodyFinalization delegates to LocalEvidenceStore.finalize().
Verification delegates to LocalEvidenceStore.verify_current(), LocalCustodyLedger.verify(), and provenance_verify.
The Rust surface does not recompute or reinterpret evidence itself.
Without an identity:
provenance inspect --store ./evidence --custody ./custodyreports current manifest identity, working artifact/event counts, pending counts, and the current manifest when present.
With an identity:
provenance inspect \
--store ./evidence \
--custody ./custody \
--identity sha256:<digest>resolves the identity as a known artifact, event, manifest, or custody record.
provenance export \
--store ./evidence \
--custody ./custody \
--destination ./exportedPhase 8 export is the same narrow snapshot-copy concept used by the MCP interface:
current verified snapshot
→ descriptor-bound copy
→ independent verify_bundle(copy)
→ EXPORTED custody
It does not claim completion of the later Phase 11 portable forensic-package contract.
Start:
provenance tui --store ./evidence --custody ./custodyTyping a single slash opens the palette:
/record
/inspect
/verify
/finalize
/export
Typing a prefix such as /ver filters the palette.
Exact commands execute keyboard-first:
/verify
/inspect
/finalize --scope closed
/record --file evidence.bin --actor operator:alice --operation file.capture
/export --destination ./exported
/quit exits.
The TUI preserves a machine-detectable failure result across the session. If any executed slash command returns a non-zero backend status, the TUI remembers the first failure status and returns it when the session exits or stdin closes. A later successful command does not erase that failure status.
This first terminal UI is intentionally line-mode rather than a full-screen terminal framework. It establishes the interaction contract without introducing curses, a rendering framework, or external Rust crates.
Phase 8 CI builds the real Rust binary and executes:
record
↓
inspect working state
↓
finalize
↓
verify
↓
export
↓
independent verify_bundle(export)
A second integration test launches two independent Rust CLI processes concurrently against the same empty roots and requires both acknowledged records to appear in the same finalized verified bundle.
The palette is also driven through stdin to prove slash-command discovery works without a graphical UI.
The CLI workflow is triggered by changes to the Rust surface, the Python CLI backend, and its transitive PROVENANCE contracts: core, store, custody, verifier, and MCP interoperability. This prevents a lower-layer change from bypassing terminal lifecycle coverage merely because no CLI-owned file changed.
The integration suite also executes the built binary from outside the repository with PROVENANCE_ROOT pointing back to the checkout. That regression requires relative source, store, custody, and export paths to remain anchored to the caller's working directory.
RUST HANDLES THE TERMINAL.
EXISTING MODULES HANDLE EVIDENCE.
THE VERIFIER REMAINS INDEPENDENT.
MCP IS OPTIONAL.
NETWORK IS OPTIONAL.
The Phase 8 export command remains a verified copy of the current immutable Phase 2 snapshot.
Phase 11 adds a distinct command:
provenance package \
--store /path/to/store \
--custody /path/to/custody \
--destination /path/to/forensic-packageThis creates and independently verifies a provenance.forensic-package.v1 directory containing the evidence snapshot, stable custody snapshot, schema/version metadata, verification metadata, and recomputed declared gaps.
After successful publication, the live custody ledger receives an EXPORTED record for the evidence manifest whose related_identity is the package identity. The already-finalized package is not rewritten to include that later export record.
See PACKAGE.md.
Detached trust operations act on finalized Phase 11 packages and do not require --store / --custody.
provenance sign-package
provenance anchor-payload
provenance anchor-git
provenance verify-assurance
These commands are standalone backend commands rather than TUI palette actions because they operate on detached packages/records rather than the active mutable store session.
Sign:
provenance sign-package \
--package /path/to/package \
--key /path/to/ed25519-key \
--output ./package.signature.jsonCreate bytes to commit as a Git anchor:
provenance anchor-payload \
--package /path/to/package \
--output /path/to/git-repo/package.provenanceAfter committing that exact file, create the detached anchor record:
provenance anchor-git \
--package /path/to/package \
--git-repo /path/to/git-repo \
--commit HEAD \
--path package.provenance \
--output ./package.git-anchor.jsonVerify dimensions independently:
provenance verify-assurance \
--package /path/to/package \
--signature ./package.signature.json \
--anchor ./package.git-anchor.json \
--git-repo /path/to/git-repoSee TRUST.md for the exact proof boundary.
Create a redacted derivative disclosure from a retained artifact in a finalized Phase 11 package:
provenance redact-disclosure \
--package /path/to/source-package \
--source sha256:<source-digest> \
--range 17:29 \
--output /path/to/disclosureMultiple --range START:END arguments are accepted. The default replacement byte is decimal 42 (*); use --mask-byte for another byte value.
Verify disclosure structure/lineage without source content:
provenance verify-disclosure \
--disclosure /path/to/disclosureRecompute the transform against the original package:
provenance verify-disclosure \
--disclosure /path/to/disclosure \
--source-package /path/to/source-packageThese are standalone package/privacy commands, not TUI store-session commands.
See PRIVACY.md.
Create a signed offline handoff:
provenance transfer-create \
--package /path/to/source-package \
--source-system org-a/system-1 \
--destination-system org-b/system-9 \
--sender-key /path/to/sender-key \
--output /path/to/transferAccept it into independently operated receiver storage:
provenance transfer-receive \
--transfer /path/to/transfer \
--package-destination /receiver/package \
--receipt /receiver/receipt \
--custody /receiver/custody \
--receiver-system org-b/system-9 \
--receiver-key /path/to/receiver-key \
--expected-sender-fingerprint 'SHA256:<trusted-sender-fingerprint>'Verify sender handoff:
provenance verify-transfer --transfer /path/to/transferVerify the receiver acknowledgement and optional end-to-end bindings:
provenance verify-receipt \
--receipt /receiver/receipt \
--transfer /path/to/transfer \
--package /receiver/packageThese are standalone finalized-package operations and are not TUI working-store commands.
See TRANSFER.md.