Skip to content

Add idempotency short-circuit to v1_to_v2 converter#133

Merged
stevevanhooser merged 2 commits into
V2from
claude/fix-issue-777-ndi-did-gSjyu
May 19, 2026
Merged

Add idempotency short-circuit to v1_to_v2 converter#133
stevevanhooser merged 2 commits into
V2from
claude/fix-issue-777-ndi-did-gSjyu

Conversation

@stevevanhooser
Copy link
Copy Markdown
Contributor

Summary

Implements an idempotency short-circuit in the v1-to-v2 document converter to safely handle re-runs and mixed batches of already-converted and unconverted documents. Documents that are already V_delta-shaped skip the expensive universalRenames and per-class migrators, making the converter safely re-runnable after interruptions.

Key Changes

  • Added isAlreadyVDelta() helper function that detects V_delta-shaped documents by checking two conditions:

    • base.schema_version == 'V_delta' (set by universalRenames or external writers)
    • Absence of v1-only underscore-prefixed top-level keys (legacy structural markers)
    • Both conditions must hold to avoid misclassifying partially-converted or out-of-band-tagged documents
  • Modified main conversion loop to short-circuit when isAlreadyVDelta() returns true:

    • Skips universalRenames and per-class migrators
    • Still runs ensureClassBlocks (rebuilds superclass chain) and validation
    • Preserves already-migrated field shapes verbatim
  • Added comprehensive test coverage:

    • testShortCircuitOnAlreadyVDeltaBody: Verifies v1-shaped fields are preserved when short-circuiting
    • testIdempotencyOfDoubleRun: Confirms running converter twice produces identical output
    • testMixedBatchOfV1AndVDeltaBodies: Tests batches with both v1 and V_delta documents
    • testShortCircuitSkippedWhenSchemaVersionMissing: Guards against incomplete short-circuit conditions

Implementation Details

  • The dual-condition check prevents silent skipping of bulk v1 corpora that lack underscore markers but still need full migration
  • Short-circuited documents still go through ensureClassBlocks to maintain schema consistency
  • Enables safe resumption of partial migration runs without corrupting already-converted documents

https://claude.ai/code/session_01PcQ9ZBthfXnHaiNcQhQLQd

claude added 2 commits May 19, 2026 00:36
Bodies already in V_delta shape (base.schema_version == 'V_delta' AND
no v1-only underscore-prefixed top-level markers) now skip
universalRenames and the per-class migrators. ensureClassBlocks and
validate still run so the chain rebuild and drift gate happen on
every body.

Makes the converter safely re-runnable so the database normalisation
(issue #3) and migration commands (issues #9, #10) can resume after
an interruption without corrupting already-converted docs. Both
gates must hold to short-circuit: the schema-version check alone
would let a V_delta-tagged body with legacy field shapes slip
through, and the underscore-marker check alone would silently skip
the bulk of v1 corpora that do not happen to use the legacy markers.

Tests:
- short-circuit fires on a V_delta body: v1-shaped fields in the
  epochclocktimes block (clocktype, t0_t1) stay verbatim because
  the superclass migrator never runs
- double-run idempotency: feeding a freshly-migrated body back
  through v1_to_v2 produces the same struct
- mixed batch of v1 and V_delta bodies all migrate, summary counts
  collapse correctly
- short-circuit does not fire when schema_version is absent, even
  when there are no underscore markers (guards the AND reading)

Closes VH-Lab/NDI-matlab#777.
The previous version asserted that the treatment migrator collapsed
ontology_name + name into a treatment_name composite, but that
migrator was deleted in #130 (did-schema PR #44 reverted the
treatment class to the v1 flat shape, so the dispatcher's identity
fallback handles it).

Verify the universalRenames pass another way: feed a v1-shaped
depends_on (carries `id` and the legacy `version` key, no `value`)
and assert universalRenames promoted id -> value and dropped the
legacy keys. Still exercises the "no schema_version => no short
circuit, full pipeline runs" path.
@stevevanhooser stevevanhooser merged commit 0099629 into V2 May 19, 2026
3 checks passed
@stevevanhooser stevevanhooser deleted the claude/fix-issue-777-ndi-did-gSjyu branch May 19, 2026 17:18
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