Skip to content

CLI reference

Generated from the command definitions. Every command takes --root PATH (default: the git top-level of the working directory).

activities

GDPR processing activities: purpose, legal basis, and what they touch.

activities add

Add touchpoints (unit:id) to an existing activity.

Option Type Meaning
SLUG argument
REFS argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

activities create

Create compliance/activities/<slug>.yaml; unknown fields become !todo.

Option Type Meaning
SLUG argument
--name text
--purpose text
--legal-basis consent | contract | legal_obligation | vital_interests | public_task | legitimate_interests | no_pii
--touchpoint text unit:id, repeatable. default Sentinel.UNSET
--subject text Data subject, repeatable. default Sentinel.UNSET
--recipient text Party id, repeatable. default Sentinel.UNSET
--retention text
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

activities explain

Show an activity's manifest, its touchpoint graph and the derivation.

Option Type Meaning
SLUG argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

activities list

List the activities with their derived data, categories and DPIA verdict.

Option Type Meaning
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

challenge

Re-open the reviews a change undermines (the challenger agent alone).

The agent reads git diff BASE..HEAD, asks what reviewers asserted about the changed files, and puts the doubtful items back to pending with grounds. It never reclassifies. Exit 1 when it challenged something, 0 otherwise.

Option Type Meaning
--merge-into text Base ref: the challenger reads BASE..HEAD. default Sentinel.UNSET
--commit flag Commit the challenges it records.
--model text provider/model. default openrouter/openrouter/auto
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.
--python text Interpreter to use for introspection.

check

The compliance to-do list: what has to happen next, grouped by kind.

Errors (fix the files) exit 3. Missing (established non-compliance, never ignorable), Todo (questions for a human; --allow-todo waves them) and Review (run the agents) exit 1. 4 is a crash of model-wtf itself.

Option Type Meaning
--strict flag Treat images without a compliance block as errors instead of warnings.
--format text | json | github Output style: human-readable, JSON, or GitHub Actions annotations. default text
--allow-todo flag Open !todo questions are listed but do not fail the check.
--todo flag Print only the open questions, one per line, as a questionnaire.
--verbose, -v flag Also print the Info section.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.
--python text Interpreter to use for introspection.

data

Inventory and classify the application's data.

data auto-review

Have an OpenCode agent review every pending data item.

Runs OpenCode in an isolated configuration (throwaway HOME, generated config, read-only tools, our MCP server as the only write path) on OpenRouter, in rounds, until nothing is pending. Exit 0 when complete, 1 when items remain, 4 when OpenCode or OPENROUTER_API_KEY is missing.

Option Type Meaning
--unit text Restrict to one unit.
--base text Git ref: also re-check items whose model changed.
--max-rounds integer default 20
--batch integer Models per round. default 8
--model text provider/model. default openrouter/openrouter/auto
--python text Interpreter to use for introspection.
--max-tokens integer Stop starting new rounds once this many tokens were used.
--workers integer range Parallel OpenCode sessions per round, each reviewing --batch items. default 16
--dry-run flag Print the generated OpenCode config and stop.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data contents

Declare what a JSON-like column holds, one ENTRY per kind of information.

ITEM_ID is <unit>:<app.Model.field> of a JSONField/ArrayField/HStoreField. Each ENTRY is name=pii,sensitivity,category (name=yes,personal,contact); the names are identifiers, not JSON paths. --unknown none with no entry declares an empty, harmless blob.

Option Type Meaning
ITEM_ID argument
ENTRIES argument
--unknown none | possible | likely Is the list exhaustive? none = every write site was read. default possible
--reason text Where the writes are (else !todo).
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data list

List every data item of every unit with its classification.

Option Type Meaning
--unit text Restrict to one unit.
--pending flag Only items still to review.
--assumed flag Only library defaults resting on an assumption (implies --pending).
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data override

Create <unit>/compliance/data/<id>.yaml overriding a classification.

ITEM_ID is <unit>:<app.Model.field> (the unit prefix may be omitted when the repo has one unit). Existing files are never rewritten.

Option Type Meaning
ITEM_ID argument
--pii, --no-pii flag Personal data or not.
--sensitivity text Sensitivity level id.
--category text Category id.
--store text Slug of the store holding the value.
--reason text Why the rule was wrong (else !todo).
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data reviewed

Mark data items as reviewed by a human (writes data.lock.yaml).

ITEM_IDS are <unit>:<app.Model.field> (unit prefix optional with one unit). The current classification is what is being confirmed.

Option Type Meaning
ITEM_IDS argument
--note text One line on what was checked. default `
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data rules

Show the built-in data rules in evaluation order.

Option Type Meaning
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

data why

Who needs a data item: the touchpoints handling it, the activities holding it.

PATTERNS are unit:id ids, globs allowed (api:people.Person.*).

Option Type Meaning
PATTERNS argument
--model text unit:app.Model — every field.
--manifests flag Print the activity files in full.
--verbose, -v flag List every touchpoint with its location.
--format text | json default text
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

flows

Where the data goes: every flow, its kind, status and payload.

flows list

The flows, one per line; filters narrow by touchpoint, kind or status.

Option Type Meaning
--unit text Restrict to one unit.
--element text Only the flows of this touchpoint.
--kind request | store | transfer | call | defer
--status declared | derived | undeclared
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

flows show

One flow: ends, kind, status, items, and the threat cells on it.

FLOW_ID is source->sink as flows list prints it, or a touchpoint id to show all of its flows.

Option Type Meaning
FLOW_ID argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

ghate

The pull-request gate: fail only on findings the change introduces.

Runs compliance check on the base (in a temporary worktree) and on the head, compares by finding identity. With an API key, the challenger agent first reads the diff and re-opens the reviews it undermines, which then count as introduced. Exit 0 when nothing is introduced (pre-existing findings are listed, not failed), 1 when something is, 3 on declaration errors in the head, 4 on a tool error.

Option Type Meaning
--merge-into text Base ref the change will be merged into (default: the pull request base under GitHub Actions).
--head text Ref to gate instead of the working tree.
--format auto | text | json | github auto: github under GitHub Actions, text otherwise. default auto
--fail-on-existing flag Also fail on findings that were already there (clean repositories).
--strict flag Treat images without a compliance block as errors instead of warnings.
--challenge, --no-challenge flag Run the challenger agent on the diff before comparing (default: when OPENROUTER_API_KEY is set).
--commit-challenges flag Commit what the challenger re-opened (CI: the developer gets the fallout).
--model text Challenger model. default openrouter/openrouter/auto
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.
--python text Interpreter to use for introspection.

init

Scaffold compliance/ (app manifest, parties) and wire the units.

Missing values are prompted for on a terminal; the processor defaults to default_processor from ~/.config/model-wtf/config.yml. Never overwrites anything: re-run to add what is missing.

Option Type Meaning
--name text Product name (app.yaml#name). default Sentinel.UNSET
--controller-name text Legal name of the controller (the client). default Sentinel.UNSET
--controller-country text Controller country, ISO 3166-1 alpha-2. default Sentinel.UNSET
--processor-name text Legal name of the processor (the agency). default Sentinel.UNSET
--processor-country text Processor country, ISO 3166-1 alpha-2. default Sentinel.UNSET
--no-processor flag The controller operates the product itself; declare no processor.
--no-workflow flag Do not write .github/workflows/compliance.yml (the PR gate).
--codeowners, --no-codeowners flag Write the managed CODEOWNERS block (default: when origin is on GitHub; --codeowners makes it an error when no owner can be resolved).
--owner-dpo text GitHub team reviewing the register.
--owner-ciso text GitHub team reviewing the security posture.
--custom-sensitivity flag Copy the built-in sensitivity scale to compliance/sensitivity/ for editing.
--custom-categories flag Copy the built-in categories to compliance/categories/ for editing.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

stores

Where the data lives: databases, caches, buckets, queues.

stores explain

Show where a store comes from and which data items reference it.

STORE_ID is <unit>:<slug> (the unit prefix may be omitted when the repo has one unit).

Option Type Meaning
STORE_ID argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

stores list

List the stores of every unit with how many data items each holds.

Option Type Meaning
--unit text Restrict to one unit.
--all flag Include ignored stores.
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

threats

The threat matrix: every touchpoint, store and flow against pytm's catalogue.

threats auto-review

Have agents stamp the open threat cells.

Each reviewer reads the code and calls threat_stamp per open SID: mitigated (with file:line), n/a, accepted, or a missing finding. Same sandbox and exit codes as the other auto-reviews.

Option Type Meaning
--unit text Restrict to one unit.
--by topic | touchpoint One reviewer per security topic across touchpoints, or one per touchpoint across its open threats. default topic
--topic-batch integer Touchpoints per topic reviewer session (--by topic). default 12
--elements text Comma-separated element ids to restrict the review to (an eval subset).
--max-rounds integer default 10
--batch integer Items per worker per round. default 8
--model text provider/model. default openrouter/openrouter/auto
--max-tokens integer Stop starting new rounds once this many tokens were used.
--workers integer range Parallel OpenCode sessions per round. default 16
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

threats findings

Every !missing threat stamp, most severe first.

Severity is impact (effect x degree x sensitivity) x likelihood (the most feared actor who can reach the touchpoint); see the README. Findings stamped before weighing existed show as unweighed.

Option Type Meaning
--unit text Restrict to one unit.
--min-severity critical | high | medium | low | info Hide findings below this bucket. default info
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

threats matrix

Counts per element kind, per threat and per topic; --open lists the cells.

A cell is never (impossible in the stack), dismissed (a simple rule closed it for that element) or open (an agent has to look).

Option Type Meaning
--unit text Restrict to one unit.
--open flag List the open cells.
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

threats stamp

Stamp one open threat cell on a touchpoint, store, party or flow.

Writes the threats: block of the element's YAML (a flow's on its source touchpoint, keyed SID@sink). Pinned to the element's fingerprint: when the code moves, the stamp goes stale and the cell reopens.

Option Type Meaning
ELEMENT_ID argument
SID argument
--status mitigated | accepted | n/a Close the cell: the code mitigates it, the risk is accepted, or it does not apply here.
--note text Where / why (file:line for mitigated).
--missing text Record a finding instead: what is exploitable and where.
--effect disclosure | tampering | destruction | denial | escalation | repudiation Narrow the finding's effect (default: from the threat and the ops).
--degree existence | attribute | record | bulk Narrow how much data is reached (default: inferred, record or bulk).
--actor anonymous | subject | staff | system Narrow who can exploit it (default: whoever the scope lets in).
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

threats why

Every threat for one element (a touchpoint id, unit:store, party:x, or a flow a->b) with in/out and the rule that decided it. A finding id (F-0042) shows that one finding in full.

Option Type Meaning
ELEMENT_ID argument
SIDS argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

touchpoints

Entry points through which data flows: routes, tasks, admin screens.

touchpoints auto-review

Have an OpenCode agent declare what each touchpoint handles, then group.

Pass 1 reviews pending touchpoints one at a time (reading the view or task code, referencing inventory items, adding transient manual items when the code handles personal data that is never persisted). Pass 2, once nothing is pending, groups every PII-touching touchpoint into processing activities following the front -> api -> task edges; fields the agent cannot know stay !todo. Same sandbox and exit codes as data auto-review.

Option Type Meaning
--unit text Restrict to one unit.
--max-rounds integer default 20
--batch integer Touchpoints per round. default 8
--model text provider/model. default openrouter/openrouter/auto
--max-tokens integer Stop starting new rounds once this many tokens were used.
--group, --no-group flag Group PII-touching touchpoints into activities once nothing is pending.
--group-only flag Skip the per-touchpoint pass; only run the grouping session.
--workers integer range Parallel OpenCode sessions per round, each reviewing --batch touchpoints. default 16
--stale flag Also re-review manifests written with write / exporting.
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

touchpoints list

List every touchpoint with what it handles and which activity holds it.

Option Type Meaning
--unit text Restrict to one unit.
--pending flag Only touchpoints without a manifest.
--all flag Include ignored ones.
--format table | json default table
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

touchpoints set-data

Declare the data items a touchpoint handles (writes its manifest).

REFS are <unit>:<app.Model.field> data ids (@json/@files rows allowed; a ref without unit means the touchpoint's unit). ref=<ops> states what the code does to the item, as in a manifest: ref=create, ref=create,read, ref='{erase: {by: subject}}'; a bare ref is a read. No REF at all declares an empty list: "touches no inventory item, checked".

Option Type Meaning
TOUCHPOINT_ID argument
REFS argument
--add flag Append to the current list.
--remove flag Remove from the list.
--ignore flag Mark the touchpoint as carrying nothing.
--transfer, --export text party=ref,ref[;purpose] — data sent to another organisation; repeatable. default Sentinel.UNSET
--note text One line on what was looked at.
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.

touchpoints show

Everything known about one touchpoint: facts, schemas, manifest, activities.

TOUCHPOINT_ID is <unit>:<id>.

Option Type Meaning
TOUCHPOINT_ID argument
--python text Interpreter to use for introspection.
--root directory Repository root. Defaults to the top-level --root, else the enclosing Git checkout, else the cwd.