Skip to main content

heddle_cli_args/cli/cli_args/
commands_redact.rs

1// SPDX-License-Identifier: Apache-2.0
2//! `heddle redact` and `heddle redact purge` — the redaction primitive.
3//!
4//! See `docs/PRINCIPLES.md` and the build brief at
5//! `.agents/redaction-primitive.md` for the design rationale. Briefly:
6//!
7//! - `redact` declares a blob redacted; readers see a stub on
8//!   materialize, but the bytes remain on disk.
9//! - `purge` removes the bytes from local storage. The `Redaction`
10//!   tombstone stays in the DAG forever.
11//!
12//! Both verbs write `OpRecord` entries (`Redact`, `Purge`) so the
13//! oplog audit trail records who did what when.
14
15use clap::{Args, Subcommand};
16
17#[derive(Clone, Debug, Subcommand)]
18pub enum RedactCommands {
19    /// Declare a redaction on a blob in a state. The blob bytes stay
20    /// on disk; reads return the stub. Use `heddle redact purge` afterward
21    /// to physically remove the bytes.
22    Apply(RedactApplyArgs),
23    /// List every active redaction in the repo.
24    List(RedactListArgs),
25    /// Show a single redaction by its content-addressed id.
26    Show(RedactShowArgs),
27    /// Physically remove bytes for an existing redaction.
28    #[command(subcommand)]
29    Purge(PurgeCommands),
30}
31
32#[derive(Clone, Debug, Args)]
33pub struct RedactApplyArgs {
34    /// State that surfaces the file. Accepts short or full state IDs,
35    /// marker names, `HEAD`, `@`, or `HEAD~N`.
36    pub state: String,
37    /// Path within the state's tree.
38    #[arg(long)]
39    pub path: String,
40    /// Operator-supplied reason. Lands in the materialized stub so
41    /// reviewers know why content disappeared.
42    #[arg(long)]
43    pub reason: String,
44    /// Walk every reachable state and redact every occurrence of the
45    /// same blob hash. Default: just the named state.
46    #[arg(long)]
47    pub all_states: bool,
48    /// Path to a private key (PEM) used to sign the redaction. The
49    /// signature binds operator → declaration; auditors can verify
50    /// who hid what when with `heddle redact show`.
51    #[arg(long, value_name = "PATH")]
52    pub sign_with: Option<std::path::PathBuf>,
53    /// Override the signing algorithm. Defaults to autodetect from the
54    /// key file's PEM header. Accepts `ed25519`, `p256`.
55    #[arg(long, value_name = "ALGO", requires = "sign_with")]
56    pub sign_algo: Option<String>,
57}
58
59#[derive(Clone, Debug, Args)]
60pub struct RedactListArgs {}
61
62#[derive(Clone, Debug, Args)]
63pub struct RedactShowArgs {
64    /// Redaction id (full or short prefix).
65    pub redaction_id: String,
66}
67
68#[derive(Clone, Debug, Subcommand)]
69pub enum PurgeCommands {
70    /// Physically remove the blob bytes referenced by an existing
71    /// redaction. Refuses if no redaction declared the blob first.
72    ///
73    Apply(PurgeApplyArgs),
74    /// List every `Purge` oplog entry — who removed bytes, when, and
75    /// which redaction the purge acted on.
76    List(PurgeListArgs),
77}
78
79#[derive(Clone, Debug, Args)]
80pub struct PurgeApplyArgs {
81    /// State whose redaction we're purging the blob of.
82    pub state: String,
83    /// Path within the state's tree.
84    #[arg(long)]
85    pub path: String,
86    /// Required acknowledgement. Purge is irreversible — without
87    /// `--force` the command refuses, listing what would be removed.
88    #[arg(long)]
89    pub force: bool,
90}
91
92#[derive(Clone, Debug, Args)]
93pub struct PurgeListArgs {}