CLI Reference¶
Complete reference for all streamt CLI commands.
Which Command?¶
| Goal | Command | Needs Kafka? |
|---|---|---|
| Check YAML is valid | validate |
No |
| Generate SQL/JSON artifacts | compile |
No |
| Package artifacts + manifest + checksums | build |
No |
| Export managed topics as Strimzi KafkaTopic YAML | export strimzi |
No |
| View data lineage | lineage |
No |
| Export Backstage catalog entities | docs backstage |
No |
| Export DataHub metadata-file proposals | docs datahub |
No |
| Export OpenLineage design metadata | docs openlineage |
No |
| Declare existing Kafka topics as external sources | import |
Yes |
| See what would change on deploy | plan |
Yes |
| Compare local vs deployed state | diff |
Yes |
| Initialize configured PostgreSQL state | state init |
No |
| Migrate configured PostgreSQL state to schema v2 | state migrate-postgres-v2 |
No |
| Probe instantaneous PostgreSQL lock availability | state lock-status |
No |
| Inspect ownership/recovery metadata | state status |
No |
| Create reviewed evidence for one unfinished operation | state recovery-plan |
Sometimes1 |
| Execute one exact reviewed recovery | state recover |
Sometimes1 |
| Claim an existing declared topic or schema subject | adopt |
Yes |
| Deploy to infrastructure | apply |
Yes |
Global Options¶
These options are available for all commands:
streamt [OPTIONS] COMMAND [ARGS]
Options:
--output, -o FORMAT Output format: text (default) or json
--version Show version and exit
--help Show help message and exit
Environment Selection
In multi-environment mode, specify the target environment with --env or the STREAMT_ENV variable. The CLI flag takes precedence over the environment variable.
Structured JSON Output¶
Use --output json (or -o json) to get machine-readable output from any command. All JSON responses follow a consistent envelope:
On error, status is "error" and errors contains structured entries with machine-readable codes:
{
"status": "error",
"command": "validate",
"data": {},
"errors": [
{
"code": "E101_SOURCE_NOT_FOUND",
"message": "Source 'orders' not found",
"suggestion": "Available: events, payments"
}
],
"warnings": []
}
State-operation failures that occur after a durable intent exists also include
the canonical operation_id. The same identifier appears in text output so an
operator can inspect status or run recovery without guessing which attempt the
error describes. Provider credentials, endpoints, lock handles, and revision
tokens are never included.
This makes streamt suitable for LLM agents, CI/CD pipelines, and programmatic integrations.
Commands¶
init¶
Initialize a new streamt project.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Directory to initialize (default: current) |
--project-name NAME |
Project name (default: directory name) |
--executor flink\|kafka_streams |
Starter executor; Flink remains the default |
--runner-image ID |
Required immutable image ID or digest for the Kafka Streams starter |
--docker-network NAME |
Local Docker bridge network for the runner |
--kafka-internal SERVERS |
Broker addresses reachable from the runner container |
--initial-offset earliest\|latest |
Explicit initial position for a fresh Kafka Streams application only |
--force |
Overwrite existing project files |
--discover |
Discover sources from existing Kafka infrastructure |
--kafka SERVERS |
Kafka bootstrap servers (required with --discover) |
--schema-registry URL |
Schema Registry URL (extracts column definitions) |
--include PATTERN |
Include only topics matching glob pattern |
--exclude PATTERN |
Exclude topics matching glob pattern |
--dry-run |
Show what would be created without writing |
Scaffold mode (default):
# Create empty project skeleton
streamt init
# Custom name and directory
streamt init --project-dir ./my-pipeline --project-name payments
The Kafka Streams starter creates a managed input topic, a SQL transformation,
and a metadata-only downstream application. Its files include sample events and
the creation/no-op walkthrough. Initialization does not build an image, connect
to Kafka or Docker, deploy jobs, or schedule the declared custom application.
Kafka Streams options cannot be combined with --discover; use the documented
external import path for an existing topic.
Discover mode (from existing Kafka):
# Discover topics
streamt init --discover --kafka localhost:9092
# With Schema Registry (extracts columns from Avro schemas)
streamt init --discover --kafka localhost:9092 --schema-registry http://localhost:8081
# Filter topics
streamt init --discover --kafka localhost:9092 --include "orders.*"
# Preview without writing
streamt init --discover --kafka localhost:9092 --dry-run
runtime build¶
Build the packaged Kafka Streams runner on the selected local Docker daemon. No project is required. The output image has an immutable SHA-256 identity and no tag is created or published.
--dry-run reads packaged build inputs and reports their hash without processes,
network access, Docker calls or file writes. An actual build requires Docker
Engine and Buildx, downloads pinned base images and Maven dependencies, and
returns data.image plus a runtime.kafka_streams.image configuration fragment.
--timeout bounds the build itself (30–1800 seconds, default 600); local daemon
checks have separate short bounds. Build logs and credentials are not returned
in the public result. This command never pushes or tags an image.
The runner supports managed creation, unchanged repeat apply, and reviewed
predicate-only replacement. A failed runner, lost offsets, replaced topics, or
a pending operation cannot be bypassed by building another image or using
--force. Use the original plan and explicit state resume workflow for an
interrupted replacement. See the starting guide.
import¶
Add existing Kafka topics to an existing project as external source declarations. Infrastructure access is read-only: import reads topic metadata and, when configured, Schema Registry metadata. It never creates or changes Kafka topics, registers schemas, or writes ownership state.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Existing project directory (default: current) |
--env ENV |
Target environment in multi-environment mode |
--include PATTERN |
Include topics matching a glob; repeatable |
--exclude PATTERN |
Exclude topics matching a glob; repeatable |
--output-file PATH |
New declaration directly in sources/ (default: sources/imported.kafka.yml) |
--schemas / --no-schemas |
Use configured Schema Registry enrichment (default: enabled) |
--dry-run |
Return the complete deterministic preview without writing |
# Preview existing topics using runtime credentials from the project
streamt import --dry-run
# Import selected domains into a new declaration file
streamt import \
--include "orders.*" \
--include "payments.*" \
--exclude "*.retry" \
--output-file sources/commerce.kafka.yml
# Import Kafka metadata without Schema Registry enrichment
streamt import --no-schemas
Import skips topics already declared by exact topic name. Every generated declaration
contains ownership: {mode: external}. The command refuses sanitized source-name
collisions, incomplete live topic metadata, and newly introduced project-validation
errors. It stages and durably installs a new file with atomic no-replace semantics;
use --dry-run and merge manually or select another output path when the target exists.
Schema enrichment currently checks only the conventional {topic}-value subject.
It reads that subject directly without requiring subject-list or compatibility-config
permissions and pins the resolved numeric version. Avro and JSON Schema can contribute
top-level columns; Protobuf contributes only its external subject/version/format
reference. A service outage stops further enrichment requests while Kafka-only import
continues. Key subjects and non-topic resources are outside this MVP.
Example generated declaration:
sources:
- name: orders_events
topic: orders.events
ownership:
mode: external
schema:
registry: confluent
subject: orders.events-value
version: 4
format: avro
columns:
- name: order_id
type: STRING
With global --output json, resources, declarations, counts, warnings, and created
files are emitted in stable topic order for automation. data.discovery reports
read-only access, enrichment availability, and discovery limits. Each resource has
provenance and completeness: schema lookup distinguishes not requested, not
found, resolved, failed, and skipped after an outage. Inferred columns are not
runtime-verified. Import does not sample records or reconstruct application SQL/code.
validate¶
Validate project configuration, syntax, and governance rules.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--all-envs |
Validate all environments sequentially |
--model, -m MODEL |
Validate only this model and its dependencies |
--check-schemas |
Read external subjects, versions, formats, and references from Schema Registry |
--strict |
Treat warnings as errors |
Examples:
# Basic validation
streamt validate
# Validate specific environment
streamt validate --env dev
streamt validate --env prod
# Validate all environments at once
streamt validate --all-envs
# With schema registry validation
streamt validate --check-schemas
# Strict mode (fail on warnings)
streamt validate --strict
Without --check-schemas, validation is offline. The live check never registers
or changes schemas. It decodes Avro and JSON Schema content and resolves their
version-pinned references. For Protobuf it verifies subject/version/type and the
reference graph, but does not parse messages or infer columns.
Output:
✓ Project 'payments-pipeline' is valid
Sources: 3
Models: 5
Tests: 4
Exposures: 2
Governance:
✓ All topics meet minimum partition requirement
✓ All models have descriptions
⚠ 1 model missing tests (warning)
compile¶
Parse, validate, and generate deployment artifacts.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--output-dir PATH |
Output directory (default: generated/) |
--dry-run |
Show what would be generated without writing |
Examples:
# Compile to default directory
streamt compile
# Compile for specific environment
streamt compile --env prod
# Custom output directory
streamt compile --output-dir ./build
# Preview without writing files
streamt compile --dry-run
Output:
Compiling project...
Generated artifacts:
topics/
orders.clean.v1.json
orders.metrics.v1.json
flink/
order_metrics.sql
order_metrics.json
connect/
orders_snowflake.json
Manifest written to: generated/manifest.json
build¶
Compile and package artifacts with manifest and checksums.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--output-dir PATH |
Output directory (default: build/) |
Examples:
# Build artifacts
streamt build
# Build for specific environment
streamt build --env prod --output-dir ./dist
Output:
Building project...
flink/order_metrics.sql
topics/orders.clean.v1.json
Manifest: build/manifest.json
Checksums: build/checksums.sha256
The manifest.json contains project metadata and file listing. The checksums.sha256 file contains SHA-256 hashes of all artifacts for verification.
export¶
Generate deterministic infrastructure or interoperability artifacts without applying them.
export strimzi¶
Export managed compiled topics as canonical, offline-validated Strimzi 1.2.0
KafkaTopic YAML.
Options:
| Option | Description |
|---|---|
--namespace NAMESPACE |
Required exact Kubernetes namespace for every emitted KafkaTopic |
--cluster-name NAME |
Required exact Strimzi Kafka cluster label value |
--output-file PATH |
Atomically write canonical YAML instead of writing it to stdout |
--project-dir PATH |
Project directory |
--env ENV |
Target environment in a multi-environment project |
# Write a GitOps artifact without contacting Kubernetes or Kafka
streamt export strimzi \
--namespace payments-prod \
--cluster-name payments-kafka \
--output-file kafkatopics.yaml
# Return the validated documents, counts, and warnings in the normal envelope
streamt --output json export strimzi \
--namespace payments-prod \
--cluster-name payments-kafka
Only managed topic artifacts are emitted. External topics are omitted with
W120_STRIMZI_EXTERNAL_TOPIC_OMITTED; adopted topics fail with
E509_STRIMZI_INVALID; non-topic artifacts produce the bounded
W121_STRIMZI_ARTIFACTS_OMITTED warning. Text stdout is only the canonical YAML
unless --output-file is used, in which case successful text stdout is empty.
This command does not contact Kubernetes, apply resources, install or operate Strimzi, manage credentials, configure a GitOps controller, or provide deletion safety. See Strimzi KafkaTopic export for the exact mapping, file-safety, compatibility, and unsupported boundaries.
diff¶
Compare local definitions against deployed state.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
Examples:
Output:
Topics:
~ orders.clean.v1: partitions 6 → 12
= orders.metrics.v1: no changes
Flink Jobs:
+ order_metrics: new
plan¶
Show planned changes without applying them (like terraform plan).
External artifacts remain declaration-only no-ops without live drift reads. Online planning creates only the clients required by managed resources or explicit lifecycle work; required missing runtimes are errors. Managed evidence and exact identity checks remain mandatory. Offline planning assumes managed resources are absent, not that external resources are missing; it cannot authorize apply.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--offline |
Plan without connecting to infrastructure (assumes fresh deploy) |
--out PATH |
Atomically save a deterministic reviewed-plan JSON file |
Examples:
# Plan all changes
streamt plan
# Plan for specific environment
streamt plan --env staging
# Offline plan (no Kafka/Flink needed)
streamt plan --offline
# Save the exact reviewed actions for a later apply
streamt plan --env staging --out staging.plan.json
Offline Plan
Use --offline to preview a fresh deployment without connecting to Kafka or other infrastructure. Managed resources are assumed absent and planned as creates; external declarations remain no-ops. Offline plan files cannot authorize apply; generate an online plan with live evidence before mutation.
Online planning reports ordered safety_blockers for Kafka partition
reductions, incompatible schemas, and Flink job updates. A blocked plan still
exits successfully and can be saved for review; its JSON data sets
is_apply_blocked: true. Reviewed plan format version 5 includes these blockers,
an exact ownership-state reference, and canonical ordered action evidence in its
integrity checksum. Version 1 through 4 files cannot authorize apply and are
rejected with regeneration guidance.
A sole supported Kafka Streams predicate update uses reviewed format 6. Online
planning observes the full current project and binds the exact owned generation,
retained volume, provider identities and offset lower bounds. Use --out to save
that evidence; only apply --plan can execute it. Other plans retain format 5.
Selections, mixed mutations and unsupported runner changes remain blocked.
The JSON kafka_streams_replacement field reports whether the plan file was saved
and supplies the required next commands. Offline plans never authorize replacement.
Output:
Plan: 2 to create, 1 to update, 0 to delete
Topics:
+ orders.clean.v1 (12 partitions, rf=3)
~ orders.metrics.v1 (partitions: 6 → 12)
Flink Jobs:
+ order_metrics (parallelism: 8)
Connectors:
(no changes)
apply¶
Deploy artifacts to infrastructure.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--target MODEL |
Deploy only specific model |
--select SELECTOR |
Filter by tag or selector |
--plan PATH |
Verify and apply a saved reviewed-plan file |
--runner-timeout SECONDS |
Bound each Kafka Streams replacement wait; greater than 0, at most 600, default 60. This is not a total command deadline. |
--dry-run |
Show what would be deployed |
--confirm |
Skip confirmation prompt for protected environments |
--confirm-env ENV |
Non-interactive confirm: pass environment name to verify (for agents/CI) |
--force |
Allow destructive operations when environment policy does not already permit them |
--emit-openlineage |
Emit one validated finite apply-command lifecycle through an explicit transport |
--openlineage-job-namespace NAMESPACE |
Job namespace; falls back to OPENLINEAGE_NAMESPACE |
--openlineage-kafka-namespace KAFKA-URI |
Validated shared Kafka namespace option; apply emits no datasets |
--openlineage-gateway-namespace KAFKA-URI |
Validated shared Gateway namespace option; apply emits no datasets |
Examples:
# Deploy all
streamt apply
# Deploy to specific environment
streamt apply --env dev
# Create the required reviewed plan for a protected environment
streamt plan --env prod --out prod.plan.json
# After review, verify and apply that exact plan in CI/CD
streamt apply --env prod --plan prod.plan.json --confirm-env prod
# Override destructive policy after review (unsupported migrations remain blocked)
streamt apply --env prod --plan prod.plan.json --confirm-env prod --force
# Deploy specific model
streamt apply --target order_metrics
# Deploy by tag
streamt apply --select tag:critical
# Apply the reviewed plan; target/select cannot be added after review
streamt apply --env staging --plan staging.plan.json
# Emit the finite durable apply lifecycle through an explicit File/HTTP transport
streamt apply --env prod --plan prod.plan.json --confirm-env prod \
--emit-openlineage \
--openlineage-job-namespace https://lineage.example/namespaces/prod
A reviewed plan records the project, environment fingerprint, manifest
checksum, exact ownership-state backend/store/address/serial/checksum, resource
actions, ownership requirements, and an integrity checksum. apply --plan
recompiles the project, acquires the state operation lock, verifies that exact
state before runtime setup, and then replans live infrastructure before making
changes. It rejects modified plans or drift in the project, environment,
ownership state, resource actions, or ownership decisions. Offline plans record
state: null and cannot authorize apply.
The checksum detects accidental or unreviewed modification; it is not a digital
signature and does not establish author identity.
A format-6 runner replacement takes the dedicated coordinator path under the
same state-operation lock. It verifies the full current project and original
reviewed action before each transition, then commits only the runner checksum
and one ownership serial increment. It does not use generic rollback. The
first supported update changes predicates only and is the sole mutation in
the full project. Direct apply, --target, --select, and --force do not
enable other runner changes. --dry-run --plan performs no runtime mutation.
After a missing acknowledgement, JSON reports committed: null, the original
operation UUID and the last acknowledged boundary. Follow its next_steps with
the same plan file; do not replan or rerun apply against a partially replaced
runtime. A verified completion followed by a lock-release error retains
committed: true. See state runner-status and state resume below.
OpenLineage apply telemetry¶
OpenLineage emission is strictly opt-in: transport environment variables do
not enable it without --emit-openlineage. The namespace options take
precedence over OPENLINEAGE_NAMESPACE,
STREAMT_OPENLINEAGE_KAFKA_NAMESPACE, and
STREAMT_OPENLINEAGE_GATEWAY_NAMESPACE, respectively, after project .env
loading. The job namespace is required and is never inferred. Explicit Kafka
and Gateway namespace values are validated for the shared CLI contract, but
apply emits no input or output datasets.
Runtime emission requires an explicit bounded File or synchronous HTTP
transport. For example, /etc/streamt/openlineage.yml can contain:
Then run:
OPENLINEAGE_CONFIG=/etc/streamt/openlineage.yml \
streamt apply --env prod --plan prod.plan.json --confirm-env prod \
--emit-openlineage \
--openlineage-job-namespace https://lineage.example/namespaces/prod
An HTTP transport uses the same syntax documented in the OpenLineage integration reference.
The run ID is exactly the UUIDv4 persisted in the durable apply intent, and
START uses that intent's exact started_at time. START follows durable
begin_operation and precedes the first provider mutation. COMPLETE follows a
confirmed ownership-state commit and durable marker clear. Runtime failure,
unknown commit, authority loss before confirmed commit, or a recovery-required
outcome produces FAIL; interruption after START produces ABORT. A verified
post-commit authority-release failure remains COMPLETE even though the CLI
returns E426_STATE_RELEASE_FAILED_AFTER_COMMIT with committed: true.
Parse, validation, confirmation, review, safety, planning, existing-recovery,
final-drift, telemetry-preflight, and --dry-run exits before the durable
operation begins emit no RunEvent. After START, delivery and transport-close
failures add only W112_OPENLINEAGE_EMIT_FAILED; they never alter apply output,
rollback, recovery truth, exit status, or the original exception.
These events describe only the finite streamt control-plane command. They contain no deployment actions, plan or state details, infrastructure datasets, credentials, or runtime lifecycle claims. COMPLETE does not mean that a submitted Flink, Gateway, Connect, or Kafka workload finished or processed data. See OpenLineage integration for the complete boundary.
Remove an exact Gateway rule¶
Gateway removal is an explicit reviewed workflow. Declare one exact
lifecycle.gateway_rule_removals tombstone using the prior compiler-level
artifact fields shown in the
YAML reference, then create an
online plan and apply that exact plan:
streamt plan --env prod --out gateway-removal.plan.json
streamt apply --env prod --plan gateway-removal.plan.json --confirm-env prod --force
The tombstone always requires a fresh online reviewed plan, even in an
unprotected environment. Direct apply, direct apply --dry-run, offline plan
files, and apply combined with --target or --select cannot authorize the
removal. An actual delete also requires --force unless the environment sets
safety.allow_destructive: true; an exact reviewed already-absent no-op does not
need that destructive override.
streamt deletes only the exact live AliasTopic and owned Interceptors bound by the tombstone, reviewed action evidence, and ownership state. Removing a model or omitting a rule does not request deletion, and streamt does not discover Gateway deletion candidates by prefix or cluster-wide search. Gateway adoption is a separate exact alias-only workflow described below.
Remove one exact Kafka Connect Connector¶
Connector removal is an explicit PostgreSQL-v2-only reviewed workflow. Declare
one exact lifecycle.connector_removals tombstone as shown in the
YAML reference,
then create a fresh online plan and apply that exact file:
streamt plan --env prod --out connector-removal.plan.json
streamt apply --env prod --plan connector-removal.plan.json \
--confirm-env prod --force
Every Connector tombstone requires this complete workflow, including in an
unprotected environment. plan --offline, direct apply, every direct or
reviewed apply --dry-run, and apply combined with --target or --select
are rejected before deployment-state or Connect access. Local state,
PostgreSQL schema version 1, and any writer that cannot prove the exact version
2 catalog/ACL and direct-primary authority are also rejected. --force cannot
bypass any of these gates; it supplies only destructive authorization when
safety.allow_destructive is not already true.
Planning resolves all tombstone, desired-artifact, ownership, backend, and
provider-locator collisions before constructing Connect. An actionable delete
requires one exact prior managed record and one complete strict Connector
observation that reconstructs its artifact checksum. Reviewed-plan format 5
binds the ordered delete to the connector name, alias-bearing endpoint digest,
prior artifact checksum, exact current fingerprint, and exact desired-absence
fingerprint. It stores no Connect endpoint or raw connector configuration.
Apply reacquires the PostgreSQL address advisory lock, freshly replans, and requires exact plan equality before recording durable version-3 action evidence. The managed mutation performs an immediate equality GET, one direct non-retrying DELETE, and bounded exact-absence confirmation. The lock excludes other streamt writers at that state address but cannot exclude a manual or other non-streamt Connect writer; that provider race remains fail-closed.
Removing a sink model, omitting a Connector artifact, selecting a different model, or merely observing absence never requests deletion. A tombstone with no prior record and an already-absent Connector is an assessed no-op: it makes no provider mutation, needs no destructive override, and does not advance the ownership serial. Absence with a prior managed record is blocking drift, while a present Connector without ownership is blocking ownership-required state.
After a DELETE starts, a 404, redirect, non-empty or non-204 response, transport
failure, changed preimage, or unproved absence is the uncertain
E428_CONNECTOR_REMOVAL_DRIFT outcome. streamt stops later actions, retains
ownership, records recovery-required state, and never retries the DELETE or
attempts an automatic rollback. Use the reviewed recovery workflow below. The
operation deletes only the exact Connector object; it does not delete Kafka
topics or records, consumer offsets, schemas, external systems, credentials,
or plugins.
Online JSON plan output also includes operation_status, containing only safe
status, operation ID/kind, stable failure code, and last safely successful
action index. Planning is read-only and does not clear an unfinished operation.
Offline output reports this status as unavailable without constructing a
state backend.
After a successful non-dry-run apply, streamt atomically records resources it
manages or has adopted in the configured deployment-state provider. External,
unowned, and ownership-blocked resources are never recorded. Local state uses
.streamt/state/<environment>.json and is appropriate for a single-user
development checkout only. PostgreSQL online plan/apply/adopt require
writer_dsn_env, an exact v2 writer/catalog/ACL, and a direct standalone
primary. They never fall back to the owner/admin credential, local state, or
empty state. Version 1 remains administrative only.
Failed and rolled-back planner results do not advance ownership state before
final commit.
An environment may set safety.require_remote_state: true to reject apply
and adopt with E421_REMOTE_STATE_REQUIRED while the effective provider is
local. This check runs after reviewed/offline plan-file gates but before
confirmation, compilation, state access, or runtime deployer construction.
--force cannot bypass it. Read-only plan and state status are not blocked.
For local apply/adopt, .streamt/state/<environment>.control.json records a
versioned durable intent before mutation and safe ordered action progress.
PostgreSQL records the same protocol atomically in its v2 catalog. Both
in_progress and recovery_required block later apply/adopt commands
indefinitely with E419_STATE_RECOVERY_REQUIRED; elapsed time is not proof that
a runtime call failed. Do not delete or edit the sidecar, and do not roll back
streamt versions while a marker exists. Use the explicit two-command reviewed
recovery workflow below for an exactly representable outcome; unsupported or
ambiguous targets remain blocked.
This sidecar complements a same-host file lock and does not provide cross-host
or distributed exclusion.
Protected Environments
Protected environments reject direct apply with
E418_REVIEWED_PLAN_REQUIRED. First save and review an online plan with
streamt plan --env ENV --out ENV.plan.json, then apply it with
streamt apply --env ENV --plan ENV.plan.json. Confirmation is still
required: type the environment name interactively, use --confirm, or use
--confirm-env ENV (which also verifies the name). --confirm, --force,
and --dry-run do not bypass the reviewed-plan requirement.
An unprotected environment can opt into the same shared-workflow gate with
safety.require_reviewed_plan: true. streamt never infers this policy from
names such as staging, shared, or prod.
Unsupported migrations are not forceable
apply rejects Kafka partition reductions, incompatible Schema Registry
updates, and every existing Flink job update with
E417_SAFETY_BLOCKED. This happens before backend mutation for both direct
apply and apply --plan; --force does not bypass it. Flink creates and
no-op jobs remain allowed.
LLM/Agent Usage
Use --confirm-env ENV instead of --confirm for programmatic deployments. It provides an extra safety check by verifying the environment name matches, preventing accidental deployments to the wrong environment.
Output:
Applying changes...
Topics:
+ orders.clean.v1 .............. created
~ orders.metrics.v1 ............ updated
Flink Jobs:
+ order_metrics ................ deployed
Summary: 2 created, 1 updated, 0 unchanged
Idempotency & Existing Resources
apply is idempotent — running it twice with the same project produces the same result:
- Topic already exists, same config → skipped (
unchanged) - Topic already exists, different config → updated (partitions increased, config altered)
- Topic doesn't exist → created
- Partitions decreased → plan records
kafka_partition_reduction; apply is refused before mutation (Kafka does not support partition reduction)
A controlled apply stops before starting any later action after one runtime
call fails. It may attempt rollback of earlier created resources while the
lock remains healthy, but it preserves a recovery marker because the failed
call's result can be unknown. Do not automatically rerun apply; inspect the
online plan's operation_status, retain the sidecar evidence, and use the
explicit reviewed recovery workflow only after establishing the exact live
outcome.
Flink Job Lifecycle
Existing Flink job updates are currently blocked because the available cancel-and-resubmit path is not savepoint-safe. New jobs may still be submitted and unchanged jobs are left alone. See Flink Options Reference — Job Lifecycle on Apply for the underlying lifecycle boundary.
adopt¶
Explicitly claim one existing Kafka topic, Schema Registry subject, Kafka Connect connector, or alias-only Conduktor Gateway rule for lifecycle management. Adoption changes only the configured ownership state; it never mutates the provider resource.
streamt adopt \
--project-dir . \
--env prod \
--kind topic \
--name orders \
--confirm-resource streamt://payments/prod/topic/orders \
--confirm-env prod
For a compiled schema subject, use the same logical owner and confirmation
protocol with --kind schema:
streamt adopt \
--project-dir . \
--env prod \
--kind schema \
--name orders \
--confirm-resource streamt://payments/prod/schema/orders \
--confirm-env prod
For a compiled Kafka Connect connector bound to the configured default Connect
cluster, use --kind connector:
streamt adopt \
--project-dir . \
--env prod \
--kind connector \
--name orders_sink \
--confirm-resource streamt://payments/prod/connector/orders_sink \
--confirm-env prod
For one compiled Gateway rule with no desired Interceptors, use
--kind gateway_rule and the model's logical ownership name:
streamt adopt \
--project-dir . \
--env prod \
--kind gateway_rule \
--name orders_view \
--confirm-resource streamt://payments/prod/gateway_rule/orders_view \
--confirm-env prod
--name is the stable logical declaration name, not a physical topic, subject,
connector, Gateway rule, or AliasTopic name. It must resolve to exactly one compiled artifact whose
declaration explicitly sets ownership.mode: adopted. Topic adoption displays
partitions, replication factor, dynamic configuration, and pending differences.
Schema adoption displays only the subject, type, version, schema ID,
compatibility, content checksums, and pending differences; schema bodies are
never printed. Connector adoption accepts an omitted cluster or an explicit
cluster equal to the effective default; an explicit non-default cluster fails
closed. The claim binds the default alias, versioned normalized-endpoint
fingerprint, and exact connector name. Review output contains checksums for the
whole configuration plus sanitized changed-key categories and directions,
never raw connector configuration or per-value fingerprints. Gateway adoption
requires the exact AliasTopic to exist at the bound endpoint and effective
vCluster with canonical physical cluster main. Both the desired rule and the
selected live aggregate must have zero rule-owned Interceptors. Its review
shows only the alias, binding fingerprint, mapping and aggregate fingerprints,
artifact checksum, and pending-change categories; physical topic names,
credentials, endpoint, and Interceptor configuration are omitted.
Interactive use requires typing an exact token containing both the full
resource ID and environment. Non-interactive use requires both exact
--confirm-resource and --confirm-env values; there is no generic yes/force
flag. A successful adoption atomically advances only the configured
environment-scoped ownership state. Repeating an identical adoption is a no-op
and does not advance its serial. Connector idempotency returns after one strict
resource GET; Gateway idempotency returns after one complete two-list
observation. Neither path asks for confirmation or writes state.
The accepted --kind values are topic, schema, connector, and
gateway_rule. A new
Connector adoption performs exactly one percent-encoded
GET /connectors/<connector-name> before confirmation and the same strict read
again after confirmation. It does not call Connect list, status, task, create,
update, delete, pause, resume, or restart APIs. A legacy unbound
backend: kafka-connect ownership record fails closed; it is never silently
rebound to the selected endpoint. A new Gateway adoption makes exactly two
ordered collection GETs for review and repeats them after confirmation. The
AliasTopic and Interceptor reads are sequential rather than provider-atomic,
so external writers remain a TOCTOU boundary; any changed or third-state
aggregate fails closed. Gateway POST, PUT, PATCH, and DELETE endpoints are not
used. Full Gateway Interceptor adoption and Flink adoption remain unsupported
under the gates in the extended resource adoption
plan.
Adoption uses configured state
Local adoption state is safe only for a single-user checkout. PostgreSQL v2
adoption for every supported kind, including Connector and Gateway, uses the same exact
writer and distributed address lock as apply, and requires
writer_dsn_env; owner/admin and local fallback are forbidden.
Run streamt plan --out ... after adoption and review that plan before
applying any pending differences.
test¶
Run data quality tests.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--model MODEL |
Test specific model only |
--type TYPE |
Filter by type: schema, sample, continuous |
--deploy |
Reserved deployment path; currently warns and runs locally without OpenLineage emission |
--coverage |
Show test coverage report (which models have tests) |
--emit-openlineage |
Emit one validated finite command-run lifecycle through an explicit transport |
--openlineage-job-namespace NAMESPACE |
Job namespace; falls back to OPENLINEAGE_NAMESPACE |
--openlineage-kafka-namespace KAFKA-URI |
Sample-input namespace; falls back to STREAMT_OPENLINEAGE_KAFKA_NAMESPACE or safe Kafka bootstrap derivation |
--openlineage-gateway-namespace KAFKA-URI |
Validated shared Gateway namespace option; test inputs still use Kafka because the runner consumes runtime.kafka |
Examples:
# Run all tests
streamt test
# Run tests against specific environment
streamt test --env staging
# Run schema tests only
streamt test --type schema
# Test specific model
streamt test --model orders_clean
# Emit a finite command lifecycle using an explicitly configured transport
streamt test --emit-openlineage \
--openlineage-job-namespace https://lineage.example/namespaces/prod
# Reserved deployment path; currently warns and runs locally
streamt test --deploy
OpenLineage emission is strictly opt-in and requires File or HTTP transport
configuration. One non-empty invocation uses a new UUIDv4 and attempts START
plus exactly one COMPLETE, FAIL, or ABORT event. Only selected sample-test
topics appear as Kafka inputs; schema and continuous tests contribute no
dataset input. Coverage, an empty selection, and --deploy emit no run.
Preflight construction/configuration failures use
E506_OPENLINEAGE_INVALID before the runner starts. Delivery or close failures
use W112_OPENLINEAGE_EMIT_FAILED without changing the test output or exit
status. This lifecycle describes the finite streamt invocation, not completion
of a deployed streaming job. See OpenLineage integration.
Output:
Running tests...
Schema Tests:
✓ orders_schema_validation (3 assertions)
Sample Tests:
✓ orders_data_quality (1000 messages)
Continuous Tests:
○ orders_monitoring (deployed)
Results: 2 passed, 0 failed, 1 deployed
lineage¶
Display data lineage and dependencies.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--model MODEL |
Focus on specific model |
--upstream |
Show only upstream dependencies |
--downstream |
Show only downstream dependencies |
--columns |
Show column-level lineage (requires --model) |
--format FORMAT |
Output format: ascii, json, mermaid |
Examples:
# Full lineage (ASCII)
streamt lineage
# Full lineage for specific environment
streamt lineage --env prod
# Focus on one model
streamt lineage --model order_metrics
# Upstream only
streamt lineage --model order_metrics --upstream
# Downstream only
streamt lineage --model orders_clean --downstream
# JSON output
streamt lineage --format json
# Mermaid diagram
streamt lineage --format mermaid
Output (ASCII):
orders_raw (source)
└── orders_clean (topic)
├── order_metrics (flink)
│ └── ops_dashboard (exposure)
└── billing_service (exposure)
state init¶
Explicitly initialize a new PostgreSQL version-1 store or register one empty canonical address in an exact compatible version-1 or version-2 store. This is an administrative command, not ordinary deployment-state authority.
| Option | Description |
|---|---|
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Target environment (reads STREAMT_ENV if omitted) |
--confirm-project NAME |
Exact parsed project name |
--confirm-env ENV |
Exact effective environment, including default |
--confirm-address URI |
Exact streamt-state://<namespace>/<project>/<environment> address |
All three confirmation values are required and must match exactly. A mismatch fails before the initializer is constructed or a database connection is opened. For example:
streamt state init -p . -e prod \
--confirm-project payments \
--confirm-env prod \
--confirm-address streamt-state://platform/payments/prod
When the configured schema is absent, init creates the frozen seven-table version-1 catalog, one immutable random store ID, the requested address and its collision-checked advisory-lock mapping, and a clear operation-control row. When the schema already exists but is empty, the initializer identity must own it. An exact compatible version-1 or version-2 store can register a previously unregistered empty address. Repeating init for the same compatible, empty address is a no-op. Init never changes an existing store's schema version.
The structured outcome is initialized, address_registered, or
already_initialized. Every successful result reports the safe store ID,
schema version, canonical address, absent ownership state, clear operation
status, and an ordinary_state_authority capability label. A newly initialized
v1 store reports disabled; address registration in an exact v2 store reports
supported_for_v2_writer. Init does not resolve or probe the writer credential.
It never imports local state, repairs a partial catalog, or migrates a populated
store.
Initialization is serialized by a bounded schema-scoped session advisory lock.
After acquiring it, streamt begins a fresh serializable transaction, sets the
transaction-local search_path to pg_catalog, creates and precommit-validates
the complete result, commits once, and verifies the result through a fresh
read-only connection. A failure before commit rolls the transaction back. An
ambiguous commit is never retried automatically; run state status or repeat
the identical confirmed init to resolve the durable result.
For a newly created schema, init revokes all schema access from PUBLIC; it
revokes all table access from PUBLIC for every table it creates. It creates no
roles and grants no privileges. The exact catalog requires one common owner for
the schema and tables. A named status role may have only non-grantable schema
USAGE and non-grantable table or column SELECT; every PUBLIC, mutating, or
grantable non-owner ACL is rejected. Partial catalogs, owner/ACL drift, extra
objects, populated or active target addresses, incompatible versions, and
advisory-lock-key collisions fail closed without repair.
Incompatible state uses E411_STATE_INVALID. Missing dependencies or
credentials and connection failures use the secret-neutral
E420_STATE_BACKEND_UNAVAILABLE; no local fallback occurs.
state migrate-postgres-v2¶
Explicitly migrate one exact PostgreSQL deployment-state catalog from schema version 1 to schema version 2 and bind its separately provisioned, least-privilege writer role. This is an owner-only administrative operation; it prepares the v2 catalog used by ordinary plan/apply/adopt and recovery, but does not itself resolve or test the writer DSN.
| Option | Description |
|---|---|
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Target environment (reads STREAMT_ENV if omitted) |
--confirm-store-id UUID |
Exact canonical store UUID reported by state status |
--confirm-writer-role ROLE |
Exact role value resolved through postgres.writer_role_env |
Both confirmations are required. The store ID must be canonical UUID text. The
role must be nonempty, NUL-free, UTF-8 encodable, and no longer than PostgreSQL's
63-byte identifier limit. Missing or malformed confirmations fail before
project parsing or provider construction. The supplied role must exactly match
the value obtained from the configured postgres.writer_role_env; the source
store must exactly match the supplied ID. A mismatch fails before mutation, and
no failure echoes a role, DSN, login, endpoint, or schema name.
The owner connection is resolved through postgres.dsn_env; the external role
name is resolved separately through postgres.writer_role_env. Both named
environment values are required, with no implicit credential or role fallback.
The command requires a direct standalone primary, takes the schema lock and
all registered-address locks under one bounded deadline, validates the complete
v1 catalog and histories, migrates metadata and ACLs atomically, and verifies
the postimage through a fresh connection. It never creates or alters a role.
streamt state migrate-postgres-v2 -p . -e prod \
--confirm-store-id 8d04f3f7-0000-4000-8000-000000000000 \
--confirm-writer-role streamt_state_writer
A successful human result reports the outcome, safe store ID, schema version
2, Catalog mutation readiness: catalog_ready, and Ordinary state
authority: supported_for_v2_writer. Structured result data contains only:
{
"backend": "postgres",
"outcome": "migrated",
"store_id": "8d04f3f7-0000-4000-8000-000000000000",
"schema_version": 2,
"ordinary_state_authority": "supported_for_v2_writer",
"mutation_status": "catalog_ready"
}
outcome is migrated or, for an exact same-store/same-role retry,
already_migrated. supported_for_v2_writer is catalog capability, not proof
that writer_dsn_env is present, authenticates as the stored role, or reaches a
supported endpoint. Each ordinary command reproves those conditions.
Migration-specific failures are:
| Code | Operator meaning |
|---|---|
E411_STATE_INVALID |
A confirmation, role, source catalog, control/history sequence, or resulting ACL is incompatible. No repair or rebind is attempted. |
E420_STATE_BACKEND_UNAVAILABLE |
Configuration, optional dependency, named environment value, endpoint, credential, or connection is unavailable. |
E422_STATE_LOCK_TIMEOUT |
The bounded lock deadline expired. Resolve contention, recheck clear control, then retry the identical confirmed command. |
E425_STATE_UNKNOWN_OUTCOME |
Commit could not be classified. Do not blindly replay; preserve evidence and inspect state status and the durable catalog. |
E426_STATE_RELEASE_FAILED_AFTER_COMMIT |
The v2 postimage was verified but lock release was not. Structured data contains committed: true; treat the migration as committed and do not replay it as an uncommitted write. |
There is no in-place downgrade, repair, or writer-rebind command. See the PostgreSQL deployment-state migration guide for backup and preflight steps, the exact writer ACL, ambiguity handling, and the supported topology boundary.
state lock-status¶
Probe the instantaneous availability of the configured PostgreSQL address lock. This separate diagnostic command does not acquire a reservation for later work or verify ordinary PostgreSQL writer authority.
| Option | Description |
|---|---|
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Target environment (reads STREAMT_ENV if omitted) |
The command validates the complete version-1 or version-2 catalog and requires
a direct standalone primary endpoint. It runs in an explicit
repeatable-read, read-only transaction. For an unregistered address it returns
unregistered without invoking an advisory-lock function. For a registered
address it calls
pg_try_advisory_xact_lock(bigint) once and returns available or busy.
available, busy, and unregistered are all successful command outcomes.
Before returning any result, streamt requires the transaction rollback to
succeed. That rollback releases a successful transaction-scoped probe lock, so
the command neither reserves nor leaks it. The observation is instantaneous
and racy: another process may acquire the lock immediately afterward, and the
result cannot authorize mutation. Full catalog validation reads the
operation-control rows, but the command does not report, clear, or interpret
durable operation control as mutation safety; use streamt state status to
view it.
Structured output contains only:
{
"backend": "postgres",
"store_id": "8d04f3f7-...",
"address": "streamt-state://platform/payments/prod",
"lock_status": "available",
"reservation": "none",
"ordinary_state_authority": "not_verified"
}
PostgreSQL advisory locks are physical-session state. Use a direct connection to one standalone primary. Every pooler/proxy and every HA or failover topology is unsupported; streamt cannot reliably detect that a DSN bypasses all poolers. The operation lock retains one connection for its complete lifetime. The probe creates no roles, grants, address rows, or operation markers.
An invalid catalog uses E411_STATE_INVALID. A replica, missing dependency or
credential, connection failure, or unsuccessful rollback uses secret-neutral
E420_STATE_BACKEND_UNAVAILABLE. No local fallback occurs.
state status¶
Inspect safe configured ownership-state and operation-control metadata without acquiring a mutation lock or connecting to runtime infrastructure.
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
For the working local provider, structured output contains its kind, immutable store ID,
canonical state address, ownership presence/serial/checksum, and the same safe
operation_status fields exposed by online plan. Provider revisions, resource
contents, credentials, and raw provider errors are not emitted. A missing state
file is reported as state_status: absent with serial 0; the command does not
create .streamt/, ownership state, a control sidecar, or lock files.
Both in_progress and recovery_required are shown without modification. The
text output directs operators to retain the sidecar evidence because those
markers still block apply/adopt indefinitely. state status cannot clear or
recover them.
For backend: postgres, the optional postgres package extra enables a
separate administrative reader. It verifies the exact version-1 or version-2
store catalog, then reports safe store, address, ownership, and
operation-control fields from
one bounded, repeatable-read, read-only snapshot. It never returns the DSN,
endpoint, SQL, raw driver errors, or ownership payload. An absent schema is
uninitialized; an initialized store can report an unregistered, absent, or
present address. Missing dependencies or credentials, incompatible stores, and
connection failures use sanitized state errors and never fall back to local.
Catalog verification also requires common schema/table ownership and the exact
version-specific ACL contract. For v2, status reports mutation_status:
catalog_ready and ordinary_state_authority: supported_for_v2_writer; v1
reports disabled. This is a catalog capability label only: status uses
dsn_env and does not resolve, authenticate, or test writer_dsn_env. The
read-only transaction sets
search_path to pg_catalog and uses schema-qualified state objects.
state runner-status¶
Inspect one reviewed Kafka Streams replacement under the deployment-state lock.
Unlike state status, this command verifies the current full project, original
plan, exact operation journal or completion receipt, and live runner evidence.
It makes no runtime, ownership or audit writes. Acquiring the lock may create a
local lock file; read-only does not mean that the filesystem is never touched.
streamt -o json state runner-status -p . -e prod \
--plan filter-change.json --operation-id '<original UUID>'
| Option | Description |
|---|---|
--plan PATH |
Required original reviewed format-6 plan |
--operation-id UUID |
Required canonical UUID returned by the original apply |
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Original environment; omit for a single-environment project |
JSON contains status, control_status, lifecycle_phase, committed,
resumable, next_step, reason and next_action. A pending operation may be
safe to resume or blocked. An already-clear result is completed only when its
exact receipt, current ownership and ready candidate agree. Clear control alone
does not prove success. This is an exact-current-operation diagnostic, not a
general historical query: subsequent ownership or project changes can prevent
verification of an older receipt. Observation does not authorize mutations.
state resume¶
Continue one interrupted predicate replacement using its original reviewed plan and operation UUID. This command can mutate the runtime; it is distinct from read-only diagnosis and generic reviewed recovery.
streamt -o json state resume -p . -e prod --confirm-env prod \
--plan filter-change.json --operation-id '<original UUID>' --timeout 60
The options of state runner-status also apply here. --confirm-env ENV is
required when the environment's apply policy demands confirmation; its value
must match exactly. --timeout SECONDS bounds each replacement wait, greater
than 0 and at most 600 (default 60). It is not a total command deadline.
Remote-state requirements still apply. Neither command silently falls back to
local state. Omit --env and --confirm-env for the single-environment starter.
Resume preserves the original intent and retained incident history. It validates
the current project and locked state before observing or executing the next
proven step. A candidate created before a lost response is reused only when its
exact generation and mounted inputs match. Resume never initializes offsets,
recreates a missing volume, force-kills a process, or replans a partial topology.
Completed results are verified without another deployment, ownership increment
or audit append; those retries return read_only: true.
An error after a missing acknowledgement reports an unknown outcome until a fresh command verifies it. An old-removed/new-absent topology is incomplete; read-only diagnosis cannot clear it. Changed identities, unavailable progress, corrupt history or mismatched SQL block continuation. See the interruption runbook.
state recovery-plan¶
Create integrity-checked evidence for one exact unfinished operation without clearing its marker or changing ownership state.
| Option | Description |
|---|---|
--resolution OUTCOME |
Required exact outcome: observed, rolled_back, or abandoned_before_mutation |
--out FILE |
Required new recovery-evidence file; existing paths and symlinks are refused |
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Target environment (reads STREAMT_ENV if omitted) |
The command acquires the configured state lock and rereads the complete state,
control marker, durable progress, and ordered action intent. observed and
rolled_back also recompile the current project and freshly observe every
target. abandoned_before_mutation is accepted only when durable progress is
empty and does not construct runtime deployers. A target that cannot be
represented exactly fails closed. Present Flink jobs remain unsupported.
A version-2 Gateway mutation intent contains secret-neutral evidence for the exact current and desired managed aggregate: its bound endpoint/vCluster identity, provider rule name, alias, aggregate fingerprint, and owned-interceptor count. Recovery compares one fresh full alias-plus-owned-interceptor aggregate with those two surfaces. A current match is classified as prior and can prove a rolled-back create, update, or delete; a desired match is classified as the candidate and can prove a completed create, update, or delete. Any partial or intermediate aggregate fails closed. Gateway performs the shared observation as a bounded pair of sequential AliasTopic and Interceptor list GETs. The pair is read-only but not provider-atomic, so freeze concurrent Gateway changes while creating and first executing the plan.
Legacy control-version-1 Gateway actions have no exact aggregate evidence and
fail before provider access for live observed or rolled_back recovery. They
may use abandoned_before_mutation only when durable progress is empty.
A control-version-3 Connector delete action carries secret-neutral evidence for one exact current-present and desired-absent Connector surface: its alias-bearing endpoint digest, exact connector name, prior artifact checksum, and whole-observation fingerprints. Recovery validates the action, its exact prior managed ownership record, current runtime binding, and collisions before Connect access. It then makes one strict resource GET for each normalized endpoint/name locator; current desired Connectors, retained removal tombstones, and recovery actions sharing that locator reuse the same observation.
The lifecycle tombstone is not required during recovery: the durable action is
the deletion authority. Exact absence is the completed candidate accepted by
observed; exact presence with the durable current fingerprint and a
reconstructible matching prior checksum is the prior result accepted by
observed or rolled_back. rolled_back never accepts absence. Any other
present value, malformed or partial document, unavailable observation, wrong
runtime binding, or competing desired/removal claim fails closed and retains
the blocker. Control versions 1 and 2 cannot represent a Connector delete and
fail before Connect access for live recovery; only a progress-empty
abandoned_before_mutation resolution remains provider-free.
The evidence file is created atomically as a regular file with mode 0600 and
is never overwritten. It binds the configured store/address, blocked and new
recovery operation IDs, prior state and control preimage, current project
fingerprints and normalized target evidence when required, selected resolution,
candidate ownership state when applicable, and an evidence_checksum. It
contains no DSN, provider revision token, or raw provider error. The checksum
detects modification; it is not an approval signature.
streamt state recovery-plan -p . -e prod \
--resolution observed \
--out /secure/recovery/payments-prod-observed.json
Successful structured result data contains:
{
"plan_file": "/secure/recovery/payments-prod-observed.json",
"blocked_operation_id": "00000000-0000-4000-8000-000000000000",
"recovery_operation_id": "00000000-0000-4000-8000-000000000001",
"resolution": "observed",
"evidence_checksum": "sha256:..."
}
Creating evidence is read-only with respect to deployment state. Review its exact operation, actions, live classifications, candidate state, project fingerprints, and checksum before execution. Do not edit the file; after any drift, generate and review a new file at a new path.
state recover¶
Execute one exact reviewed recovery after revalidating its state, project, and live evidence under the configured lock.
| Option | Description |
|---|---|
--plan FILE |
Required reviewed recovery-evidence file |
--confirm-operation-id UUID |
Exact blocked operation UUID from that file |
--confirm-resolution OUTCOME |
Exact observed, rolled_back, or abandoned_before_mutation value from that file |
--confirm-evidence-checksum CHECKSUM |
Exact lowercase sha256: checksum from that file |
--project-dir PATH, -p PATH |
Project directory |
--env ENV, -e ENV |
Target environment (reads STREAMT_ENV if omitted) |
All three confirmations are required. Malformed confirmations fail before the plan is read or a provider is constructed. The command then strictly validates the plan and checksum, configured store/address, current state/control preimage, and, when required, project fingerprints and fresh live evidence. Any mismatch stops without partially accepting a plan. If the exact reviewed state is already present and operation control is already clear, an identical completed retry skips project and provider re-observation; the state backend verifies the recovery operation and result against its durable recovery history.
streamt state recover -p . -e prod \
--plan /secure/recovery/payments-prod-observed.json \
--confirm-operation-id 00000000-0000-4000-8000-000000000000 \
--confirm-resolution observed \
--confirm-evidence-checksum sha256:0000000000000000000000000000000000000000000000000000000000000000
Successful structured result data contains:
{
"store": {
"backend": "postgres",
"store_id": "8d04f3f7-0000-4000-8000-000000000000"
},
"address": "streamt-state://platform/payments/prod",
"state_serial": 13,
"state_checksum": "sha256:...",
"control_status": "clear",
"state_changed": true,
"blocked_operation_id": "00000000-0000-4000-8000-000000000000",
"recovery_operation_id": "00000000-0000-4000-8000-000000000001",
"resolution": "observed",
"evidence_checksum": "sha256:..."
}
observed may preserve an exact reviewed mix of targets at their prior and
candidate states. rolled_back requires every target to match prior state.
abandoned_before_mutation retains prior state and requires no started action.
Recovery never repeats a runtime mutation, lowers the state serial, edits
history in place, force-unlocks, or runs automatically.
For Gateway specifically, only a desired-absent match for an exact durable
delete action may remove its ownership record. Manifest absence never creates
or implies that action. Ordinary planning currently has no broad discovery of
removed Gateway rules, so deleting a rule declaration does not itself schedule
a provider delete. Alias-only adopt recovery requires the exact reviewed
current aggregate; observed records the adopted ownership candidate and
rolled_back retains the absent prior claim.
For Connector deletion specifically, only exact absence for a durable
version-3 delete action can remove its matching managed ownership record.
Manifest or model absence is inert, recovery never retries DELETE, and no
nearby, legacy, adopted, differently bound, or checksum-mismatched record is
accepted. A present exact prior surface can only retain that record. Local
state cannot authorize or resolve a Connector deletion; use the exact
PostgreSQL-v2 writer and advisory-lock boundary that created the blocked
operation.
Local recovery uses the local state authority and a crash-safe history
sequence. PostgreSQL recovery requires an exact v2 catalog and resolves only
the separately configured postgres.writer_dsn_env; it never falls back to
the administrative postgres.dsn_env. It proves the stored writer identity,
exact catalog/ACL, and a direct standalone primary, then commits state,
history, and control atomically. Ordinary plan/apply/adopt use the same writer
authority. All poolers and HA/failover topologies are unsupported.
Recovery failures use these stable codes:
| Code | Operator meaning |
|---|---|
E408_PLAN_FILE_INVALID |
The plan or a confirmation is malformed, modified, incomplete, unsupported, unsafe, or mismatched. Do not repair the plan in place. |
E409_PLAN_STALE |
Current project inputs or fresh live observations no longer match the reviewed evidence. Create and review a new plan. |
E411_STATE_INVALID |
State, control, history, catalog, or address is incompatible. Do not hand-edit state metadata. |
E419_STATE_RECOVERY_REQUIRED |
Recovery planning found no active unfinished operation, or the selected abandonment outcome is forbidden after durable progress. Inspect state status and preserve the marker. |
E420_STATE_BACKEND_UNAVAILABLE |
A dependency, named credential, endpoint, runtime provider, or exact PostgreSQL writer authority is unavailable; no fallback occurs. |
E422_STATE_LOCK_TIMEOUT |
The bounded lock deadline expired. Resolve legitimate contention and retry; never force-unlock. |
E423_STATE_LOCK_LOST |
State authority was lost. Start no mutation and inspect state status. |
E424_STATE_CONFLICT |
State or operation control changed after observation. Create fresh reviewed evidence for the remaining blocker. |
E425_STATE_UNKNOWN_OUTCOME |
Recovery may have committed. Inspect status and use only the identical file and confirmations for idempotent verification. |
E426_STATE_RELEASE_FAILED_AFTER_COMMIT |
The recovery commit was verified but authority release failed. Structured data reports committed: true; treat the recovery as committed. |
See the deployment-state recovery runbook for resolution criteria, independent review, backups, supported target boundaries, failure handling, and PostgreSQL topology requirements.
status¶
Check deployment status of selected managed resources. External resources are
declared but not inspected unless --include-external is supplied.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--lag |
Show consumer lag and message counts for topics |
--consumer-groups |
Show per-consumer-group lag |
--include-external |
Explicitly inspect external sources and compiled artifacts |
--health |
Exit 1 for missing, drifted, unhealthy, or unavailable observations in the selected scope |
--format FORMAT |
Output format: text (default) or json |
--filter PATTERN |
Filter resources by name pattern (glob-style) |
Examples:
# Managed status; external declarations are not inspected
streamt status
# Explicit live inspection of external dependencies too
streamt status --include-external
# Status for specific environment
streamt status --env prod
# With consumer lag info
streamt status --lag
# JSON output (for scripting)
streamt status --format json
# Filter by name pattern
streamt status --filter "payments*"
# Combine options
streamt status --lag --filter "orders*"
# Health check (exit 1 if anything unhealthy)
streamt status --health
Filtering happens before provider connections. JSON data.observation_scope is
managed or managed_and_external. Unobserved external sources have exists: null
and observation: not_requested; compiled external artifacts are listed under
external_resources rather than assigned a runtime status. A successful
managed-only --health does not certify that external dependencies are available.
Output (text):
Topics:
OK orders.clean.v1 (partitions: 12, rf: 3) ~15420 msgs
OK orders.metrics.v1 (partitions: 6, rf: 3) ~8210 msgs
Flink Jobs:
RUNNING order_metrics
Connectors:
RUNNING orders_snowflake
Summary: Topics: 2 OK, 0 missing | Jobs: 1 running, 0 other
Output (JSON):
{
"project": "payments-pipeline",
"topics": [
{
"name": "orders.clean.v1",
"exists": true,
"partitions": 12,
"replication_factor": 3,
"message_count": 15420
}
],
"flink_jobs": [
{
"name": "order_metrics",
"exists": true,
"job_id": "abc123",
"status": "RUNNING"
}
],
"connectors": [],
"schemas": []
}
list¶
List project resources by type.
Arguments:
| Argument | Values |
|---|---|
RESOURCE_TYPE |
sources, models, tests, exposures |
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--select SELECTOR |
Filter by tag or selector expression |
--sort-by FIELD |
Sort results by field: name (default), type, upstream |
Examples:
# List all sources
streamt list sources
# List models with JSON output
streamt -o json list models
# List tests for a specific environment
streamt list tests --env prod
JSON Output:
{
"status": "ok",
"command": "list",
"data": {
"resource_type": "models",
"count": 3,
"items": [
{"name": "orders_clean", "materialized": "virtual_topic", "upstream": ["orders_raw"]},
{"name": "order_metrics", "materialized": "flink", "upstream": ["orders_clean"]}
]
}
}
show¶
Show detailed information about a single resource.
Arguments:
| Argument | Values |
|---|---|
RESOURCE_TYPE |
source, model, test, exposure |
NAME |
Resource name |
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--diff |
Show diff between declared and deployed state |
Examples:
# Show source details
streamt show source orders_raw
# Show model with JSON output (for agents)
streamt -o json show model order_metrics
# Show test details
streamt show test orders_quality
JSON Output (model):
{
"status": "ok",
"command": "show",
"data": {
"resource_type": "model",
"name": "order_metrics",
"materialized": "flink",
"upstream": ["orders_clean"],
"downstream": ["ops_dashboard"],
"sql": "SELECT ...",
"flink": {"parallelism": 4, "state_ttl_ms": 3600000},
"topic": {"partitions": 12}
}
}
observe¶
Show live runtime health: consumer lag, Flink job status, backpressure. Connects to Kafka (for consumer group lag) and Flink (for job metrics). Does not modify any infrastructure.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--model MODEL |
Observe a single model by name |
Examples:
# Full runtime health
streamt observe
# Observe specific model
streamt observe --model payments_clean
# JSON output
streamt -o json observe
docs¶
Generate project documentation.
docs generate¶
Generate HTML documentation site.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--output PATH |
Output directory (default: site/) |
Examples:
# Generate docs
streamt docs generate
# Generate docs for specific environment
streamt docs generate --env prod
# Custom output
streamt docs generate --output ./public
docs asyncapi¶
Generate a deterministic, offline-validated AsyncAPI 3.1 JSON document for declared Kafka source and model channels.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
Examples:
# Generate an AsyncAPI 3.1 document
streamt docs asyncapi
# Save to file
streamt docs asyncapi > asyncapi.json
# Return the document in the structured CLI envelope at data.document
streamt --output json docs asyncapi
The export includes stable channel, message, schema, and operation identifiers, payload schemas from declared columns/contracts, and only the Kafka binding fields supported by explicit model topic metadata. It does not invent broker servers, credentials, serialization settings, or payload schemas for resources without declared columns. Unsupported or malformed Flink types and identifier collisions fail closed. See AsyncAPI export for the exact validation and representation boundary.
docs odcs¶
Generate one deterministic, offline-validated Open Data Contract Standard (ODCS) 3.1.0 document for one parsed streamt project.
Options:
| Option | Description |
|---|---|
--contract-id ID |
Explicit contract identity; semantically required and copied exactly |
--status STATUS |
Explicit lifecycle status; semantically required and copied exactly |
--contract-version VERSION |
Contract version; defaults to the exact project.version |
--format yaml\|json |
Raw-document serialization (default: yaml) |
--output-file PATH |
Atomically replace this file instead of writing the raw document to stdout |
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
Examples:
# YAML is the default raw format
streamt docs odcs \
--contract-id urn:acme:data-contract:payments \
--status active > payments.odcs.yaml
# Write validated JSON through an atomic file replacement
streamt docs odcs \
--contract-id urn:acme:data-contract:payments \
--status active \
--contract-version 2.3.0 \
--format json \
--output-file payments.odcs.json
# Keep the document as an object in the standard streamt JSON envelope
streamt --output json docs odcs \
--contract-id urn:acme:data-contract:payments \
--status active \
--format yaml
Without --output-file, text mode reserves stdout for exactly one raw YAML or
JSON document. Parser notices and incomplete-schema warnings go to stderr. The
global --output json option instead returns one normal streamt envelope with
the document under data.document; local --format remains serialization
metadata and does not replace the envelope. With --output-file, serialization
and validation complete before streamt stages and atomically replaces the
explicit target.
Contract ID and status never receive defaults. A version must come from
--contract-version or non-blank project.version. Invalid contract metadata,
mapping, validation, serialization, or output uses E505_ODCS_INVALID.
The document contains every declared source and model once. It maps only declared schema facts and does not export data quality, SLAs, teams, roles, servers, runtime endpoints, credentials, SQL, catalog publication state, or a separate contract per model. See ODCS export for the exact mapping, validation, and omission boundary.
docs backstage¶
Export deterministic, offline-validated Backstage Software Catalog core entities as canonical multi-document YAML.
Options:
| Option | Description |
|---|---|
--catalog-id ID |
Stable catalog identity; semantically required |
--catalog-namespace NAMESPACE |
Explicit lowercase namespace for generated entities; semantically required |
--default-owner-ref REF |
Full Group or User reference; semantically required |
--lifecycle VALUE |
Exact Component lifecycle; semantically required |
--owner-map PATH |
Strict version-1 JSON mapping from declared streamt owner labels to full refs |
--kafka-cluster-ref REF |
Full Resource ref; required when Kafka Resources are emitted |
--gateway-cluster-ref REF |
Full Resource ref; required when Gateway virtual-topic Resources are emitted |
--domain-ref REF |
Optional full Domain ref for the generated System |
--output-file PATH |
Atomically replace this file with canonical YAML |
--project-dir PATH |
Project directory |
--env ENV |
Target environment |
streamt docs backstage \
--catalog-id payments-prod \
--catalog-namespace payments \
--default-owner-ref group:platform/payments \
--lifecycle production \
--kafka-cluster-ref resource:platform/kafka-prod \
--output-file catalog-info.yaml
Text mode writes raw YAML to stdout when no file is selected; warnings remain
on stderr. Global --output json returns the validated entities, exact kind
counts, release metadata, and output path in the standard envelope. Sink
destinations and exposures are intentionally omitted with
W113_BACKSTAGE_SINK_OUTPUT_OMITTED and
W114_BACKSTAGE_EXPOSURE_OMITTED. Invalid catalog inputs or mapping use
E507_BACKSTAGE_INVALID.
The command performs one dry-run compile and does not read deployment state, contact providers, or publish to Backstage, DataHub, or Conduktor Console. See Backstage Software Catalog export for the exact entity, ownership, output, and sensitivity boundaries.
docs datahub¶
Export deterministic, offline-validated DataHub v1.7.0 simplified Metadata Change Proposals as canonical JSON.
Options:
| Option | Description |
|---|---|
--catalog-id ID |
Exact caller-owned DataFlow ID; semantically required |
--fabric FABRIC |
Exact uppercase DataHub v1.7.0 FabricType; semantically required |
--kafka-platform-instance ID |
Optional Kafka platform instance matching DataHub Kafka ingestion identity |
--gateway-platform-id ID |
Explicit bare DataHub platform ID; required with the instance when Gateway datasets exist |
--gateway-platform-instance ID |
Explicit Gateway platform instance; required with the platform ID when Gateway datasets exist |
--output-file PATH |
Atomically replace this file with canonical MCP JSON |
--project-dir PATH |
Project directory |
--env ENV |
Target streamt environment; it does not imply the DataHub fabric |
Supported fabrics are exactly DEV, TEST, QA, UAT, EI, PRE, STG,
NON_PROD, PROD, CORP, RVW, PRD, TST, SIT, SBX, SANDBOX, and
CERT.
# Write canonical simplified MCP JSON to stdout
streamt docs datahub \
--catalog-id payments-prod \
--fabric PROD \
--kafka-platform-instance kafka-main
# Supply an explicit platform and instance for Gateway virtual topics
streamt docs datahub \
--catalog-id payments-prod \
--fabric PROD \
--kafka-platform-instance kafka-main \
--gateway-platform-id conduktor-gateway \
--gateway-platform-instance gateway-prod \
--output-file datahub-mcps.json
# Return proposals, entity/aspect counts, and warnings in the normal envelope
streamt --output json docs datahub \
--catalog-id payments-prod \
--fabric PROD
One project becomes one dataFlow; sources and topic outputs become native
DataHub dataset URNs; actual Flink, Gateway, and Connect processes become
dataJob entities with exact direct Dataset lineage. Process-free topics do
not invent jobs, and Connect sinks do not invent destination datasets. A model
contract contributes only streamt.contract.status with declared or
enforced; this is not an ODCS document, native DataHub DataContract, schema,
or assertion.
Text mode without a file reserves stdout for the canonical JSON array and puts
warnings on stderr. With --output-file, text stdout is empty. Global JSON
mode returns standard, pinned release and API metadata, proposals, exact
entity/aspect counts, and output_file under data; warnings use the normal
top-level array. --quiet suppresses raw output and warning text.
The bounded omission warnings are:
| Code | Meaning |
|---|---|
W115_DATAHUB_SINK_OUTPUT_OMITTED |
A sink DataJob is emitted without an invented destination Dataset |
W116_DATAHUB_EXPOSURE_OMITTED |
One exposure occurrence is omitted |
W117_DATAHUB_TAGS_OMITTED |
One declaration's tag mapping is deferred |
W118_DATAHUB_OWNER_OMITTED |
One declaration's ownership mapping is deferred |
Invalid identity, mapping, validation, serialization, or file output fails
closed with E508_DATAHUB_INVALID and no partial artifact.
This command is an offline metadata-file export. It constructs no DataHub,
Kafka, Gateway, deployment-state, or subprocess client and has no runtime
acryl-datahub dependency. Release gates validate the bytes with the exact
DataHub 1.7.0 SDK, wrapper, and metadata-file reader. A separate test-only gate
also ingests both identity variants twice into a disposable exact v1.7.0 GMS
and verifies emitted aspects and representative direct relationships. The
production command still does not call GMS, ingest the file, publish or
reconcile entities, or verify platform existence. See
DataHub catalog export for identity, mapping, warning,
sensitivity, and pinned server-acceptance details.
docs openlineage¶
Export deterministic, offline-validated OpenLineage 1.53.0 design metadata as canonical JSON Lines.
Options:
| Option | Description |
|---|---|
--job-namespace NAMESPACE |
Job namespace; falls back to OPENLINEAGE_NAMESPACE and is semantically required |
--kafka-namespace KAFKA-URI |
Kafka dataset namespace; falls back to STREAMT_OPENLINEAGE_KAFKA_NAMESPACE or safe single-bootstrap derivation |
--gateway-namespace KAFKA-URI |
Gateway dataset namespace; falls back to STREAMT_OPENLINEAGE_GATEWAY_NAMESPACE or safe single-bootstrap derivation |
--output-file PATH |
Atomically replace this file instead of writing JSONL to stdout |
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
Examples:
# Write validated JSONL to stdout
streamt docs openlineage \
--job-namespace https://lineage.example/namespaces/prod
# Use explicit catalog identities and atomic file output
streamt docs openlineage \
--job-namespace https://lineage.example/namespaces/prod \
--kafka-namespace kafka://catalog-kafka.example:9092 \
--gateway-namespace kafka://catalog-gateway.example:6969 \
--output-file lineage.jsonl
# Retain events and warnings in the normal structured envelope
streamt --output json docs openlineage \
--job-namespace https://lineage.example/namespaces/prod
Text-mode stdout contains only compact canonical JSONL when no output file is
selected; warnings go to stderr. In global JSON mode, events and counts are
under data, while warnings use the normal top-level warnings array. All
events are generated, validated against bundled official schemas, and
serialized before event output begins. Failures use
E506_OPENLINEAGE_INVALID and never emit a partial event stream.
This command exports static DatasetEvent and JobEvent records from one
dry-run compile. It performs no live-service or deployment-state reads and does
not emit RunEvent records. Separately, explicitly enabled apply
--emit-openlineage and test --emit-openlineage support finite command-run
pairs through an explicit File or HTTP transport. Ordinary compile, apply
without the flag, and deployed Flink, Gateway, or Connect processes do not emit
OpenLineage telemetry. See OpenLineage integration for exact
mapping, transport, namespace, validation, and security boundaries.
docs openapi¶
Deprecated compatibility alias for streamt docs asyncapi. It emits the exact
same AsyncAPI 3.1 document; despite the historical command name, it does not
emit an OpenAPI document. New automation should use docs asyncapi.
docs dictionary¶
Export data dictionary (all sources and models with columns).
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
--env ENV |
Target environment (multi-env mode) |
--format FORMAT |
Output format: csv (default) or json |
Examples:
# Export CSV data dictionary
streamt docs dictionary
# Export as JSON
streamt docs dictionary --format json
# Save to file
streamt docs dictionary > data-dictionary.csv
envs¶
Manage and inspect environments (multi-env mode only).
envs list¶
List all available environments.
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
Examples:
Output:
dev Local development environment
staging Staging environment
prod Production environment [protected]
envs show¶
Show resolved configuration for an environment (secrets masked).
Options:
| Option | Description |
|---|---|
--project-dir PATH |
Project directory |
Examples:
Output:
environment:
name: prod
description: Production environment
protected: true
runtime:
kafka:
bootstrap_servers: prod-kafka.example.com:9092
schema_registry:
url: https://prod-sr.example.com
username: admin
password: '****'
Environment Variables¶
| Variable | Description |
|---|---|
STREAMT_ENV |
Default target environment (overridden by --env flag) |
STREAMT_PROJECT_DIR |
Default project directory |
STREAMT_LOG_LEVEL |
Log level (DEBUG, INFO, WARNING, ERROR) |
STREAMT_NO_COLOR |
Disable colored output |
.env File Loading¶
In multi-environment mode, environment variables are loaded with precedence:
.env— Base variables (always loaded).env.{environment}— Environment-specific overrides (e.g.,.env.prod)- Actual environment variables — Highest priority
See Multi-Environment Support for details.
Exit Codes¶
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (validation, deployment, or runtime) |
Structured Error Codes¶
When using --output json, errors include machine-readable codes. These codes follow a taxonomy for programmatic handling.
Validation Errors (E1xx):
| Code | Meaning |
|---|---|
E101_SOURCE_NOT_FOUND |
Referenced source does not exist |
E102_MODEL_NOT_FOUND |
Referenced model does not exist |
E103_DUPLICATE_NAME |
Duplicate resource name |
E104_CYCLE_DETECTED |
Circular dependency in DAG |
E105_JINJA_SYNTAX_ERROR |
Jinja template syntax error in SQL |
E106_ACCESS_DENIED |
Access denied by governance rules |
E107_TEST_MODEL_NOT_FOUND |
Test references nonexistent model |
E108_EXPOSURE_MODEL_NOT_FOUND |
Exposure references nonexistent model |
E109_EXPOSURE_SOURCE_NOT_FOUND |
Exposure references nonexistent source |
E110_EXPOSURE_DEPENDENCY_NOT_FOUND |
Exposure dependency not found |
E111_NAME_COLLISION |
Name collision between resources |
Configuration Errors (E2xx):
| Code | Meaning |
|---|---|
E201_GATEWAY_REQUIRED |
Gateway config required for virtual topics |
E202_FLINK_REQUIRED |
Flink config required for Flink materializations |
E203_CONFLUENT_FLINK_REQUIRED |
Confluent Cloud Flink required (e.g., for ML_PREDICT) |
E204_MISSING_SINK_CONFIG |
Sink model missing connector configuration |
E205_CONNECT_REQUIRED |
Connect cluster config required for sink connectors |
E206_SQL_GATEWAY_NOT_CONFIGURED |
Flink SQL Gateway URL not configured |
E207_CONTINUOUS_TEST_WITHOUT_FLINK |
Continuous test requires Flink cluster |
E208_MISSING_CONFIG |
Required configuration is missing |
Schema Errors (E3xx):
| Code | Meaning |
|---|---|
E301_INVALID_STATE_TTL |
Invalid state TTL configuration |
Deployment Errors (E4xx):
| Code | Meaning |
|---|---|
E401_CANNOT_REDUCE_PARTITIONS |
Cannot reduce topic partition count |
E402_SCHEMA_INCOMPATIBLE |
Schema incompatible with registry |
E403_FLINK_SQL_ERROR |
Flink SQL execution error |
E404_AUTH_FAILED |
Authentication failed |
E405_SSL_ERROR |
SSL/TLS connection error |
E406_CONNECTION_REFUSED |
Connection refused by service |
E407_DEPLOY_ERROR |
General deployment error |
E408_PLAN_FILE_INVALID |
A reviewed deployment/recovery plan or required recovery confirmation is malformed, mismatched, or fails integrity validation |
E409_PLAN_STALE |
Project, environment, ownership state, or live action/evidence drifted after review |
E410_OWNERSHIP_REQUIRED |
A live resource needs an explicit ownership decision or adoption |
E411_STATE_INVALID |
Ownership state is malformed or belongs to another context |
E412_ADOPTION_TARGET_INVALID |
Adoption target is missing, ambiguous, or not explicitly declared adopted |
E413_ADOPTION_LIVE_NOT_FOUND |
Declared physical topic does not exist in Kafka |
E414_ADOPTION_CONFIRMATION_REQUIRED |
Exact resource and environment confirmation is absent or incorrect |
E415_ADOPTION_STATE_CONFLICT |
Existing ownership state conflicts with the requested claim |
E416_ADOPTION_FAILED |
Live observation or atomic adoption-state persistence failed |
E417_SAFETY_BLOCKED |
Apply refused an unsupported partition, schema, or Flink migration before mutation |
E418_REVIEWED_PLAN_REQUIRED |
Direct apply is disabled by protected/shared environment policy; create and apply a reviewed plan file |
E419_STATE_RECOVERY_REQUIRED |
An unfinished operation marker blocks mutation pending explicit recovery |
E420_STATE_BACKEND_UNAVAILABLE |
The configured deployment-state provider cannot be used; no fallback occurs |
E421_REMOTE_STATE_REQUIRED |
Environment policy rejects apply/adopt while local deployment state is selected |
E422_STATE_LOCK_TIMEOUT |
The bounded wait for deployment-state operation authority expired |
E423_STATE_LOCK_LOST |
The operation no longer owns its deployment-state lock; inspect the reported operation ID before continuing |
E424_STATE_CONFLICT |
The observed deployment state or operation control changed; re-observe or re-plan |
E425_STATE_UNKNOWN_OUTCOME |
A state transition may have committed; inspect status and never blindly replay it (recovery permits only exact idempotent verification) |
E426_STATE_RELEASE_FAILED_AFTER_COMMIT |
The commit is verified but authority release is not; data.committed is true and the commit must not be replayed |
Parse Errors (E5xx):
| Code | Meaning |
|---|---|
E501_PARSE_ERROR |
YAML/SQL parsing error |
E502_ENV_VAR_ERROR |
Environment variable not set |
E503_ENVIRONMENT_ERROR |
Environment configuration error |
E504_ASYNCAPI_INVALID |
AsyncAPI generation or validation failed |
E505_ODCS_INVALID |
ODCS metadata, mapping, validation, serialization, or output failed |
E506_OPENLINEAGE_INVALID |
OpenLineage namespace, mapping, validation, serialization, or output failed |
Governance Errors (E6xx):
| Code | Meaning |
|---|---|
E601_NAMING_VIOLATION |
Resource name violates naming convention |
Import Errors (E7xx):
| Code | Meaning |
|---|---|
E701_IMPORT_DISCOVERY_FAILED |
Kafka discovery failed before any declaration was written |
E702_IMPORT_TARGET_EXISTS |
Import target already exists and was not changed |
E703_IMPORT_NAME_COLLISION |
Generated name collides with another generated source or an existing source/model |
E704_IMPORT_PATH_INVALID |
Output is not a direct YAML declaration under sources/ |
E705_IMPORT_VALIDATION_FAILED |
Generated declaration failed strict validation |
E706_IMPORT_WRITE_FAILED |
Exclusive declaration creation failed |
Warnings (Wxxx):
| Code | Meaning |
|---|---|
W101_STATE_TTL_RECOMMENDED |
Stateful query should set state TTL |
W102_MISSING_SOURCE_COLUMN |
Source column referenced but not defined |
W103_MISSING_REF_COLUMN |
Referenced model column not found |
W104_RULE_MAX_RETENTION |
Topic retention exceeds governance limit |
W105_RULE_INVALID_OWNER |
Owner not in allowed owners list |
W106_LOCAL_STATE_ONLY |
Local ownership state is unsafe for shared CI without remote locking |
W107_SCHEMA_ENRICHMENT_SKIPPED |
Optional Schema Registry enrichment was unavailable or unsupported |
W108_IMPORT_TARGET_EXISTS |
Dry-run target exists; a real import would refuse to overwrite it |
W109_ODCS_SCHEMA_INCOMPLETE |
A source or model has no declared columns, so its ODCS object omits properties |
W110_OPENLINEAGE_SCHEMA_INCOMPLETE |
A dataset has no declared columns, so its OpenLineage event omits the schema facet |
W111_OPENLINEAGE_SINK_OUTPUT_OMITTED |
A sink job has no normalized OpenLineage output dataset |
W112_OPENLINEAGE_EMIT_FAILED |
A finite command started, but OpenLineage START, terminal, or transport-close delivery failed without changing command truth |
W201_SQL_PARSE_WARNING |
Non-fatal SQL parsing issue |
W202_UNUSED_SOURCE |
Defined source not referenced by any model |
W203_SOURCE_NO_COLUMNS |
Source has no column definitions |
W301_COLUMN_TYPE_MISMATCH |
Column type mismatch detected |
Examples¶
CI/CD Pipeline (Single Environment)¶
#!/bin/bash
set -e
# Validate
streamt -o json validate --strict
# Build artifacts (manifest + checksums)
streamt build
# Show diff against deployed state
streamt diff
# Plan and apply
streamt plan
streamt apply --confirm
# Verify health
streamt status --health
# Run tests
streamt test
CI/CD Pipeline (Multi-Environment)¶
#!/bin/bash
set -e
# Validate all environments
streamt validate --all-envs --strict
# Deploy to staging
streamt plan --env staging --out staging.plan.json
streamt apply --env staging --plan staging.plan.json
streamt test --env staging
# Deploy to production (protected, with name verification)
streamt plan --env prod --out prod.plan.json
streamt apply --env prod --plan prod.plan.json --confirm-env prod
streamt test --env prod
Agent/LLM Automation¶
# All commands support structured JSON output
streamt -o json list models
streamt -o json show model order_metrics
streamt -o json validate
streamt -o json plan --env prod --out prod.plan.json
streamt -o json apply --env prod --plan prod.plan.json --confirm-env prod
Development Workflow¶
# Set environment for session
export STREAMT_ENV=dev
# 1. Validate changes
streamt validate
# 2. View lineage
streamt lineage --model my_new_model
# 3. Plan deployment
streamt plan
# 4. Apply changes
streamt apply
# 5. Run tests
streamt test --model my_new_model
Monitoring Script¶
#!/bin/bash
# Health check — exit 1 if any resource MISSING or DRIFT
streamt status --health || notify_team "Unhealthy resources detected"
# Detailed check with lag info
streamt status --lag
See Also¶
- Multi-Environment Support — Complete guide for managing dev/staging/prod environments
-
observedandrolled_backrecovery contact every runtime provider needed by the blocked action.abandoned_before_mutationrequires empty durable progress and does not contact runtime targets. An exact retry of an already-completed recovery also skips provider observation and verifies the expected result against recovery history. ↩↩