feat: thothctl workspace preprocessing CLI and file-ingress contracts (P2)
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Workspace preprocessing CLI contract
|
||||
|
||||
`thothctl` is the only supported host entrypoint for workspace preprocessing.
|
||||
|
||||
## Invocation
|
||||
|
||||
```text
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace inspect
|
||||
--workspace <id> [--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace preprocess dwh
|
||||
--workspace <id> [--resume <32hex>] [--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace schema suggest-fks
|
||||
--workspace <id>
|
||||
[--from-sql <regular-file>]... [--assume <column=table>]...
|
||||
[--output <new-file>] [--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace schema check
|
||||
--workspace <id>
|
||||
[--annotations <regular-file> --reviewed-candidates <sha256:hex>]
|
||||
[--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace index-schema
|
||||
--workspace <id> [--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace preprocess evidence
|
||||
--workspace <id> [--dry-run] [--resume <32hex>] [--json]
|
||||
|
||||
thothctl --installation <absolute>/thothii-installation.yaml workspace preprocess run
|
||||
--workspace <id> [--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 <owned-name> workspace-maintenance <fixed-command>
|
||||
```
|
||||
|
||||
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": "<optional 32hex>",
|
||||
"childRuns": {"stage": "<optional 32hex>"},
|
||||
"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`
|
||||
Reference in New Issue
Block a user