Date: 2026-07-23
Branch: codex/data-rule-execution-m3a-m5
Implementation commits: 69d83ed, f4d798b, 8bffdb6
8bffdb6 is the final hash of the second remediation commit. It replaces the
intermediate a17bcd0 after restoring the historical M3A acceptance document
byte-for-byte; no production or test behavior changed in that amend.
Lifecycle boundary: physical Polars plans are created as compiled; Task 5
does not add a production promotion API. The real integration inserts a
published fixture only to exercise the existing Runner publication gate.
Task 5 now provides a fail-closed PostgreSQL/MySQL → Parquet/MinIO → isolated Polars → cataloged Parquet path through the production repository, resolver, executor, HTTP token, and durable task-ledger combination.
The final implementation includes:
date(), timestamp(), timestamp cast, and
timestamptz cast;RLIMIT_AS, bounded execution time, and
fail-closed worker errors;(correlation_id, binding_id, artifact_kind);The bound plan contains canonical RuleVersion, SchemaSnapshot, and
DatasetBinding hashes plus dataops-polars-1.42.1 provenance. It contains no
Python source, pickle, callable, module, caller-supplied path, arbitrary URL,
secret, or serialized Polars internal plan.
The second review was implemented as fail-first slices. Representative RED evidence captured during the work:
schema_fields.app/runner/polars_worker.py existed;
the first adapter reconstruction run then exposed one schema-order failure
(1 failed) because canonical fields are name-sorted while Parquet retains
physical column order. Validation was corrected to compare the closed field
set and exact per-field types.test_polars_cast_operations_carry_complete_typed_targets failed
(1 failed) with missing target_field.test_polars_expression_date_and_timestamp_use_plan_timezone failed
(1 failed) because timestamp() produced timezone-aware output for a
timezone-free timestamp contract.1 failed, 553 passed) after in-memory BytesIO staging was removed; the
regression check was changed to assert the stage implementation contains no
BytesIO.io, nested
with); both were fixed before final verification.Second-remediation GREEN:
57 passed in 4.17s.30 passed in 3.92s.1 passed in 2.03s.554 passed, 26 skipped, 59 subtests passed in 8.39s.All checks passed!.git diff --check: passed.docker compose -f deploy/docker/docker-compose.yml config -q: passed.Migration 20260723_140 now enforces:
UNIQUE (correlation_id, binding_id, artifact_kind)
Its downgrade raises RuntimeError because removing the catalog would violate
immutable runtime handoff evidence.
PostgresArtifactResolver.register implements the retry invariant:
Resolution requires the exact artifact kind, current binding hash, matching correlation prefix, valid TTL, digest, row count, and schema hash. The integration asserts one input, one lookup, and one output row/object after repeated deterministic execution.
cleanup-rule-artifacts --limit uses a bounded
FOR UPDATE SKIP LOCKED selection, removes each expired store object, and
deletes its exact catalog row in the same database transaction scope. Unit
tests cover the CLI and object+row cleanup behavior.
The local database had an earlier applied copy of migration 140. Before real integration, its artifact table was verified empty and its old unique constraint was aligned to the final triple invariant. Migration source tests verify the clean-install definition.
ArtifactStore.stage:
NamedTemporaryFile while hashing;pyarrow.parquet.ParquetFile;Full schema contracts are no longer base64-encoded into MinIO metadata. MinIO metadata contains only bounded digest/count/expiry/size fields, with a 2,048-character aggregate ceiling. PostgreSQL remains the canonical store for the complete schema contract.
The adapter stages paths but does not collect input frames. A spawn child:
RLIMIT_AS relative to baseline virtual memory;The parent independently watches incremental RSS with psutil, kills the child on limit breach, enforces a hard timeout, and returns only bounded metrics. Worker PID is deliberately not exposed in the public result.
Tests prove:
Portability boundary: spawn and psutil are portable, but the OS hard limit
requires Unix resource.RLIMIT_AS. Linux/macOS are supported targets. On a
platform without RLIMIT_AS, the worker fails closed instead of silently
running without an OS memory boundary.
Each compiled cast operation now contains an exact target_field. The shared
validator rejects a missing field, an unknown/extra shape, a target name/type
mismatch, incomplete Decimal precision/scale, or missing timestamptz timezone.
The worker no longer falls back to inferring cast details from output fields.
Executable tests verify:
Decimal(12, 2);Datetime(time_zone="Asia/Shanghai");timestamp;date(offset_value) converts to the rule timezone before selecting the
calendar date;timestamp(offset_value) converts to the rule timezone and removes timezone
metadata to match the platform's timezone-free timestamp type.The integration discovers runtime values from
deploy/docker/docker-compose.yml; credentials are not copied into source.
/v1/tasks/execute: signed short-lived task token;PostgresTaskLedger: single-use claim and committed success record.Evidence:
success / committed;schema_fields;The test finally removes only its exact correlation prefix, source tables, ledger record, catalog entries, plan/binding/deployment/rule rows, and schema snapshots, and asserts the MinIO prefix is empty.
docs/security/data-rule-runtime-sbom.json now uses standard CycloneDX fields:
licenses;externalReferences;properties;bom-ref and dependency relationships.Pinned runtime components:
polars==1.42.1 — MIT;polars-runtime-32==1.42.1 — MIT;pyarrow==21.0.0 — Apache-2.0;psutil==5.9.8 — BSD-3-Clause;minio==7.2.10 — Apache-2.0.The test validates the document with jsonschema against vendored official
CycloneDX 1.5, SPDX, and JSF schemas. The official files' SHA-256 hashes are
asserted before validation, so the check is deterministic and offline.
Production:
app/core/data_rules/compilers/polars.pyapp/runner/artifacts.pyapp/runner/polars_worker.pyapp/runner/rule_polars.pyapp/runner/bootstrap.pymigrations/versions/20260723_140_rule_run_artifacts.pyrequirements.txtdocs/security/data-rule-runtime-sbom.jsondocs/security/cyclonedx-1.5-schema/Tests:
tests/core/data_rules/test_polars_compiler.pytests/runner/test_artifacts.pytests/runner/test_polars_worker.pytests/runner/test_rule_polars.pytests/runner/test_bootstrap.pytests/integration/test_data_rule_polars_execution.pytests/test_data_rule_runtime_sbom.pytests/test_data_rule_schema.pyRulePlanExecutor continues to refuse compiled plans in the published
runtime path.quality_check remains fail-closed through the existing adapter; Task 5 does
not claim an artifact-backed quality-check implementation.ArtifactStore.read remains a compatibility/helper API that can return a
bounded in-process frame. The production Polars adapter does not call it;
it uses staged files plus the isolated worker.RLIMIT_AS is unavailable.