# Workspace preprocessing CLI contract `thothctl` is the only supported host entrypoint for workspace preprocessing. ## Invocation ```text thothctl --installation /thothii-installation.yaml workspace inspect --workspace [--json] thothctl --installation /thothii-installation.yaml workspace preprocess dwh --workspace [--resume <32hex>] [--json] thothctl --installation /thothii-installation.yaml workspace schema suggest-fks --workspace [--from-sql ]... [--assume ]... [--output ] [--json] thothctl --installation /thothii-installation.yaml workspace schema check --workspace [--annotations --reviewed-candidates ] [--json] thothctl --installation /thothii-installation.yaml workspace index-schema --workspace [--json] thothctl --installation /thothii-installation.yaml workspace preprocess evidence --workspace [--dry-run] [--resume <32hex>] [--json] thothctl --installation /thothii-installation.yaml workspace preprocess run --workspace [--resume <32hex>] [--json] ``` ## Validation - `--installation` is mandatory and absolute. - `--workspace` is mandatory exactly once and must match `[a-z][a-z0-9-]{2,62}`. - `--resume` values must be 32 lowercase hex characters. - `--json` may be supplied once. - `schema suggest-fks` - allows at most 32 `--from-sql` files; - each SQL file must be a canonical regular file, UTF-8, non-symlink, max 1 MiB; - total SQL ingress must not exceed 16 MiB; - allows at most 256 `--assume` values, each `column=table`, max 256 bytes; - `--output` must name a new canonical path; existing targets are refused. - `schema check` - `--annotations` and `--reviewed-candidates` are all-or-nothing; - annotations must be UTF-8, canonical, non-symlink, max 16 MiB; - `--reviewed-candidates` must match `sha256:<64 lowercase hex>`. - Unknown flags, passthrough separators, and shell fragments are rejected before Docker runs. ## Container boundary `thothctl` resolves the selected `core` image from the rendered installation, converts it to an immutable local image ID, writes a one-shot final override that pins both `core` and `workspace-maintenance` to that ID with `pull_policy: never`, and runs only: ```text docker compose run --rm --no-deps --no-TTY --name workspace-maintenance ``` The request is streamed as one schema-versioned JSON document over stdin. Public stdout is always one schema-versioned JSON result; human mode is rendered from an allowlisted subset of that same result. ## Public JSON result ```json { "schemaVersion": 1, "status": "succeeded|unchanged|dry_run|blocked|failed", "code": "ok|workspace_not_found|workspace_not_activatable|binding_missing|preprocessing_conflict|preprocessing_resume_mismatch|manual_review_required|evidence_materialization_required|effective_config_mismatch|semantic_index_incompatible|annotation_invalid|egress_policy_refused", "workspaceId": "abc", "workspaceRevision": "1234567890abcdef1234567890abcdef12345678", "descriptorBlob": "sha256:<64 lowercase hex>", "operation": "inspect|preprocess-dwh|schema-suggest-fks|schema-check|index-schema|preprocess-evidence|preprocess-run", "runId": "", "childRuns": {"stage": ""}, "completedStages": ["stage"], "counts": {"name": 1}, "artifactIdentities": [{"kind": "fk_candidates", "digest": "sha256:<64 lowercase hex>"}], "warnings": ["safe warning"] } ``` `thothctl --json` parses the operator stdout strictly and re-encodes only the public fields above. ## Exit codes - `0`: `succeeded`, `unchanged`, or `dry_run` - `3`: `blocked` - `2`: host-side grammar or local file safety failure - `1`: operational failure or operator-reported `failed`