Skip to content

feat(pf): domain model structure/data split + data conformance (FT-145)#16

Merged
Hafeok merged 2 commits into
mainfrom
claude/beautiful-newton-vfgb2v
Jun 22, 2026
Merged

feat(pf): domain model structure/data split + data conformance (FT-145)#16
Hafeok merged 2 commits into
mainfrom
claude/beautiful-newton-vfgb2v

Conversation

@Hafeok

@Hafeok Hafeok commented Jun 22, 2026

Copy link
Copy Markdown
Owner

What & why

Implements the §3.1 structure/data split of the Product Framework so you can validate production data against the domain model. The structure side (entities, relations, invariants) was already captured; this adds the data side and the data conformance verification (§6.3), plus the §13 Data Conformance Profile's standing divergence-rate signal.

The split (three new node kinds)

  • ReferenceSet — constitutive reference data, part of the What (reference_data_for a concept). E.g. the valid shipping methods. Versioned/governed like the rest of the model.
  • DataShape — the structure made machine-checkable: a target entity plus three field-constraint kinds (the SHACL-property side):
    • required — present + non-null
    • enums — value must be a member of a declared reference set
    • types — value must be of a datatype (string/integer/number/boolean/date)
  • ProductionDataset — the oracle pointer: the shape it conforms_to_shape + a JSON source of populated records. Not specification.

Data conformance — product domain data <dataset>

Validates every record against the shape and reports the data-divergence rate, catching the §3.1 defects the structure side can't see — a field null/absent, an undeclared enum value, a wrong datatype:

Data conformance for OrdersLive (shape OrderShape, target Order):
  3 record(s): 2 conforming, 1 violating — divergence rate 33.3% (▲ rising)
  ✗ record 1 [total] missing-required: required field "total" is absent or null
  ✗ record 1 [shipping] not-in-reference-set: value "drone" is not in reference set "ShippingMethods"
  • The verdict reads both ways — "fix the data, or (if the spec is stale) fix the shape" — the one check whose failure can indict the specification (§3.1). Exit 1 on any divergence.
  • Each run is recorded to a per-product history and the report surfaces the trend (first / rising / falling / stable) — the §3.1 "spec staleness becomes measurable" signal, made visible as it happens (§13.3). --no-record skips persistence.
  • domain validate also catches dangling data cross-references (a shape targeting an unknown entity, etc.).

Architecture (slice + adapter, per CLAUDE.md)

  • Pure engine + trend classifier: pf::data_check; data-side rules: pf::rules_data; model: pf::model_data. Thin CLI adapter: commands::domain_data (history I/O + report).
  • Wired through ids/model/edit/validate/turtle/bundle/list; validate_node refactored to keep the function-length gate green.
  • Docs: FT-145, ADR-089 (sealed), TC-1021–1026; checklist regenerated.

Verification

  • cargo build ✅ · cargo clippy -- -D warnings -D clippy::unwrap_used ✅ · cargo xtask check ✅ (0 errors)
  • cargo t: lib 670, integration 711 (incl. 6 new data TCs), sessions 139, property 13, code_quality 16 — all green
  • 12 new unit tests + 6 integration tests (TC-1021–1026)

⚠️ One pre-existing failure, unrelated to this change: tc_366_atomic_batch_write fails only because this CI container runs as root (uid 0), so its chmod 0o555 write-block doesn't apply. It tests migrate link-tests, which this PR does not touch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NGoLrRZv23sg6quHJHEP54


Generated by Claude Code

claude added 2 commits June 21, 2026 20:12
…5 ✓)

§3.1 adds the data side of the domain model. The structure side (entities,
relations, invariants) was already captured; this adds the data side:

- ReferenceSet — constitutive reference data, part of the What
  (reference_data_for a concept), versioned/governed like the rest.
- DataShape — the structure made machine-checkable: a target entity, its
  required fields, and reference-set membership constraints (the SHACL-
  property side).
- ProductionDataset — the oracle pointer: the shape it conforms_to_shape
  plus a JSON source of populated records (not specification).

`product domain data <dataset>` runs §6.3 data conformance: it validates
each record against the shape and reports the data-divergence rate, catching
the two §3.1 defects (a field null/absent in rows, an enum value the schema
never declared). The verdict reads both ways — fix the data, or (if the spec
is stale) fix the shape — and exits 1 on any divergence.

Pure engine in pf::data_check; data-side rules (presence + cross-reference)
in pf::rules_data; model in pf::model_data; CLI is a thin adapter. Wired
through ids/model/edit/validate/turtle/bundle/list. validate_node refactored
to extract check_local_shape (function-length gate).

Adds ADR-089, TC-1021..1024, and unit + integration coverage.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NGoLrRZv23sg6quHJHEP54
Round out the §3.1 data side (FT-145):

- DataShape gains a third constraint kind, `types` (field → datatype:
  string/integer/number/boolean/date), catching type drift the structure
  side cannot see. A wrong type is a per-record `not-of-type` finding;
  unknown datatypes are rejected at author time.
- `domain data` now records each run's divergence rate to a per-product
  history and surfaces the trend (first / rising / falling / stable) against
  the previous run — the §3.1 "spec staleness becomes measurable" signal
  (§13.3), made visible as it happens. `--no-record` skips persistence.

The data-check handler moves to a dedicated commands/domain_data.rs adapter
(history I/O + report); the trend classifier is a pure fn in pf::data_check.
Adds TC-1025/TC-1026 and unit + integration coverage; ADR-089 amended.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NGoLrRZv23sg6quHJHEP54
@Hafeok Hafeok merged commit 22863f3 into main Jun 22, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants