Status: experimental Phase 0 contract hardening
IDKMesh already separates:
Work Unit
-> worker ResultManifest
-> independent VerificationResult
-> integration / human / governance decision
JSON Schema can validate the shape of each object, but shape validation alone cannot prove that the objects refer to the exact same underlying work and result.
A verifier could otherwise provide a schema-valid result_manifest_digest or work_unit_digest that does not match the referenced object while the IDs still look correct.
The Phase 0 integrity rule uses deterministic JSON serialization:
json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
The UTF-8 bytes are hashed with SHA-256 and encoded as:
sha256:<64 lowercase hex characters>
This is the same canonical-digest convention already used by the Phase 0 harness.
For a tuple (WorkUnit, ResultManifest, VerificationResult) the integrity checker requires:
ResultManifest.work_unit_id == WorkUnit.id.ResultManifest.work_unit_version == WorkUnit.version.ResultManifest.provenance.work_unit_digest == canonical_digest(WorkUnit).VerificationResult.result_manifest_id == ResultManifest.id.VerificationResult.provenance.result_manifest_digest == canonical_digest(ResultManifest).VerificationResult.provenance.work_unit_digest == canonical_digest(WorkUnit).VerificationResult.provenance.source_revision == ResultManifest.provenance.source_revision.VerificationResult.independence.worker_id_observed == ResultManifest.worker.id.The existing Phase 0 harness continues to enforce validator coverage, evidence references, independent-verifier requirements, and decision-support constraints. This integrity layer complements rather than replaces those checks.
Cross-object equality and cryptographic binding are relational properties. JSON Schema validates one document at a time and should not be stretched into pretending that it has independently loaded and hashed referenced objects.
The executable rule therefore lives in:
experiments/provenance_integrity.py
and runs in Phase 0 CI.
Positive fixtures:
examples/work-units/phase0-smoke.work-unit.jsonexamples/results/phase0-smoke.result-manifest.jsonexamples/results/phase0-smoke.verification-result.jsonNegative fixture:
examples/results/invalid-mismatched-provenance.verification-result.jsonThe negative fixture is deliberately schema-shaped and otherwise plausible, but declares the wrong ResultManifest digest. CI must reject it.
A matching digest proves object identity under the canonical serialization convention; it does not prove that the candidate is correct, that the verifier is honest, or that the result should be merged.
The trust model remains:
proposal != proof, and verification evidence != final authority.
This Phase 0 convention is intentionally simple. If IDKMesh later adopts signed attestations, Merkle transparency logs, content-addressed stores, DSSE/in-toto envelopes, or another provenance standard, the same invariant should remain: every verification statement must be bound to the exact candidate and exact work specification it claims to evaluate.