Skip to content

did2: enforce superclasses-chain consistency in validateDocument#132

Merged
stevevanhooser merged 1 commit into
V2from
claude/ndi-matlab-did2-migration-Dp03V
May 19, 2026
Merged

did2: enforce superclasses-chain consistency in validateDocument#132
stevevanhooser merged 1 commit into
V2from
claude/ndi-matlab-did2-migration-Dp03V

Conversation

@stevevanhooser
Copy link
Copy Markdown
Contributor

Summary

Closes the last gap between V_delta's spec and did2-matlab's validator: document_class.superclasses must equal the schema-derived chain class-name-by-class-name (V_gamma_SPEC.md §"Validation checklist", inherited unchanged by V_delta per conversions/from_did_v1/_universal_renames.md §4).

validateDocument previously only required one property block per chain class — a hand-built or partially-migrated doc could pass with a truncated or reordered superclasses array, which silently breaks transitive isa queries downstream. The clearest example is ndi-cloud-node's classLineage field, which is computed from document_class.superclasses[*].class_name and never independently resolves the schema chain — so the writer must emit the full transitive closure.

Changes

  • src/did/+did2/+schema/cache.m: validateDocument now compares dc.superclasses to obj.superclasses(className) and raises one of three errors on drift:

    • did2:validation:missingSuperclasses — the field is absent.
    • did2:validation:badSuperclassEntry — an entry lacks class_name.
    • did2:validation:superclassesChainMismatch — wrong length, wrong order, or wrong names.

    Added a small superclassClassNames helper that normalises the [] / scalar-struct / struct-array shapes the same way the existing BFS does.

  • src/did/+did2/+convert/v1_to_v2.m: ensureClassBlocks now also rebuilds document_class.superclasses from the schema cache after per-class migrators run. Necessary because the v1→v2 pipeline previously preserved the v1 chain verbatim — when V_delta has reordered or extended the chain (e.g., oridirtuning_calc adding tuning_fit), the migrated doc would now fail the new check. Migrators still see the v1-shaped chain when they dispatch; the rewrite happens after.

  • tests/+did2/+unittest/testSchemaCache.m: five new tests covering truncated chain, reordered chain, missing-field, malformed-entry, and base's legitimate empty-chain case.

Why this matters for the NDI-matlab did2 migration

ndi-cloud-node's classLineage is the index backing isa queries. It's populated from the document's document_class.superclasses array verbatim — no schema traversal, no graph walk. The cloud trusts the writer. This change makes the writer trustworthy by failing loudly the moment a non-spec-compliant chain shows up, rather than letting it ship to Mongo and silently miss documents on every ancestor-class query.

Test plan

  • did2.unittest.testSchemaCache passes (new chain-consistency tests).
  • did2.unittest.testConvertV1ToV2 passes (verifies the migrator rebuild).
  • Corpus tests (B, Dab, JH, PRED, Soph) still pass — they exercise the v1→v2 path that the migrator change touches.

Generated by Claude Code

V_gamma_SPEC (inherited unchanged by V_delta per
conversions/from_did_v1/_universal_renames.md §4) requires that
document_class.superclasses match the schema-derived chain
class-name-by-class-name. validateDocument previously only checked
that one property block existed per chain class; a hand-built or
serialised doc could pass with a truncated or reordered superclasses
array, which silently breaks transitive isa queries downstream
(notably ndi-cloud-node's classLineage computation).

- cache.validateDocument now compares dc.superclasses to
  obj.superclasses(className) and raises
  did2:validation:superclassesChainMismatch (or
  :missingSuperclasses / :badSuperclassEntry) on drift.
- v1_to_v2.ensureClassBlocks rebuilds document_class.superclasses
  from the schema cache after per-class migrators run, so v1 inputs
  whose chain order/membership drifts from V_delta still produce
  spec-compliant output.
- testSchemaCache covers truncated, reordered, missing-field, and
  malformed-entry cases, plus the base-class empty-chain accept.
@stevevanhooser stevevanhooser merged commit 7542cd2 into V2 May 19, 2026
3 checks passed
@stevevanhooser stevevanhooser deleted the claude/ndi-matlab-did2-migration-Dp03V branch May 19, 2026 00:03
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