Skip to content

Provisional SHACL claim validation + alignment-gap analysis#30

Open
DarrenZal wants to merge 1 commit into
regen-prodfrom
darren/claims-shacl-validation
Open

Provisional SHACL claim validation + alignment-gap analysis#30
DarrenZal wants to merge 1 commit into
regen-prodfrom
darren/claims-shacl-validation

Conversation

@DarrenZal

Copy link
Copy Markdown
Contributor

What

Scaffolding for SHACL validation of claims, OFF by default and intentionally NOT wired into create_claim — plus a runnable proof of why it can't be enabled yet.

The finding (the real value here)

koi-processor already emits an rfs:Claim JSON-LD (used for content hashing) with flat keys: claimant_uri / claim_type / statement / about_uri.

The PR #53 LinkML rfs:Claim shape is sh:closed and requires structured slots: schema:name, rfs:hasClaimType, rfs:verificationStatus, rfs:hasClaimant (Entity), rfs:hasSubject (Entity), rfs:hasPrimaryImpact (Impact) — with nested Entity/Impact required slots + controlled-vocab enums.

Same @type, different property vocabulary → today's claims fail validation 100%. Proven executably (pyshacl 0.31 / rdflib 7.6):

(A) LinkML-slot-aligned claim: conforms=True
(B) today's koi flat-key claim: conforms=False
   Message: Node <urn:claim:koi> is closed. It cannot have value: Literal("ecological")

So SHACL can't be meaningfully enabled until the claim representation is aligned (re-key the JSON-LD to LinkML slots, or extend the claim model — note hasSubject/hasPrimaryImpact are required but have no source field in ClaimCreateRequest). Coordinate upstream with PR #53 + FWG/Marie. See docs/claims/shacl-alignment-gap.md.

Contents

  • schema/shacl/claim.shacl.ttl — shape generated from PR #53 Claim.yaml (provisional until #53 merges)
  • api/shacl_validation.pypyshacl wrapped in asyncio.to_thread (never block the single-worker event loop), fail-closed on missing shape, gated by VALIDATE_CLAIMS_SHACL (default false)
  • docs/claims/shacl-alignment-gap.md — gap, proof, two fix options, exact wiring point
  • tests/test_shacl_claim_shape.py — codifies the proof (3 tests, green)
  • requirements.txtpyshacl>=0.27, rdflib>=7.0

Safety

Review branch. Do not merge to regen-prod until the claim model is aligned — regen-prod auto-deploys to personal-koi, and enabling synchronous SHACL on the single-worker hot path is an outage risk (asyncio.to_thread mitigates event-loop blocking, but profile under load first).

🤖 Generated with Claude Code

…ysis

Adds the SHACL-validation scaffolding for claims, OFF by default and NOT yet
wired into create_claim — because the koi-processor rfs:Claim JSON-LD (flat
keys: claimant_uri/claim_type/statement) does not match the PR #53 LinkML
rfs:Claim slot vocabulary (hasClaimant/hasSubject/hasPrimaryImpact/...). A
runnable proof demonstrates the gap: an LinkML-slot-aligned claim CONFORMS;
today's flat-key claim fails with sh:closed violations.

- schema/shacl/claim.shacl.ttl: shape generated from regen-data-standards
  PR #53 Claim.yaml (linkml ShaclGenerator; provisional until #53 merges)
- api/shacl_validation.py: pyshacl wrapped in asyncio.to_thread (never block
  the single-worker event loop), fail-closed on missing shape, gated by
  VALIDATE_CLAIMS_SHACL (default false)
- docs/claims/shacl-alignment-gap.md: the gap, the proof, two fix options,
  exact create_claim wiring point
- tests/test_shacl_claim_shape.py: codifies the proof (3 tests, green)
- requirements.txt: pyshacl>=0.27, rdflib>=7.0

Review branch only — do NOT merge to regen-prod (auto-deploys to personal-koi).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.

1 participant