Date: 2026-07-24
Branch: codex/data-rule-execution-m3a-m5
Task 8 removes the user-facing parallel rule implementations from Data Standard and Data Flow authoring.
The governed path is now:
Generated source code is never editable in the new path. Legacy code and free-text flow rules remain visible only in explicit migration sections and are excluded from new execution semantics.
The control plane now exposes:
GET /api/rules/catalog
query, asset_type, limit, and offset parameters;GET /api/rules/catalog/assets/<rule|standard>/<version_id>/evidence
Compatibility aliases remain available at
/api/rules/catalog/rule-versions and
/api/rules/rule-versions/<version_id>/evidence. Global API policy keeps all
GET paths behind rules:read.
RuleAuthoringPanel now:
rules:edit and rules:publish UI gates;Data Standard editing now links a published RuleVersion through
RuleCatalogPicker. New saves contain the fixed rule_version_id and bounded
migration_metadata; they do not require or write an operation-code field.
Existing operation code is shown in a read-only migration area with clear
unmigrated / linked state and a path back to natural-language
re-authoring. It cannot become execution semantics merely by saving the
legacy record.
Data Flow no longer edits free-text rules or embeds rule definitions.
ProductionLineAssembler models the flow as ordered factory stations:
standard.enforce fixes a standard_version_id;rule.apply and quality.check fix a rule_version_id;The new saved script_requirement envelope contains only:
dataflow_spec;dataset_edges;migration_metadata.It contains no inline rule definition or generated source. Existing legacy requirements remain read-only and are not copied into that envelope.
The implementation reuses Vue 2, Vuetify, Material Design Icons, and the existing request client. No dependency or design system was added.
The interface uses a low-motion, medium/high-density governance-workbench style. Catalog loading, empty and error states are explicit. Catalog items support focus, arrow navigation, Enter/Space selection, listbox semantics, ARIA labels, and skeleton loading. Responsive layout collapses the Data Flow dataset grid on narrow screens.
Fail-first:
5 failed, 3 passed because the
three governed components and convergence behavior did not exist.Final:
64 passed;672 passed, 31 skipped, 59 subtests passed;git diff --check: passed;0 errors;no-console warnings plus existing CSS
ordering and bundle-size warnings;/api/system/health returned application code 200;/api/rules/catalog returned HTTP 401.Browser automation opened the rebuilt deployment and verified the local login surface. The documented local sample administrator password did not match the persisted administrator in this long-lived Docker volume, so authenticated Standard/Data Flow navigation was not forced by overwriting or resetting credentials. The build, component contracts, authenticated API tests, real PostgreSQL query, and container health checks provide the Task 8 acceptance evidence; an authenticated visual walkthrough can be repeated during the phase-level M4 acceptance with the environment owner’s current local credential.
The post-implementation review found eight convergence gaps. All eight are closed:
rule.apply; standard.enforce and
quality.check now match the closed DataFlow contract;unknown;POST /api/interface/data/standard/code is closed with HTTP 410 and
read-only-migration semantics;rule_version_id against the complete trusted publication evidence chain;validated state;
new Standard clauses must bind a server-published RuleVersion;ready is rendered as successful and async
station values are reloaded by the existing deep watcher.The cutover deliberately preserves legacy non-governed records and read-only migration displays, while preventing those fields from becoming new governed execution semantics.
The second review strengthened the boundary from server-issued identifiers to database-enforced, single-use draft reservations:
20260723_210 adds a unique DataFlow UID, actor foreign key,
unique nonce digest, expiration and consumption ledger;UPDATE ... RETURNING;script_type, script path, task, code or workflow fields;Data Standard natural-language authoring now deterministically produces a Rule candidate. The prompt states that rule explicitly, the authoring agent repairs a model-produced Standard candidate, and the API independently checks the post-validation candidate before recording or signing it. New legacy Standard records require an exactly attested published RuleVersion; only an existing legacy record may be updated without one for read-only migration.
Catalog compatibility is now evaluated server-side against the production
line's current input and output schema references. It returns
compatible, incompatible, or unknown with a reason and evidence.
The frontend supplies this context, blocks unknown/incompatible stations,
hydrates an already-fixed version through an exact-version endpoint even
when it is outside the first catalog page, and uses a monotonically
increasing request sequence so stale searches cannot overwrite newer
context.
Real PostgreSQL acceptance confirmed:
20260723_210 (head);The third review replaced the one-shot PostgreSQL-consume/Neo4j-create
boundary with a recoverable create Saga. Historical migration 210 remains
unchanged; forward-only migration 20260724_220 adds:
reserved, creating, completed, and failed states;begin_dataflow_create now uses one conditional UPDATE ... RETURNING to
claim a lease. The claim is committed before the graph side effect. Governed
DataFlow creation installs the idempotent DataFlow.uid unique constraint,
uses MERGE only on the server-reserved UID, and verifies the persisted name,
UID, script type and canonical governed requirement without overwriting an
existing node. Completion conditionally owns the lease and persists the exact
response. A retry after response loss returns that stored response; an expired
lease reclaims the same UID, observes the existing graph node and finalizes it.
Name/UID or immutable-property conflicts fail closed.
Catalog compatibility no longer trusts matching reference strings alone:
SchemaResolver;standard_rule_bindings entry and requires
the same trusted rule plan/evidence/hash chain for every clause;unknown; same-reference hash drift and any bound
Standard rule drift return incompatible;The Data Flow editor stores the reservation expiry, renews it when less than
60 seconds remain, and changes to a new server UID only when the server
returns the explicit draft_reservation_refresh_required signal. It retries
that safe pre-side-effect case once. Network errors and in-progress leases do
not cause a new UID; a completed response-loss retry is replayed by the server.
Additional acceptance evidence:
20260724_220 (head);dataflow_create_in_progress; completion replay returned the identical
result, expired drafts were rejected, and an expired create lease was
reclaimed as attempt 2;data_flow_uid unique constraint, two same-UID
merges produced one node, and immutable drift was rejected;2 passed;