crates/veilvoice-cli/src/main.rs
veilvoice-cli · 3461 lines · read the source here · or on GitHub
veilvoice, the command-line interface.
Everything VeilVoice does, available without a desktop: it runs over SSH, in a container, and on machines that have no GUI toolkit at all. The same engine backs both this and the graphical app.
What is here
Twenty subcommands, and they divide into five groups:
- Audio --
anonymisea file,livescramble a microphone, listdevices,conversationfor a recording with several people in it. - Privacy of the files themselves --
cleanmetadata,encrypt,decrypt,keygen,shred. - Watching the machine --
watchthe microphone and camera,guardVeilVoice's own files against tampering,sentryfor canaries and how fast a folder is changing,capturefor which screen recorders are running. - The app lock --
lock set|status|change|remove, andpolicyfor settings somebody has fixed so the interface cannot turn them off. - Getting it onto the machine --
install,uninstall,companions, andguito open the desktop application.
That last group is a front end over veilvoice_setup, which the desktop application's setup tab also calls. The careful part -- editing PATH -- has one implementation and one set of tests, rather than one per front end.
Two behaviours that surprise people, on purpose
anonymise writes <out>.veil, not a bare WAV. Recordings are encrypted at rest by default. --encrypt=false opts out and requires --yes, because an unsealed recording is the thing somebody later wishes they had not produced. The wiki explains where the WAV went.
The front-ends refuse rather than downgrade. Asked to encrypt with nothing to encrypt with, this exits with an error instead of writing plain audio and mentioning it. Quiet degradation to a weaker posture is the defect class this project has found in itself most often.
Passphrase prompts cannot be piped
rpassword needs a real console; piping a passphrase in blocks on CONIN$ rather than reading it. That is a property of terminal input, not a bug here, and it means anything that prompts cannot be smoke-tested from a non-interactive shell. The layer beneath each prompt is therefore tested instead -- see crate::atrest and crate::lock, where the logic lives precisely so it can be reached without a terminal.
A clap ordering rule worth knowing
An argument declared beside #[command(subcommand)] must precede the subcommand on the command line unless it is marked global = true. So veilvoice lock --path X status parses and veilvoice lock status --path X does not, except that --path is now global specifically so both do.
In plain words
This is VeilVoice without a window.
Everything the program does, typed instead of clicked: disguise a recording, scramble a microphone while you talk, seal a file, strip a photograph's hidden labels, handle a recording with several people in it.
It is the same code underneath, so it works the same way -- over a remote connection, on a machine with no desktop, or from a script that runs it a thousand times.
WHAT THIS FILE CONTAINS
3461 lines defining 29 functions (0 public), 13 types and 0 constants. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
struct Cliline 118enum Commandline 124enum FixCommandline 731 · The corrections veilvoice conversation fix can make.enum ConversationCommandline 815enum AppctlCommandline 973 · What veilvoice capture can do.enum InputCommandline 1000enum CaptureCommandline 1013enum MandateCommandline 1053 · What veilvoice mandate can do.enum PolicyCommandline 1089 · What veilvoice policy can do.enum SentryCommandline 1142 · What veilvoice sentry can do.enum CleanPolicyline 1203struct Tuningline 2196 · The engine settings a user can reach from the command line.struct AtRestline 2273 · What to do with the result once it exists.
WHAT CALLS WHAT
The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one. 22 of 28 functions are drawn; the diagram is bounded at 22 so it stays readable.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_flavour_for["flavour_for<br/>line 1225"]
n_explain_verification["explain_verification<br/>line 1245"]
n_main["main<br/>line 1323"]
n_run["run<br/>line 1365"]
n_run_ffmpeg["run_ffmpeg<br/>line 1933"]
n_list_volumes["list_volumes<br/>line 2008"]
n_list_companions["list_companions<br/>line 2056"]
n_offer_line["offer_line<br/>line 2089"]
n_install_companion["install_companion<br/>line 2113"]
n_reseed_range_from["reseed_range_from<br/>line 2215"]
n_config["config<br/>line 2235"]
n_describe_reseed_range["describe_reseed_range<br/>line 2254"]
n_describe_reseed["describe_reseed<br/>line 2264"]
n_anonymise["anonymise<br/>line 2283"]
n_live["live<br/>line 2426"]
n_list_devices["list_devices<br/>line 2658"]
n_read_named["read_named<br/>line 2709"]
n_video_plan["video_plan<br/>line 2724"]
n_write_named["write_named<br/>line 2741"]
n_clean["clean<br/>line 2746"]
n_encrypt["encrypt<br/>line 2764"]
n_decrypt["decrypt<br/>line 2795"]
n_anonymise --> n_config
n_anonymise --> n_describe_reseed_range
n_clean --> n_read_named
n_decrypt --> n_read_named
n_describe_reseed_range --> n_describe_reseed
n_encrypt --> n_read_named
n_encrypt --> n_write_named
n_install_companion --> n_offer_line
n_list_companions --> n_offer_line
n_live --> n_config
n_live --> n_describe_reseed_range
n_main --> n_run
n_run --> n_anonymise
n_run --> n_clean
n_run --> n_config
n_run --> n_decrypt
n_run --> n_encrypt
n_run --> n_explain_verification
n_run --> n_flavour_for
n_run --> n_install_companion
n_run --> n_list_companions
n_run --> n_list_devices
n_run --> n_list_volumes
n_run --> n_live
n_run --> n_reseed_range_from
n_run --> n_run_ffmpeg
n_run --> n_video_plan
click n_flavour_for href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1225" "open the source"
click n_explain_verification href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1245" "open the source"
click n_main href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1323" "open the source"
click n_run href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1365" "open the source"
click n_run_ffmpeg href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L1933" "open the source"
click n_list_volumes href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2008" "open the source"
click n_list_companions href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2056" "open the source"
click n_offer_line href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2089" "open the source"
click n_install_companion href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2113" "open the source"
click n_reseed_range_from href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2215" "open the source"
click n_config href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2235" "open the source"
click n_describe_reseed_range href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2254" "open the source"
click n_describe_reseed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2264" "open the source"
click n_anonymise href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2283" "open the source"
click n_live href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2426" "open the source"
click n_list_devices href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2658" "open the source"
click n_read_named href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2709" "open the source"
click n_video_plan href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2724" "open the source"
click n_write_named href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2741" "open the source"
click n_clean href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2746" "open the source"
click n_encrypt href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2764" "open the source"
click n_decrypt href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-cli/src/main.rs#L2795" "open the source"
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_flavour_for,n_explain_verification,n_main,n_run,n_run_ffmpeg,n_list_volumes,n_list_companions,n_offer_line,n_install_companion,n_reseed_range_from,n_config,n_describe_reseed_range,n_describe_reseed,n_anonymise,n_live,n_list_devices,n_read_named,n_video_plan,n_write_named,n_clean,n_encrypt,n_decrypt helper
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
ITEMS
| Item | Line | Documentation |
|---|---|---|
Cli struct | 118 | |
Command enum | 124 | |
conversation::Fix::from fn | 712 | |
FixCommand enum | 731 | The corrections veilvoice conversation fix can make. |
ConversationCommand enum | 815 | |
AppctlCommand enum | 973 | What veilvoice capture can do. |
InputCommand enum | 1000 | |
CaptureCommand enum | 1013 | |
MandateCommand enum | 1053 | What veilvoice mandate can do. |
PolicyCommand enum | 1089 | What veilvoice policy can do. |
SentryCommand enum | 1142 | What veilvoice sentry can do. |
CleanPolicy enum | 1203 | |
Policy::from fn | 1211 | |
flavour_for fn | 1225 | The verification script's spelling for a system, in one place. |
explain_verification fn | 1245 | What checking a release actually involves, and who does which part. |
main fn | 1323 | Parse the command line and turn a failure into an exit code and a message. |
run fn | 1365 | Carry out one subcommand. |
run_ffmpeg fn | 1933 | Roadmap items 87 and 88. |
list_volumes fn | 2008 | Report the encrypted volumes this machine is offering. |
list_companions fn | 2056 | Report every companion that means anything on this platform. |
offer_line fn | 2089 | One line describing what VeilVoice can do about a missing companion. |
install_companion fn | 2113 | Act on one named companion. |
Tuning struct | 2196 | The engine settings a user can reach from the command line. |
reseed_range_from fn | 2215 | Turn --reseed-range into a range, or into the reason it was not one. |
config fn | 2235 | The de-identification settings a Tuning describes, with every figure clamped. |
describe_reseed_range fn | 2254 | How a randomised roll range reads in the output. |
describe_reseed fn | 2264 | How the seed-rolling setting reads in the output. |
AtRest struct | 2273 | What to do with the result once it exists. |
anonymise fn | 2283 | veilvoice anonymise: veil a recording and write it somewhere else. |
live fn | 2426 | veilvoice live: veil the microphone as it is heard, with an optional preview. |
list_devices fn | 2658 | veilvoice devices: every input and output this machine reports. |
read_named pub(crate) fn | 2709 | Read a file, naming it if that fails. |
video_plan pub(crate) fn | 2724 | Read a --size and an --fps into a render plan, saying what was decided. |
write_named pub(crate) fn | 2741 | Write a file, naming it if that fails. |
clean fn | 2746 | veilvoice clean: strip the metadata a file carries, in place. |
encrypt fn | 2764 | veilvoice encrypt: seal a file, to a passphrase or to a public key. |
decrypt fn | 2795 | veilvoice decrypt: open a sealed file, given the passphrase or the secret key. |
load_secret_key fn | 2827 | Load a private key file, which is itself a password-locked container. |
keygen fn | 2837 | veilvoice keygen: write a new key pair, refusing to overwrite either file. |
watch fn | 2913 | Report, and keep reporting, what is using the microphone and camera. |
shred fn | 3003 | Destroy a file's contents, then delete it. |
info fn | 3072 | veilvoice info: the versions, and what this build was compiled to do. |