Skip to content
🚧 Early alpha — building the foundation. See the roadmap →

Challenge 43: Version migration — the semantic-diff loop

Created Updated

Surfaced 2026-07-11 in a local architect working draft (.workspace/2026-07-11-thinking-big-the-lifecycle-arc.md, gitignored per the research-artifact lifecycle convention — pre-decision drafts stay local; see the workbench synthesis log for the public record of the build era it closes). The owner’s reframe: Crosswalker is not an importer, it’s the place ontologies live — a five-act product where Act 1 (import) is what v0.1.6 ships, and Act 2 (live with it) — “framework versions update; Crosswalker shows a semantic diff vs your vault and runs a guided migration preserving user notes, links, evidence” — is the proposed headline of v0.2, not a footnote. The strategic bet: “import anything” is a feature list; “your frameworks update and your world survives” is a moat.

The Act 2 sketch (match pass → impact pass → review UI → apply → audit) is architect-drafted, not stress-tested. This challenge is that stress test — specifically against how publishers actually behave, not how a tidy diff algorithm would like them to behave.

This is not a green field. A large, pre-v0.1 Foundation-phase concept page already maps most of this problem in detail — before render(), recipes, or the workbench existed. Part of this challenge’s job is auditing whether that vision still holds against what actually shipped.

AssetWhat it gives you
Ontology evolutionRead this first, fully. The three-layer problem (ontology changes → crosswalks break → your work breaks), the actors/timing table (NIST every 5-10yr with Federal Register notice; MITRE every 6mo with STIX JSON changelog; CIS ad hoc with no machine-readable diff), Slowly Changing Dimensions (Type 1 overwrite / Type 2 keep-history / Type 3 alias / Type 6 hybrid — Crosswalker’s committed default is Type 2 + Type 3), bitemporal tracking, the N² vs pivot/interlingua translation analogy, and a “What Crosswalker does about all this” section naming an EvolutionPattern taxonomy and migration-strategy engine that were designed but not built
Framework versioningPublisher-specific what-actually-changed detail: NIST CSF 1.1→2.0 (GOVERN function added, ids renamed PR.AC-1→PR.AC-01), NIST 800-53 Rev4→5 (65 controls + 2 new families), MITRE ATT&CK’s STIX 2.1 machine-readable changelogs + lifecycle states (the closest thing to a “gold standard”), CIS v7→v8 (renumbered, no automated migration), CRI Profile v1.2→v2.0. Also covers who maintains crosswalks (NIST OLIR — submission-based, no staleness notification)
Data model resilienceThe already-recommended strategy: version-tagged folders (SCD Type 2) + previous_ids aliasing (SCD Type 3); stale-crosswalk detection via source-hash comparison; a near/medium/long-term roadmap sketch that never got built
Schema matchingMatching strategies (string/structure/instance/semantic-based), the OAEI benchmark landscape, the interlingua/pivot approach (SCF STRM as the N-to-1 hub), NIST OLIR’s formal relationship types, and the SSSOM section — this is the toolbox for the match-pass design
previous_ids frontmatter fieldCORRECTION 2026-08-27: this does NOT exist. The brief previously said it was “already spec’d and shipped”. Verified: zero occurrences of previous_ids in spec/tier1.schema.json and zero in src/. No lineage primitive of any kind is implemented. The real question is therefore not “is one flat field enough for split/merge” but whether a lineage primitive should exist at all, and what shape — a materially different question, and one the answer to must survive the additive-evolution rule
CURIE / ConceptIdentityThe stable-identity primitive a match pass keys off of. Open question this brief must answer: are curies actually stable across publisher versions, or do the publishers themselves rename the compact identifier (CSF’s PR.AC-1→PR.AC-01 is a curie rename, not just a label change)
managed / user_preserve splitThe frontmatter-ownership mechanism a migration’s “apply” phase must respect — user_preserve keys (and, by extension, evidence junction notes and crosswalk edges pointing at a note) must survive regeneration even when the note’s managed fields change underneath
Render report / deviation tracking (shipped 2026-07-05; see repo-root CHANGELOG.md [Unreleased])render()’s optional observational RenderReport — every row that doesn’t fit the recipe pattern is now recorded, not silently dropped. A version migration produces a structurally similar artifact (a change-set); ask whether the same reporting shape (plain-language deviation reasons, per-row detail, UI banner pattern) is the right substrate for a migration’s change-set, not just a parallel bespoke format
Ontology diff primitivesThe mathematical foundation already researched: 9 provably-complete atomic operations over labeled directed graphs (graph edit distance, Bunke 1983; algebraic graph transformation, Ehrig 2006). Add/remove/modify/move/merge/split are named in the lifecycle-arc sketch as “the ontology diff primitives already named in the KB terminology” — verify that claim; the primitives research may or may not actually cover merge/split cleanly
EvolutionPattern taxonomy draft + user-first ontology maintenanceFoundation-phase drafts of a per-framework “how does this ontology evolve” classification and an entity-aligned migration UX. Pre-date render()/recipes/workbench — assess what survives
SSSOM + STRM + SKOS→STRM direction conventionThe committed crosswalk-edge metadata stack (mandatory mapping_justification, optional confidence, predicate vocabulary). The lifecycle-arc sketch’s framing — “a version bump IS a crosswalk v-old→v-new” — proposes treating a migration’s match pass as just another SSSOM mapping set between two versions of the same ontology rather than a bespoke mechanism. Stress-test that framing directly
Shape workbench synthesisAct 1’s shipped review-UI pattern (source rail / mapping canvas / live preview, deviation banner, connectedness mandate, golden-vault + consumer’s-view testing doctrine). The Act 2 sketch explicitly proposes reusing “the workbench pattern again” for the migration review screen — verify what actually transfers vs what a change-set review needs that a column-mapping review doesn’t (e.g., per-change accept/redirect at hundreds-to-thousands of concepts, not dozens of columns)
v0.1.8 — Audit trailThe git-commit-on-write substrate a migration’s “apply” step would log against — relevant to the lineage-storage question
Ch 42: Variable-depth hierarchy generationSibling challenge on ragged/variable depth in render(). Relevant because ATT&CK’s sub-technique migration (T1086 → T1059.001, a structural nesting change, not just a rename) is a split/merge case that also happens to be a depth change — the two challenges may share a worked example
Ontology lifecycleThe five-phase cycle (Acquire → Import → Enrich → Maintain → Share) that Act 2 belongs to; “Maintain” is marked “research complete; implementation planned” — this challenge is input to actually planning it
Archived Ch 09: UUID/CWUUID strategyPredecessor question (“what about renamed/split/merged controls across versions?”) — raised 2026-05-02, resolved only for the identity-scheme layer (UUIDv7 + sha256 CIDs + CURIEs), not for the migration-semantics layer this challenge covers
  1. Match-pass feasibility against real publisher behavior. For each of NIST (CPRT-published CSF/800-53), MITRE ATT&CK (STIX 2.1), and CIS Controls: are curies stable enough for curie-exact match to carry most of the load, or do publishers routinely rename the identifier itself (CSF’s PR.AC-1→PR.AC-01 says no)? Which publishers ship a machine-readable rename/crosswalk table (MITRE’s STIX x_mitre_deprecated/revoked fields + CTID mappings; NIST CPRT’s own crosswalk artifacts) vs which don’t (CIS v7→v8 — Excel or PDF only, per framework-versioning)? Where no table exists, what’s the honest ceiling for SSSOM-style lexical/structural fallback matching (label similarity, hierarchy-position similarity) run in-plugin, TS-only, on mobile — not an OAEI-grade ML matcher?
  2. The two axes of change. Distinguish source-version change (the framework itself changed between v-old and v-new) from recipe change (the same source data, but the user edited how it renders — a workbench mapping edit, a new preset). Does render()’s determinism/Pass-1 hashability give this apart for free — unchanged content hash + changed recipe hash = pure recipe change, no semantic diff needed — or does the system need an explicit signal? What happens when both change at once (re-import v-new with an also-edited recipe)?
  3. Split/merge semantics for evidence reassignment. When a curie splits (ATT&CK’s T1086→T1059.001, nested under a new parent) or merges (CIS’s control consolidation, 20→18), what happens to the artifacts hanging off the old concept — evidence junction notes, user_preserve frontmatter, crosswalk edges pointing at it? Is previous_ids: string[] (already shipped, one-to-many toward the old side) sufficient, or does split/merge need a richer many-to-many lineage shape? Does a “moved concept drags its evidence links along” default make sense, or does split specifically require a forced human choice (which of the N new concepts does the old evidence now belong to)?
  4. Lineage storage. Where does “this note descends from v-old’s AC-2” actually live — an extended previous_ids-style frontmatter field (cheap, but not natively graph-queryable), a sidecar mapping file shaped like an SSSOM mapping set (queryable via the same Tier 2 machinery already built for crosswalks), or graph_edges (schema-reserved, per Ch 22)? Whichever wins, does it compose with the Bases query layer and the audit-trail git substrate, or fight both?
  5. Confidence thresholds + human-in-the-loop UX. The lifecycle-arc sketch proposes reusing “the workbench pattern again” — change-set list + impact preview + per-change accept/redirect. At Act 1 scale that’s dozens of column-mapping decisions; at Act 2 scale a framework update can touch hundreds or thousands of concepts. What’s the actual UX when 95% of changes are high-confidence curie-exact matches that shouldn’t need a click, and 5% are ambiguous splits/merges that must? Where’s the line between “auto-apply” and “block on review,” and who sets it?
  6. Determinism + replayability. Should a migration be replayable/hashable the same way render() is — i.e. does the golden-vault testing doctrine extend to “re-running this migration on the same two source versions produces a byte-identical change-set and a byte-identical vault”? What has to be true of the match pass for that to hold (deterministic tie-breaking on ambiguous matches, not “pick whichever the fuzzy matcher liked best today”)?
  7. Is “a version bump IS a crosswalk” actually true? The lifecycle-arc sketch frames match-pass output as reusable SSSOM machinery (v-old→v-new mapping set, same mapping_justification/confidence envelope as a cross-framework crosswalk). Stress-test this: does a same-ontology version-to-version mapping actually behave like a cross-ontology crosswalk (symmetric, framework-agnostic predicates), or does it need version-specific semantics (e.g., a supersedes/superseded_by predicate that STRM’s 5-relationship vocabulary doesn’t currently name) that would extend, not reuse, the committed STRM + SSSOM stack?
  8. Worked examples over real corpora. At minimum: NIST CSF 1.1→2.0 (id rename + new function added — what does the match pass resolve automatically vs flag?), MITRE ATT&CK’s July 2020 sub-technique migration (T1086→T1059.001 — a split-and-nest, machine-readable via STIX), and CIS Controls v7→v8 (renumbered/consolidated, no machine-readable diff — what’s the fallback when publisher tooling gives you nothing?). For each: what fraction of concepts match cleanly, what fraction need the fallback matcher, what fraction need a human, and does the corpus already exist in this repo (test-vault/Crosswalker Test Data/, the framework corpus) to actually run this rather than reason about it abstractly?
  • A recommended match-pass design (curie-exact primary + explicit fallback tier[s]) or a defensible argument that fallback matching is out of scope for v0.2 and curie-exact + human-review-on-miss is sufficient — with evidence from the worked examples, not assertion.
  • An explicit split/merge evidence-reassignment contract, including whether previous_ids needs a schema extension.
  • A verdict on the source-version-vs-recipe-change distinction: is it free from existing determinism machinery, or does it need a new signal?
  • A lineage-storage recommendation (frontmatter extension vs sidecar vs graph edges) that names its Bases-queryability and audit-trail implications.
  • A verdict on whether match-pass output should extend the SSSOM/STRM stack or needs version-specific predicate semantics.
  • At least two real-corpus worked examples with concrete match/fallback/human-review percentages, not hypothetical framework descriptions.
  • A “wire now (v0.2) vs defer” call on each open question, given the owner’s proposed reframe that Act 2 is v0.2’s headline, not a stretch goal.
  • Assuming publishers provide clean machine-readable rename tables. Only MITRE (STIX) reliably does; NIST is partial (CPRT crosswalk artifacts, mostly Excel-shaped); CIS provides essentially nothing machine-readable. Design for the CIS case, not the MITRE case, or the design is fiction.
  • Building an OAEI-grade ML/embedding-based ontology matcher for v0.2. Breaks commitment #3 (mobile-Obsidian portability, TS in-plugin, small-OSS-contributor pool). SSSOM-style lexical/structural matching with explicit, auditable rules is the ceiling; justify anything beyond it.
  • Conflating internal _crosswalker schema-version migration with source-ontology version migration — see the caution callout at the top. They share vocabulary (“migration,” “version”) but are different problems with different solved-vs-open status.
  • Silent auto-apply of low-confidence matches. The whole point of Act 2 is that the user’s work survives honestly reviewed, not silently reshuffled — echoes the connectedness mandate’s core lesson from Act 1 (silent behavior is the failure mode, not a baseline to preserve).
  • Treating “semantic diff” as one monolithic operation. The sketch already decomposes it into match / impact / review / apply phases — don’t flatten that back down; each phase has different failure modes and different automatability ceilings.
  • Ignoring that this is a mid-vision-not-yet-built area. Ontology evolution and data model resilience already did real thinking here in the Foundation phase (2026-04) — pre-render(), pre-recipe, pre-workbench. Read them before re-deriving SCD Type 2/3 or bitemporal tracking from scratch; the job is to check that vision against what actually shipped, not to ignore it.
  • A concrete, evidence-backed match-pass design (or defensible “curie-exact + human-review is enough for v0.2” verdict) tested against at least the CSF, ATT&CK, and CIS worked examples.
  • Explicit split/merge evidence-reassignment semantics, with a stated verdict on whether previous_ids needs a schema change.
  • A clear answer to whether source-version-change and recipe-change are already distinguishable via existing determinism/hashing machinery.
  • A lineage-storage recommendation compatible with managed/user_preserve, Bases, and the audit trail.
  • An explicit “wire now vs defer to v0.3+” call per open question, given the proposed v0.2-headline framing.