|
|
@@ -25,9 +25,10 @@ The delivered chain is:
|
|
|
`draft` RuleVersion plus an immutable validation profile.
|
|
|
5. Logical validation compiles a closed, validation-only Polars plan against
|
|
|
the separately pinned input and output schema snapshots.
|
|
|
-6. Logical testing executes that exact plan in the isolated Polars worker
|
|
|
- against the pinned MinIO sample artifact. Digest, schema, resource, row,
|
|
|
- expiry, and ownership checks are enforced by `ArtifactStore`.
|
|
|
+6. Logical testing executes that exact plan and any golden comparison in the
|
|
|
+ same isolated Polars worker against pinned MinIO artifacts. Digest, schema,
|
|
|
+ resource, row, expiry, and ownership checks are enforced by
|
|
|
+ `ArtifactStore` and the bounded worker.
|
|
|
7. Successful evidence advances RuleVersion `draft -> validated` and logical
|
|
|
plan `compiled -> tested`.
|
|
|
8. Publication requires exact successful compile and test evidence and advances
|
|
|
@@ -61,11 +62,19 @@ clock skew are checked cryptographically and against current database time
|
|
|
during consumption.
|
|
|
|
|
|
Draft creation performs `SELECT ... FOR UPDATE` on the generation record and a
|
|
|
-compare-and-set consumption update. A receipt is rejected if it is expired,
|
|
|
+compare-and-set consumption update. A new consumption is rejected if it is expired,
|
|
|
tampered, belongs to another actor, has a different source/RuleSpec/candidate
|
|
|
or validation context, has already been consumed, or is linked to another
|
|
|
version.
|
|
|
|
|
|
+An exact same-actor receipt replay after an unknown commit outcome returns the
|
|
|
+already-linked canonical draft even after the short-lived receipt expires.
|
|
|
+This replay path still requires the same signed receipt hash and every canonical
|
|
|
+claim to match; expiry is bypassed only after the consumed row is proven exact.
|
|
|
+New consumption uses PostgreSQL `clock_timestamp()` rather than the
|
|
|
+transaction-start timestamp, so a long-running transaction cannot extend a
|
|
|
+receipt's usable lifetime.
|
|
|
+
|
|
|
Publication locks the rule/plan/profile/schema or
|
|
|
plan/component/rule/binding/schema rows in one transaction and re-reads the
|
|
|
current compiler, RuleSpec, plan, schema, binding, data source, object,
|
|
|
@@ -129,7 +138,12 @@ physical backends are rejected on current schema, binding, dialect, plan-hash,
|
|
|
RuleVersion, or logical-evidence drift.
|
|
|
|
|
|
Logical dry-run supports a distinct output schema and optional golden Parquet
|
|
|
-result. Golden comparison uses canonical output-field order. The real
|
|
|
+result. The server stages both artifacts and passes their local paths and
|
|
|
+digests to one spawned worker governed by the plan's single RLIMIT/RSS/timeout
|
|
|
+budget. That worker verifies the staged golden digest and compares exact
|
|
|
+schema, row count, row order, null positions, and field values. The Flask
|
|
|
+process does not materialize either Parquet result. Concurrent large-golden
|
|
|
+tests fail closed inside the same resource boundary. The real
|
|
|
cross-schema acceptance reads `name/mobile`, derives `name_copy`, removes one
|
|
|
quarantined row, and compares the output to the pinned golden artifact.
|
|
|
|
|
|
@@ -148,9 +162,11 @@ Migration `20260723_200` is forward-only and adds:
|
|
|
- validation failures and publication audits;
|
|
|
- the published-rule catalog index.
|
|
|
|
|
|
-The migration refuses to run when revision 190 contains any published
|
|
|
-RuleVersion or execution plan, because pre-Task-7 rows cannot be silently
|
|
|
-upgraded into trusted evidence. Physical evidence carries an explicit
|
|
|
+The migration refuses to run when revision 190 contains any RuleVersion or
|
|
|
+execution plan, including draft and validated rows, because no pre-Task-7 row
|
|
|
+can possess the required generation, compile, test, and publication provenance.
|
|
|
+Operators must export and remove all legacy rows, apply migration 200, and then
|
|
|
+rebuild each rule through the Task 7 chain. Physical evidence carries an explicit
|
|
|
`legacy_untrusted` marker, and publication/Runner/DataFlow gates require it to
|
|
|
be false. Downgrade is deliberately rejected because deleting publication and
|
|
|
generation evidence would break audit and replay guarantees.
|
|
|
@@ -176,6 +192,18 @@ validation/testing while publication keeps the existing administrative
|
|
|
permission boundary. The documented canonical catalog path is implemented;
|
|
|
the prior nested path remains a compatibility alias.
|
|
|
|
|
|
+`/interpret` preflights the dedicated receipt signer before resolving context
|
|
|
+or invoking the model, so missing configuration cannot incur model cost.
|
|
|
+Local and production environment templates and deployment runbooks document
|
|
|
+generation and coordinated rotation of `RULE_GENERATION_RECEIPT_SECRET`
|
|
|
+without containing a real secret.
|
|
|
+
|
|
|
+DataFlow release no longer trusts RuleVersion status alone. Its production
|
|
|
+asset loader requires the exact published logical plan, successful compile
|
|
|
+evidence, successful test evidence, matching plan/schema/capability hashes,
|
|
|
+and the matching publication audit. Revoked or drifted logical evidence makes
|
|
|
+the referenced rule unavailable and the release fails closed.
|
|
|
+
|
|
|
## Acceptance evidence
|
|
|
|
|
|
Fail-first evidence included:
|
|
|
@@ -191,19 +219,24 @@ Fail-first evidence included:
|
|
|
|
|
|
Final verification:
|
|
|
|
|
|
-- focused data-rule/API/migration suite: `183 passed`;
|
|
|
+- focused second-round trust-boundary suite: `39 passed`;
|
|
|
+- focused data-rule/API/migration suite from the initial delivery:
|
|
|
+ `183 passed`;
|
|
|
- Runner plus real PostgreSQL/MySQL/Polars regression: `126 passed`;
|
|
|
- real PostgreSQL + MinIO cross-schema receipt/logical lifecycle:
|
|
|
`1 passed`;
|
|
|
- real `PhysicalPlanPublicationService` PostgreSQL/MySQL lifecycle, drift,
|
|
|
evidence replay, and PostgreSQL concurrency: `2 passed`;
|
|
|
- full repository suite:
|
|
|
- `626 passed, 29 skipped, 59 subtests passed`;
|
|
|
+ `632 passed, 29 skipped, 59 subtests passed`;
|
|
|
- changed-file Ruff: `All checks passed!`;
|
|
|
- `git diff --check`: passed;
|
|
|
- empty local PostgreSQL full Alembic rebuild:
|
|
|
base through `20260723_200 (head)`;
|
|
|
-- real revision-190 legacy publication upgrade guard: `1 passed`.
|
|
|
+- real revision-190 draft/validated/published upgrade guards: `3 passed`.
|
|
|
+- rebuilt local Docker backend: container reported `healthy`, and
|
|
|
+ `GET /api/system/health` returned HTTP/application code `200` with database
|
|
|
+ and Neo4j healthy.
|
|
|
|
|
|
Skipped tests are environment-gated integration suites. The required real
|
|
|
PostgreSQL, MySQL, and MinIO acceptance tests above were run explicitly against
|
|
|
@@ -217,9 +250,10 @@ for logical validation because those rows require a real deployment and
|
|
|
component binding. Production execution evidence remains owned by the Task 6
|
|
|
Runner path after a physical plan is published.
|
|
|
|
|
|
-Task 7 now supports separate input/output snapshots and cross-schema
|
|
|
-transformations. The remaining scope is production operational rollout:
|
|
|
-secret provisioning/rotation, multi-replica load and failure testing,
|
|
|
-monitoring/alert thresholds, and production canary/rollback evidence. Those
|
|
|
+Task 7 now supports separate input/output snapshots, cross-schema
|
|
|
+transformations, deployable secret templates, and a documented rotation
|
|
|
+procedure. The remaining scope is production operational rollout:
|
|
|
+multi-replica load and failure testing, monitoring/alert thresholds, and
|
|
|
+production canary/rollback evidence. Those
|
|
|
operational gates are outside this local Docker acceptance and must be closed
|
|
|
before a production environment is declared ready.
|