# Orca CLI Reference

This document is the complete reference for the `orca` command-line
interface. Every command, subcommand, and flag is documented here.

> **Canonical path (v0.9+)**: The v0.9 re-architecture introduced the
> SSH-push deployment model, markdown jobspec, multi-namespace layout,
> and CLI-side scheduler. Commands marked **deprecated** below are from
> the v0.8 daemon/mTLS model. The v0.12 milestone closed the dual-write
> window (REQ-138) — the legacy CA/mTLS/daemon paths are deleted. The
> v0.13 milestone (in progress) wires the scheduler into `orca job run`
> and delivers production hardening round 2.

## Global flags

These flags are available on every `orca` command.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--json` | bool | `false` | Output in JSON format (machine-readable) |
| `--system` | bool | `false` | Use system-level namespace root (`/root/.orca`) instead of user-level (`~/.orca`). Errors if `ORCA_HOME` is already set to a conflicting value. |
| `--config` | string | `""` | Path to config file (overrides `~/.orca/config.md`). Supports `.md` (canonical) and `.hcl` (legacy) formats. |
| `--no-deprecation-warnings` | bool | `false` | Suppress deprecation warnings. Use during `orca upgrade` migrations. |

### Output modes

- **Text** (default): human-readable tables and messages.
- **JSON** (`--json`): structured JSON output for machine consumption
  and AI agents.
- **Watch** (`--watch` on list commands): table refresh (text default)
  or NDJSON streaming (`--json`), one line per event until Ctrl-C.

### Environment variables

| Variable | Description |
|----------|-------------|
| `ORCA_HOME` | Namespace root directory (default `~/.orca`). Overrides all on-disk paths. |
| `ORCA_DB` | Fine-grained database path override. |
| `ORCA_LISTEN_ADDR` | Daemon listen address (deprecated). |
| `ORCA_CA_PATH` | CA certificate path override. |
| `ORCA_SERVER_CERT_PATH` | Server certificate path override. |
| `ORCA_SERVER_KEY_PATH` | Server key path override. |
| `ORCA_NODE_CPU` | Node CPU capacity override (millicores). |
| `ORCA_NODE_MEMORY_MB` | Node memory capacity override (MiB). |

### Exit codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Error (printed to stderr) |

---

## `orca init`

Initialize local orca state with full bootstrap.

```
orca init
```

Performs a 6-step idempotent bootstrap:

1. Create the namespace directory (honors `$ORCA_HOME`; defaults to `~/.orca`)
2. Open and migrate the SQLite database (migrations 0001–0006)
3. Bootstrap the internal CA (`ca.crt` + `ca.key`) if not already present
4. Generate the server cert (`server.crt` + `server.key`) if not already present
5. Auto-detect the local OS via `/etc/os-release`
6. Register a localhost node (kind=localhost, os=\<detected\>)

Re-running `orca init` is safe — it refreshes `last_seen` and `os` on
the localhost node without regenerating certs or changing the node ID.

**Flags**: none.

**Example**:
```bash
orca init
orca --system init    # system-level bootstrap at /root/.orca
```

---

## `orca version`

Print the orca version, git commit, and build time.

```
orca version
```

**Flags**: none (global flags only).

---

## `orca status` *(deprecated)*

Show orca daemon status.

```
orca status
```

> **Deprecated (v0.13)**: This command is a v0.1 stub that reports a
> hardcoded "daemon stopped" status. The daemon model was replaced by
> SSH-push in v0.9 (R-001) and the dual-write window closed in v0.12
> (REQ-138). Use `orca node list` for node registry/state and
> `orca metrics /healthz` for health probes. This command will be
> removed in a future release.

---

## `orca node`

Manage orca nodes — join, leave, list, drain, key-reset, and capacity.

### `orca node join`

Join a node to the orca registry.

```
orca node join [flags]
```

Node types (via `--type`):
- `localhost` (default): register a local or Linux node
- `proxmox`: SSH-bootstrap a remote Proxmox VE 8/9 host (deploys orca
  pubkey, creates orca user + PVE role + sudoers allowlist; requires
  `--host` + `--ssh-key`; R-021: no passwords)

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--name` | string | `""` | Node name (required for `--type localhost`) |
| `--addr` | string | `"localhost:8443"` | Node address |
| `--ca-fingerprint` | string | `""` | Pin CA cert SHA-256 (fails if on-disk CA doesn't match) |
| `--type` | string | `"localhost"` | Node type: `localhost` or `proxmox` |
| `--host` | string | `""` | Proxmox host address (IP/hostname; required for `--type proxmox`) |
| `--ssh-user` | string | `"root"` | SSH username for proxmox bootstrap |
| `--ssh-key` | string | `""` | SSH private key path for proxmox bootstrap (R-021: no passwords; default: orca key) |
| `--ssh-port` | int | `22` | SSH port for proxmox bootstrap |
| `--proxmox-user` | string | `"orca"` | Linux system user to create on the proxmox host |
| `--proxmox-role` | string | `"OrcaOperator"` | PVE custom role to create |
| `--host-key-fingerprint` | string | `""` | SSH host key `SHA256:base64` fingerprint (pre-pin; supersedes TOFU for `--type proxmox`) |

**Examples**:
```bash
# Localhost
orca node join --name my-node

# Proxmox (v0.9 canonical SSH-push path)
orca node join --type proxmox --host 192.168.1.100 --ssh-user root
orca node join --type proxmox --host 192.168.1.100 --ssh-key ~/.ssh/orca_ed25519

# Proxmox with pre-pinned host key
orca node join --type proxmox --host 192.168.1.100 --host-key-fingerprint SHA256:abc123...
```

### `orca node leave`

Remove a node from the orca registry.

```
orca node leave [node-id] [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--id` | string | `""` | Node ID (alternative to positional argument) |

### `orca node list`

List all nodes in the orca registry.

```
orca node list [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--watch` | bool | `false` | Stream nodes until Ctrl-C (table refresh or `--json` per-event) |

**Output columns**: `ID  NAME  ADDRESS  STATE`

### `orca node key-reset`

Reset the SSH known_hosts entry for a node.

```
orca node key-reset <node>
```

Removes the pinned SSH host key for `<node>` from the local
`known_hosts` file. The next connect re-pins the key via TOFU or
`--host-key-fingerprint`. Local only — does not touch the remote
host's `authorized_keys`.

`<node>` is the node name (for proxmox nodes, this is the host address).

**Example**:
```bash
orca node key-reset 192.168.1.100
```

### `orca node drain`

Drain a node: stop its allocations and mark it drained (REQ-061).

```
orca node drain <host> [flags]
```

Marks the node as "draining" (scheduler skips draining nodes), stops
every running allocation via SSH (`systemctl stop orca-alloc-<id>.service`),
waits for them to stop, and marks the node "drained". This is NOT
live-migration — use `orca job migrate` to reschedule first.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--timeout` | duration | `30s` | Max time to wait for allocations to stop |

### `orca node capacity`

Manage node capacity declarations (bin-packing scheduler input).

```
orca node capacity <subcommand>
```

#### `orca node capacity show`

Show capacity for a node (defaults to `self`).

```
orca node capacity show [node-id] [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--node` | string | `""` | Node ID (defaults to `self`) |

**Output**: `Node:`, `CPU:` (millicores), `Memory:` (MiB), `Disk:` (MiB), `Updated:`

#### `orca node capacity set`

Declare capacity for a node.

```
orca node capacity set [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--cpu` | int | `0` | CPU capacity in millicores (1000 = 1 vCPU) |
| `--memory` | int | `0` | Memory capacity in MiB |
| `--disk` | int | `0` | Disk capacity in MiB |
| `--node` | string | `""` | Node ID (defaults to `self`) |

**Example**:
```bash
orca node capacity set --cpu 4000 --memory 8192 --disk 100000
orca node capacity set --cpu 2000 --memory 4096 --node web-1
```

#### `orca node capacity list`

List all node capacity declarations.

```
orca node capacity list
```

**Output columns**: `NODE  CPU(mc)  MEM(MiB)  DISK(MiB)  UPDATED`

---

## `orca job`

Manage orca jobs — run, list, stop, lint, verify, migrate, restart.

### `orca job run`

Run a job from a spec file.

```
orca job run <spec> [flags]
```

Dispatches by file extension:
- `.md` → Markdown frontmatter parser (v0.9 canonical)
- `.yaml` / `.yml` → YAML frontmatter parser
- `.hcl` → Legacy HCL adapter (deprecated)

The v0.13 scheduler wiring (REQ-151) deploys to remote nodes via the
scheduler → emitter → SSH-push pipeline. When no remote nodes are
available, falls back to local execution (dev mode).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--target` | string | `""` | Pin job to a specific node ID (overrides bin-packing scheduler) |
| `--idempotency-key` | string | `""` | Idempotency key for cross-node dispatch dedupe |

**Examples**:
```bash
orca job run web-app.md
orca job run api.yaml --target node-abc-123
orca job run worker.md --idempotency-key deploy-2026-08-05
```

> **Deprecated**: `orca job run <spec.hcl>` (legacy HCL jobspec) still
> works via the adapter but emits a deprecation warning. Migrate `.hcl`
> specs to `.md` (see [docs/jobspec.md](jobspec.md)).

### `orca job list`

List all jobs.

```
orca job list [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--watch` | bool | `false` | Stream jobs until Ctrl-C (table refresh or `--json` per-event) |

**Output columns**: `ID  NAME  STATUS  EXIT`

**Examples**:
```bash
orca job list
orca job list --watch           # table refresh
orca job list --watch --json    # NDJSON: {"event":"update","job":{...}}
```

### `orca job stop`

Stop a running job by sending `systemctl stop orca-alloc-<name>-*` to
the node running the allocation via SSH, then mark the job as stopped
in the DB (REQ-158, P09).

```
orca job stop [job-id] [flags]
```

If `--peer` is not given, the node is looked up from the allocation
history. If no node is found, the DB status is updated anyway (soft
stop fallback for local-run jobs).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--id` | string | `""` | Job ID (alternative to positional argument) |
| `--peer` | string | `""` | Peer address (host:port) running the allocation (auto-detected from alloc history if empty) |
| `--timeout` | duration | `2m0s` | SSH command timeout |

**Example**:
```bash
orca job stop abc-123-def
orca job stop --id abc-123-def
orca job stop abc-123-def --peer 192.168.1.100:22
```

### `orca job logs`

Show task output for a job.

```
orca job logs [job-id] [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--id` | string | `""` | Job ID (alternative to positional argument) |

**Example**:
```bash
orca job logs abc-123-def
```

### `orca job lint`

Lint a jobspec (schema, CEL, body, migration, best-practice) without
applying it (REQ-084).

```
orca job lint <spec> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--explain` | bool | `false` | Print the rationale for each finding |
| `--format` | string | `"text"` | Output format: `text` or `json` |

Exit codes: 0 = no errors (warnings OK), 1 = errors found.

### `orca job verify`

Dry-run a jobspec through the lead (no apply).

```
orca job verify <spec> [flags]
```

Validates the spec through the render + txn pipeline without staging
or applying it. Reports any schema, constraint, or render errors.

### `orca job migrate`

Drain + reschedule a job onto a target node (REQ-116).

```
orca job migrate <job-id> [flags]
```

Stops the job on its current node and re-submits it to the scheduler
(pinned to `--target` if given).

### `orca job restart`

Restart an allocation to pick up EnvironmentFile drift (REQ-113).

```
orca job restart <job-id> [flags]
```

Restarts the systemd unit(s) for the job's allocation(s) via SSH so they
re-read the `.env` / `.env.secrets` files without a full redeploy.

---

## `orca ns`

Manage orca namespaces under `ORCA_HOME` (R-002).

Each namespace is a directory with `ns.md`, `.env`, `.env.secrets`,
`db/`, `jobs/`, `alloc/`. The implicit root namespace `_defaults`
always exists; every namespace inherits from `_defaults` and cannot
opt out (D-185, D-187).

### `orca ns list`

List all namespaces under `ORCA_HOME`.

```
orca ns list
```

**Output columns**: `NAME  DEFAULT  PATH` (`_defaults` marked `*`)

### `orca ns create`

Create a namespace directory + `ns.md`.

```
orca ns create <name> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--parent` | string | `""` | Parent namespace (default `_defaults`; implicit root always appended last) |
| `--inherits-env` | bool | `true` | Inherit env from parents |
| `--inherits-secrets` | bool | `true` | Inherit secrets from parents |

**Example**:
```bash
orca ns create prod --parent _defaults
orca ns create staging --parent prod
```

### `orca ns delete`

Remove an empty namespace directory.

```
orca ns delete <name>
```

Refuses if `jobs/` or `alloc/` contain files. The implicit root
`_defaults` cannot be deleted.

### `orca ns inspect`

Print the effective inheritance chain, merged env, and constraints.

```
orca ns inspect <name>
```

**Output**: `Namespace:`, `Chain:` (e.g., `prod -> _defaults`), `Env:`
(sorted keys), `Constraints:` (unioned CEL expressions).

### `orca ns validate`

Run cycle + missing-parent + schema checks on a namespace.

```
orca ns validate <name>
```

Exits 0 if valid, 1 on error. Runs over ALL namespaces under
`ORCA_HOME` (parsing + resolving validates cycles and missing parents
across the set).

### `orca ns inherit`

Set the parent namespace for a namespace (R-002).

```
orca ns inherit <name> [flags]
```

Updates `ns.md` frontmatter (`parents` field) and validates the new
chain has no cycles. The implicit root `_defaults` is always appended
last (D-185).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--parent` | string | `""` | Parent namespace to inherit from (required) |

**Example**:
```bash
orca ns inherit staging --parent prod
```

### `orca ns set-constraint`

Set a constraint on a namespace (stored in `ns.md` frontmatter).

```
orca ns set-constraint <name> <key>=<value>
```

Constraints are `key=value` strings (e.g., `max-allocs=10`) stored in
`ns.md` frontmatter and unioned across the inheritance chain by the
resolver.

**Example**:
```bash
orca ns set-constraint prod max-allocs=10
```

---

## `orca secrets`

Manage encrypted `.env.secrets` per namespace (REQ-080).

Each namespace has a `.env.secrets` file at `<ORCA_HOME>/<ns>/.env.secrets`
containing one `base64(nonce||ciphertext||tag)` blob per line. Encryption
is AES-256-GCM with a per-namespace HKDF-SHA256 sub-key derived from the
cluster `master.key` (mode 0600). The AAD is the 1-based line number,
defeating line-swap attacks.

### `orca secrets set`

Encrypt `KEY=value` and add or update it in `<namespace>/.env.secrets`.

```
orca secrets set <namespace> <KEY=value>
```

### `orca secrets get`

Decrypt the secret named `KEY` from `<namespace>/.env.secrets` and
print its value to stdout.

```
orca secrets get <namespace> <KEY>
```

The value is printed with no trailing newline added. The value is
never logged via `slog`.

### `orca secrets list`

List the keys of all secrets stored in `<namespace>/.env.secrets`.
Values are never printed.

```
orca secrets list <namespace>
```

### `orca secrets rotate`

Re-encrypt the secret named `KEY` with a fresh nonce. The plaintext
value is unchanged.

```
orca secrets rotate <namespace> <KEY>
```

### `orca secrets delete`

Remove the secret named `KEY` from `<namespace>/.env.secrets`.

```
orca secrets delete <namespace> <KEY>
```

### `orca secrets rotate-master`

Generate a new master key, re-encrypt every namespace's `.env.secrets`
under the new key, and re-seal the master key to OIDC (REQ-129, C-30).

```
orca secrets rotate-master [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--dry-run` | bool | `false` | Report affected namespaces without writing (C-30) |

Atomic per-namespace; automatic rollback to the old key on any failure.

---

## `orca acl`

Manage the cluster ACL (P02, v0.11). Identities are either
SPIFFE workload URIs (`spiffe://orca.local/ns/<ns>/sa/<sa>/<alloc>`) or
operator token IDs. Permissions are deny-by-default.

State is stored at `ClusterDir()/acl.json` (mode 0600).

### `orca acl grant`

Grant permissions to an identity on a namespace.

```
orca acl grant <identity> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--namespace` | string | `""` | Namespace scope (required for tokens; defaults to spiffe path ns) |
| `--permissions` | string | `"read"` | Comma-separated list of `read`,`write`,`admin` |

### `orca acl revoke`

Revoke an identity's entry on a namespace.

```
orca acl revoke <identity> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--namespace` | string | `""` | Namespace scope (required for tokens; defaults to spiffe path ns) |

### `orca acl list`

List all ACL entries.

```
orca acl list
```

### `orca acl check`

Check whether an identity has the given permission on a namespace.
Exits 0 if allowed, 1 if denied.

```
orca acl check <identity> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--namespace` | string | `""` | Namespace scope (required for tokens; defaults to spiffe path ns) |
| `--permission` | string | `"read"` | Permission to check: `read`, `write`, or `admin` |

---

## `orca cluster`

Cluster-wide operations: cutover, lead rotation, mixed-version
compatibility checks, and master-key seal/unseal (REQ-147, D-241, C-35).

### `orca cluster cutover`

Stop v0.8 orca daemons and adopt running allocs (P14b).

```
orca cluster cutover
```

Stops the v0.8 orca-daemon on every peer that still runs one, discovers
its running allocations (`orca-alloc-*.service`), and adopts each into
the SSH-push path. Idempotent.

### `orca cluster rotate-lead`

Rotate the cluster lead to a new bare Linux node (REQ-114, R-003).

```
orca cluster rotate-lead --to <new-lead-host> [flags]
```

Steps: verify the new lead is a registered bare Linux node (Proxmox
nodes are ineligible — hypervisor kernel is shared with guests), copy
the cluster CA + master key + config + txn log to the new lead via
SSH, update local cluster state, rotate the SSH keypair, and deploy
the new public key to every peer. Workloads keep running.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--to` | string | `""` | New lead host (required) |
| `--debug` | bool | `false` | Enable debug logging |

### `orca cluster compat-check`

Check mixed-version tolerance across peers (REQ-065, C-13).

```
orca cluster compat-check
```

Verifies each peer's orca version, txn manifest format compatibility,
render-contract JSON schema compatibility, and that no new required
fields break old peers.

### `orca cluster seal`

Seal the cluster master key (REQ-147, D-241, C-35).

```
orca cluster seal
```

Encrypts the raw master key at `ClusterDir()/master.key` with a key
derived from the OIDC ID token subject (if `orca auth login` has been
run) or the cluster CA fingerprint (mTLS-only offline path). The
sealed blob is written to `ClusterDir()/master.key.sealed` (0600).
Five Shamir shards (3-of-5 recovery) are printed to stdout — store
them offline. The raw master key is then deleted from disk.

### `orca cluster unseal`

Unseal the cluster master key (REQ-147, D-241, C-35).

```
orca cluster unseal [flags]
```

Reads the sealed blob at `ClusterDir()/master.key.sealed` and unwraps
the master key using the OIDC ID token subject or the cluster CA
fingerprint. The unwrapped master key is written back to
`ClusterDir()/master.key` (0600). The raw key is zeroed from memory on
process exit.

With `--recovery`, the operator is prompted for 3 of the 5 Shamir
shards printed at seal time (IdP-lost recovery path).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--recovery` | bool | `false` | Shamir recovery: prompt for 3-of-5 shards (if IdP lost) |

---

## `orca doctor`

Run self-checks on the orca installation.

```
orca doctor [subcommand]
```

Without a subcommand, runs all checks and prints a PASS/WARN/FAIL
report per check.

### Subcommands

| Command | Description |
|---------|-------------|
| `orca doctor cert` | CA, server cert, expiry, fingerprint checks |
| `orca doctor network` | Network reachability via mTLS `/healthz` probe |
| `orca doctor db` | Database integrity (`PRAGMA integrity_check` + migration version) |
| `orca doctor os` | OS detection self-check (verifies `/etc/os-release` matches stored node) |
| `orca doctor proxmox` | Proxmox node reachability via SSH `pveversion`/`pvecmd status` probe; audits `/etc/sudoers.d/orca` |
| `orca doctor nft` | nftables ingress ruleset self-check (R-017); audits live ruleset against on-disk hash |
| `orca doctor audit` | Verify the audit log hash chain (tamper-evidence check, REQ-125) |
| `orca doctor modes` | Verify security-sensitive file permissions (REQ-033/130, F13) |
| `orca doctor oidc` | Check the bundled Dex OIDC provider health (P06) |
| `orca doctor db-retention` | Check DB row counts for unbounded growth (REQ-158) |
| `orca doctor no-orca-on-server` | Verify no orca binary/service/process on peers (REQ-086, R-001) |

**Example**:
```bash
orca doctor
orca doctor cert
orca doctor proxmox --json
orca doctor audit
orca doctor modes
```

---

## `orca audit`

View orca audit log (security-first observability).

### `orca audit list`

List recent audit log entries.

```
orca audit list [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--limit` | int | `50` | Max entries to show |

**Output columns**: `TIMESTAMP  ACTOR  ACTION  RESOURCE  RESULT`

---

## `orca backup`

Create a signed tar.gz backup of `ORCA_HOME` (P04).

```
orca backup [flags]
```

Walks `ORCA_HOME` recursively, excludes `/run/orca/*`, `*.sock`,
`*.db-wal`, `*.db-shm`, packs the rest into a tar.gz, and computes an
HMAC-SHA256 signature using the cluster master key.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--out` | string | `""` | Output tarball path (default: `orca-backup-<timestamp>.tar.gz` in CWD) |

---

## `orca restore`

Restore `ORCA_HOME` from a verified signed backup (P04/P07).

```
orca restore [flags]
```

Verifies the HMAC-SHA256 signature before extracting. Reconciles with
live state: refuses to clobber running allocations unless `--force` is
given. With `--dry-run`, extracts to a temp dir and reports what would
be restored without touching `ORCA_HOME`.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--in` | string | `""` | Input tarball path (required) |
| `--force` | bool | `false` | Stop running allocs before restore |
| `--dry-run` | bool | `false` | Extract to temp dir; report without writing |

---

## `orca upgrade`

Upgrade orca to a new version (thin wrapper; R-017 cutover).

```
orca upgrade [flags]
```

Handles the R-017 binding cutover (Traefik :443 → 127.0.0.1:8443 +
nftables), creates the `orca` system user on existing peers (C-27),
optionally imports the v0.8 internal CA into step-ca, and runs
`Migratev08tov11` if a v0.8 layout is detected. Idempotent.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--to` | string | `""` | Target version (e.g., `v0.12.10`) (required) |
| `--dry-run` | bool | `false` | Report what would be done without making changes |
| `--force` | bool | `false` | Skip cutover verification (use with caution) |
| `--import-ca` | bool | `false` | Import the v0.8 internal CA into step-ca during upgrade |

---

## `orca metrics`

Start a standalone HTTP server exposing Prometheus text-exposition
metrics at `/metrics` and a liveness probe at `/healthz`.

```
orca metrics [flags]
```

No orca daemon required (R-001). Polls cluster state periodically and
updates gauges.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--addr` | string | `":9100"` | Listen address for the metrics HTTP server |

---

## `orca logs`

Aggregate journald logs across registered nodes via SSH fanout
(REQ-117).

```
orca logs [flags]
```

Runs `journalctl -u 'orca-alloc-*' --since <dur> --output json` on each
peer, parses the JSON-per-line output, and streams the entries with a
`[<hostname>]` prefix (multi-node) or raw (single-node). `--json`
outputs the raw journalctl JSON lines verbatim.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--all-nodes` | bool | `false` | Fan out to every registered node |
| `--node` | string | `""` | Single node host to query |
| `--job` | string | `""` | Filter units to `orca-alloc-<name>-*` |
| `--since` | string | `""` | Duration (e.g., `5m`, `1h`, `30m`) |
| `--json` | bool | `false` | Output raw journalctl JSON lines |

**Examples**:
```bash
orca logs --all-nodes --since 5m
orca logs --node web-1 --since 1h
orca logs --all-nodes --job web --since 30m --json
```

---

## `orca cache`

Manage the CLI-side SQLite cache (R-008) at `ORCA_HOME/orca_cache.db`.

```
orca cache <subcommand>
```

Read-only list commands (`node`/`job`/`ns list`) populate the cache;
writes bypass it. The `--watch` flag bypasses the cache entirely
(streaming).

### `orca cache show`

Print cache stats (per-class counts, sizes, oldest entry).

```
orca cache show
```

### `orca cache invalidate`

Drop all entries for a cache class.

```
orca cache invalidate <class>
```

**Example**:
```bash
orca cache invalidate nodes
```

### `orca cache invalidate-all`

Drop every entry in the cache.

```
orca cache invalidate-all
```

---

## `orca drift`

Detect and remediate control-plane drift (P10b). Orca's drift detector
is a BACKUP (R-019): the primary consistency mechanism is systemd /
Traefik / step-ca / Syncthing themselves. Pre-flight drift blocks
txn apply (R-020).

```
orca drift <subcommand>
```

### `orca drift show`

Show the aggregated drift events from the lead.

```
orca drift show [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--peer` | string | `""` | Filter to a single peer host |

### `orca drift watch`

Stream drift events from the lead's aggregated state.

```
orca drift watch [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--interval` | duration | `2s` | Poll interval |
| `--paths` | strings | `[]` | Comma-separated glob patterns to watch (default: all) |

### `orca drift acknowledge`

Record operator acknowledgment for the given path in
`drift-acknowledgments.json` on the lead. Acknowledged drift no longer
blocks txn apply for that namespace (R-020).

```
orca drift acknowledge <peer> <path> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--timeout` | duration | `2m0s` | SSH command timeout |

### `orca drift remediate`

Trigger `orca-remediate.sh` on the lead for the given path.

```
orca drift remediate <peer> <path> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--force` | bool | `false` | Bypass the cooldown window (C4) |
| `--timeout` | duration | `2m0s` | SSH command timeout |

### `orca drift config`

Show or validate the drift config.

```
orca drift config <subcommand>
```

#### `orca drift config show`

Show the current drift config.

```
orca drift config show
```

#### `orca drift config validate`

Validate the drift config.

```
orca drift config validate
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--config` | string | `""` | Path to drift config JSON (default: built-in) |

---

## `orca txn`

Manage orca's transactional control-plane updates (P10a).

A transaction (txn) is a content-addressed desired-state bundle
(`apply.sh` + `verify.sh` + `rollback.sh` + signed manifest) staged to
the lead peer and applied idempotently. Cluster-wide txns require
explicit operator acknowledgement; namespace-scoped txns only touch
the given namespace (C-23).

```
orca txn <subcommand>
```

### `orca txn apply`

Apply a staged txn on the lead peer (idempotent; C-09 failure contract).

```
orca txn apply <txn-id> [flags]
```

The txn must already be staged on the lead under
`/run/orca/txns/<txn-id>/`. Cluster-wide txns (no `--namespace`)
require `--force` + `--i-understand-the-risk` (or `--yes` for
non-interactive). Namespace-scoped txns (`--namespace <ns>`) only
touch that namespace.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--namespace` | string | `""` | Namespace scope (cluster-wide if empty) |
| `--force` | bool | `false` | Acknowledge cluster-wide risk |
| `--i-understand-the-risk` | bool | `false` | Acknowledge cluster-wide risk (explicit) |
| `--yes` | bool | `false` | Non-interactive acknowledgement (skip prompt) |

### `orca txn list`

List staged + applied transactions.

```
orca txn list
```

### `orca txn show`

Show txn details (desired state, manifest, status).

```
orca txn show <txn-id>
```

### `orca txn rollback`

Run `rollback.sh` for a staged txn on the lead peer.

```
orca txn rollback <txn-id> [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--lead` | string | `""` | Lead peer address (host:port) |
| `--timeout` | duration | `2m0s` | SSH rollback timeout |

---

## `orca nft`

Inspect and manage the nftables ingress ruleset (R-017). Orca's ingress
is hybrid: Traefik binds `127.0.0.1:8443` and nftables DNATs the public
`:443` to it.

```
orca nft <subcommand>
```

### `orca nft show`

Show the live `inet orca-ingress` table on the peer (default: lead).

```
orca nft show [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--peer` | string | `""` | Peer host to query (default: lead) |

### `orca nft diff`

Compare the live nft ruleset against the expected from a txn.

```
orca nft diff [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--against` | string | `""` | Txn-ID to diff against (required) |

### `orca nft doctor`

Alias for `orca doctor nft`.

```
orca nft doctor
```

### `orca nft country`

GeoIP country-block management (opt-in). Manages the `orca_geoip_block`
nft set.

```
orca nft country <subcommand>
```

#### `orca nft country block add`

Add country codes to the GeoIP block set.

```
orca nft country block add <cc-list>
```

Adds one or more ISO-3166 alpha-2 country codes (comma-separated) to the
`orca_geoip_block` nft set on the lead.

**Example**:
```bash
orca nft country block add RU,CN
```

### `orca nft rate`

Rate-limit meter management.

```
orca nft rate <subcommand>
```

#### `orca nft rate limit set`

Adjust the forward-chain rate-limit meter.

```
orca nft rate limit set [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--rate` | int | `0` | Rate limit in packets/second (required, >0) |

Re-renders `/etc/nftables.d/orca.nft` with the new rate and applies it
on the lead. The burst is set to 2x the rate when not specified.

---

## `orca cert` *(deprecated)*

Manage orca certificates (CA, server, rotation).

> **Deprecated**: The v0.9 re-architecture replaces the internal CA
> with step-ca (D-101/REQ-076). The `orca cert` command tree is
> retained for the dual-write window and scheduled for deletion.
> The v0.12 milestone closed the dual-write window (REQ-138).

```
orca cert <subcommand>
```

### Subcommands

| Command | Description |
|---------|-------------|
| `orca cert ca-init` | Initialize a local orca CA (`ca.crt` + `ca.key`) |
| `orca cert gen` | Generate a server cert (CSR + sign) |
| `orca cert show` | Print the server cert (private keys redacted; REQ-035) |
| `orca cert renew` | Rotate the server cert (REQ-034) |
| `orca cert fingerprint` | Print the SHA-256 fingerprint of `ca.crt` or `server.crt` |

---

## `orca auth`

OIDC authentication for human operators (zero-trust identity, R-021).

Orca uses OIDC for human-identity authentication (R-021: no Orca-issued
credentials). The bundled Dex (deployed by `orca auth init-idp`) is the
default issuer; `oidc.issuer` in config can repoint to a BYO external
IdP. The CLI performs the authorization-code + PKCE + local loopback
redirect flow; headless/CI uses the device-code flow.

```
orca auth <subcommand>
```

### `orca auth login`

Authenticate via OIDC (browser or device-code flow).

```
orca auth login [flags]
```

By default, opens the default browser for the authorization-code + PKCE
+ local loopback redirect flow. Credentials are stored at
`~/.orca/credentials.json` (0600, short-lived + refresh).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--client-id` | string | `"orca-cli"` | OIDC client ID |
| `--client-secret` | string | `""` | OIDC client secret (confidential clients; public PKCE clients omit) |
| `--device-code` | bool | `false` | Use device-code flow (headless/CI) |

### `orca auth logout`

Clear the stored OIDC credentials.

```
orca auth logout
```

### `orca auth status`

Show the current OIDC authentication status.

```
orca auth status
```

### `orca auth init-idp`

Bootstrap the bundled Dex OIDC provider on the lead.

```
orca auth init-idp [flags]
```

Deploys a bundled Dex instance on the lead node as a systemd unit,
fronted by Traefik (R-017, step-ca cert). The WebAuthn connector (P05)
provides the password-free upstream authenticator.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--rp-id` | string | `""` | WebAuthn relying-party ID (cluster Traefik domain; C-38) |

### `orca auth register`

Open the WebAuthn passkey registration page in the browser.

```
orca auth register [flags]
```

Opens the browser to the Dex WebAuthn registration page at
`https://<cluster>/orca/webauthn/register`. The operator authenticates
via an existing session, then registers a passkey (biometric or
security key). Use `--no-browser` to print the URL instead of opening
a browser.

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--no-browser` | bool | `false` | Print the URL instead of opening a browser |

See [docs/webauthn.md](webauthn.md) for the WebAuthn / passkey guide.

---

## `orca peer-setup`

Create the orca system user + drift-events dir on a peer (REQ-111).

```
orca peer-setup <peer> [flags]
```

SSH to `<peer>` and idempotently create the `orca` system user
(`useradd -r orca -s /usr/sbin/nologin`) and
`/etc/orca/state/drift-events/` owned by `orca:orca`. Also detects NFS
on `/etc/orca` (REQ-112/D-233) and logs a warning. Use `--no-orca-user`
to skip user creation (for environments with an existing service
account).

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--no-orca-user` | bool | `false` | Skip orca system user creation (env has existing service account) |
| `--timeout` | duration | `2m0s` | SSH command timeout |

---

## `orca collector`

Manage the lead-side collector: the aggregator (`orca-aggregate.sh`,
10s cadence, merges per-peer state into `cluster.json` + drift-event
aggregation per REQ-107) and the watchdog (`orca-watchdog.sh`, 30s
cadence, detects aggregator starvation per C-11). Opt-in (C-12).

```
orca collector <subcommand>
```

### `orca collector start`

Emit the collector scripts + systemd units and enable them.

```
orca collector start [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--dry-run` | bool | `false` | Emit scripts/units without enabling or running systemctl |
| `--root` | string | `"/"` | Install root for emitted paths (for testing use a temp dir) |

### `orca collector stop`

Disable and remove the collector scripts + systemd units.

```
orca collector stop [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--dry-run` | bool | `false` | Remove scripts/units without disabling or running systemctl |
| `--root` | string | `"/"` | Install root for emitted paths (for testing use a temp dir) |

### `orca collector status`

Report whether the collector (aggregator + watchdog) is running.

```
orca collector status
```

---

## `orca daemon` *(deprecated)*

Run the orca daemon (HTTP API + health checks).

> **Deprecated**: The v0.9 re-architecture replaces the daemon with
> SSH-push (R-001). The daemon is repurposed to `drain-and-stop` in
> v0.11-P05. The v0.12 milestone closed the dual-write window (REQ-138).
> The legacy daemon plaintext/mTLS mode is deleted; mTLS is available
> for metrics/health probes only.

```
orca daemon [flags]
```

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--addr` | string | `":8080"` | Listen address |
| `--pprof` | bool | `false` | Enable pprof endpoint (loopback-only by default) |

---

## Deprecated commands

The following commands are from the v0.8 daemon/mTLS model and are
**deprecated**. The v0.12 milestone (REQ-138) closed the dual-write
window — the legacy CA/mTLS/daemon paths are deleted. The `orca cert`
command tree and `orca daemon` are retained as thin stubs during the
final removal cycle.

> **`orca daemon`** — Run the orca daemon. Replaced by SSH-push
> (R-001). The daemon is repurposed to `drain-and-stop` and the legacy
> plaintext/mTLS mode is deleted (REQ-138).

> **`orca cert`** — Manage orca certificates. Replaced by step-ca
> (D-101). Scheduled for deletion.

> **`orca node join` (mTLS path)** — The localhost mTLS join path
> (without `--type proxmox`) is deprecated. The v0.9 canonical path is
> SSH-push (`--type proxmox`) or local execution (no join needed).

> **`orca job run <spec.hcl>`** — Legacy HCL jobspec. Migrate to `.md`
> (see [docs/jobspec.md](jobspec.md)).

> **`orca status`** — v0.1 stub. Use `orca node list` + `orca metrics
> /healthz`.

To suppress deprecation warnings during migration, use
`--no-deprecation-warnings`:
```bash
orca --no-deprecation-warnings daemon
```

---

## See also

- [docs/jobspec.md](jobspec.md) — Markdown frontmatter jobspec reference
- [docs/ingress.md](ingress.md) — Traefik ingress configuration guide
- [docs/namespace.md](namespace.md) — Namespace and path layout
- [docs/install.md](install.md) — Installation guide
- [docs/security-runbook.md](security-runbook.md) — Security runbook (seal/unseal, rotation, incident response)
- [docs/webauthn.md](webauthn.md) — WebAuthn / passkey registration
- [docs/threat-model.md](threat-model.md) — STRIDE threat model + zero-trust architecture
- [docs/oidc.md](oidc.md) — OIDC configuration (Dex quickstart, BYO IdP)
- [examples/full-stack/](../examples/full-stack/) — Full-stack example with ingress
