Walking skeleton#
The walking skeleton is a real distributed external validation for the model-export architecture:
isolated Docker Compose project
→ Ray Jobs API
→ Ray Data Parquet
→ XGBoostTrainerImpl
→ S3 Bundle (ONNX + UBJ)
→ BundleReader
→ Ray Data map_batches
→ Ray Serve HTTP
The same job records committed-Bundle provenance through the required MLflow Hook. It verifies that the Hook records the Bundle URI, manifest digest, tags, and artifacts without creating an MLflow Model Version.
Runtime Topology#
tests/integrations/docker-compose.data-ingestion.yml starts one Ray head, one
independent Ray worker, MinIO, and MLflow under the model-export profile. The
test submits tests/integration/jobs/model_export_architecture_job.py through
the Ray Jobs HTTP API; it does not start a host-local Ray runtime or execute the
job directly in the head container.
No service publishes a fixed host port and no service has a fixed container name. The Compose project name is unique per run, so the gate cannot attach to, restart, or remove an existing container.
Contracts Exercised#
Boundary |
Evidence |
|---|---|
Version contract |
The job checks Python, Ray, MLflow, boto3, botocore, XGBoost, ONNX, ONNX Runtime, onnxmltools, Torch, Transformers, PyArrow, and pandas against |
Training lifecycle |
A first-party XGBoost trainer receives an explicit Bundle URI, uses its default ONNX opset 12 and UBJ targets, and returns the stable |
Bundle publication |
Both required artifacts commit to MinIO in one immutable Bundle and expose |
Integrity |
|
Batch inference |
The ONNX artifact is loaded through the Bundle role and used by Ray Data |
Online inference |
Ray Serve loads the same Bundle and returns predictions through HTTP. |
Provenance |
The explicit required MLflow Hook records one run and zero Model Versions. |
Distributed execution |
Ray reports both the head and the independent worker alive while the Ray Job runs. |
The first-party conformance suite runs in the same pinned Linux image before the golden path. It covers the XGBoost ONNX/UBJ/JSON exporters, Torch ONNX/Safetensors/PT2 exporters, Hugging Face ONNX exporter, ONNX quantizer, Structure and ONNX Runtime validators, and Ray checkpoint source providers.
External Validation Gate#
ci/test-suites.json reports this validation when relevant code changes. No
GitHub Actions event runs it. From an approved Docker environment, the
lifecycle-owned runner creates a unique Compose project, executes the pinned
component check and first-party conformance suites, submits the Ray Job, and
saves service logs:
./scripts/run_model_export_it.sh --suite ci
The historically named ci subset includes the component-version contract,
first-party conformance, real MLflow Hook contract, and distributed walking
skeleton. The name describes its bounded contents and does not make it a CI
job. The runner always performs exact-project cleanup equivalent to:
docker compose \
--env-file tests/integrations/component-versions.env \
--file tests/integrations/docker-compose.data-ingestion.yml \
--profile model-export \
down --volumes --remove-orphans
The cleanup command is scoped by the run-specific COMPOSE_PROJECT_NAME.
Full-Flow External Verification#
The same lifecycle-owned runner exposes a release-oriented full suite that is also excluded from every GitHub Actions workflow:
./scripts/run_model_export_it.sh --suite full
It performs prerequisites checks, snapshots the ID and state of every existing
container, uses a unique Compose project and the validated content-addressed
data-ingestion runtime image, writes pytest and service logs to
/tmp/<project-name>/, and installs an EXIT trap before any container is
started. In addition to the bounded subset, full mode runs the trainer Bundle contract
and complete S3/MinIO contract suites. The trap always removes only that
project’s containers, volumes, network, and orphans. It then fails if an owned
container remains or reports if concurrent host activity changed a pre-existing
container.
Deliberate Exclusions#
Excluded |
Boundary |
|---|---|
GPU training |
The external validation is CPU-only. |
DNN/PU full training |
Their Bundle vertical slices and exporter/source conformance are separate integration tests. |
Streaming |
Streaming has a separate lifecycle and is not part of model-export publication. |
MLflow Model Version/Alias |
This cycle provides Bundle provenance only. |
Cross-process Hook recovery |
PostgreSQL, Outbox, and asynchronous workers require a separate scope amendment. |