Metadata-Version: 2.4
Name: continuo-validation-runner
Version: 0.1.0
Summary: Slim continuo validation harness: op dispatch, candidate-SQL fetch, result-block; imports one engine adapter by discovery.
Author: Simone Carolini
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.14
Requires-Dist: boto3==1.43.59
Requires-Dist: continuo-validation-contract<0.4,>=0.3
Description-Content-Type: text/markdown

# continuo-validation-runner

The slim, continuo-owned validation harness. It dispatches on `VALIDATION_OP`
(`build_from_sql` / `clone_from_prod` / `ensure_schema` / `drop_schema`), fetches
a node's candidate SQL from S3 when relevant, discovers the single installed
engine adapter (entry-point group `continuo_validation.adapters`), runs the
corresponding warehouse DDL through it, and prints exactly one sentinel-framed
result block on stdout.

It depends on `continuo-validation-contract` (the port + result-block) and, at
image-build time, on exactly one `continuo-validation-<engine>` library —
`Dockerfile.postgres` bakes in `continuo-validation-postgres`. Inside the
shipped images, the contract, the runner, and the engine adapter all install
from this repo's own workspace paths (`contract/`, `runner/`,
`adapters/<engine>/`) in a single pip transaction at image build time, not
from PyPI — see the Dockerfile comments for why. The container entrypoint is
`python /validation_runner.py`, which continuo's executor invokes.
`python -m continuo_validation_runner` reaches the identical `main` and is
convenient for local invocation, but it is not the image contract on its
own — an image built around this package standalone (e.g. for an engine
this repo doesn't ship) has more to satisfy than that one command. This
package is also published to PyPI as `continuo-validation-runner` for
exactly that use; see [the bring-your-own-adapter section of the main
README](https://github.com/carolsimone/continuo-validation-runners/blob/main/README.md#building-a-validation-image-for-an-engine-this-repo-doesnt-ship)
for the full image contract.

## Job, not a service

This is not one of continuo's long-running services — see the service list at
[github.com/carolsimone/continuo](https://github.com/carolsimone/continuo). It
ships as a container image (`continuo-validation-<engine>`) that
`executor-controller` dispatches as a one-shot Kubernetes `Job`
(`BackoffLimit: 0`, `RestartPolicy: Never`) per node or per schema op. The
process reads `VALIDATION_OP`, runs it once, prints one result block, and
exits — there is no process to keep alive, no gRPC/HTTP surface, and no owned
datastore.

Its entire behavior is the four ops dispatched through the `ValidationAdapter`
port (see [`continuo-validation-contract`](https://github.com/carolsimone/continuo-validation-runners/blob/main/contract/README.md))
plus the sentinel result-block wire format. Because that surface is small and
fixed, this runner itself is very unlikely to need changes: adding support for
a new warehouse engine means adding a new `continuo-validation-<engine>`
adapter package and pointing `VALIDATION_IMAGE` at an image built from it, not
editing this code.

The sentinel result-block format is frozen: continuo's Go package
`pkg/validationresult` parses it, so changing it is a coordinated, versioned
event across both repos, not a local edit.
