Challenge 43: Version migration — the semantic-diff loop
Why this exists
Section titled “Why this exists”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.
What we already have (read these first)
Section titled “What we already have (read these first)”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.
| Asset | What it gives you |
|---|---|
| Ontology evolution | Read 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 versioning | Publisher-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 resilience | The 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 matching | Matching 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 field | CORRECTION 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 / ConceptIdentity | The 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 split | The 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 primitives | The 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 maintenance | Foundation-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 convention | The 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 synthesis | Act 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 trail | The git-commit-on-write substrate a migration’s “apply” step would log against — relevant to the lineage-storage question |
| Ch 42: Variable-depth hierarchy generation | Sibling 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 lifecycle | The 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 strategy | Predecessor 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 |
What to investigate
Section titled “What to investigate”- 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-01says no)? Which publishers ship a machine-readable rename/crosswalk table (MITRE’s STIXx_mitre_deprecated/revokedfields + 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? - 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)? - 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_preservefrontmatter, crosswalk edges pointing at it? Isprevious_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)? - Lineage storage. Where does “this note descends from v-old’s
AC-2” actually live — an extendedprevious_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), orgraph_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? - 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?
- 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”)? - 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/confidenceenvelope 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., asupersedes/superseded_bypredicate that STRM’s 5-relationship vocabulary doesn’t currently name) that would extend, not reuse, the committed STRM + SSSOM stack? - 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?
Deliverable shape
Section titled “Deliverable shape”- 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_idsneeds 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.
Anti-patterns
Section titled “Anti-patterns”- 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
_crosswalkerschema-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.
Success criteria
Section titled “Success criteria”- 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_idsneeds 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.
Related
Section titled “Related”- Lifecycle-arc thinking-big draft — the workbench synthesis log this challenge’s source sketch sits directly under; the draft itself lives in gitignored
.workspace/per the research-artifact lifecycle convention - Retrieval + finite shapes essence — the deeper “why” the lifecycle arc extends
- Ontology evolution · Framework versioning · Data model resilience · Schema matching — the Foundation-phase prior art this challenge audits against shipped v0.1 architecture
- Ch 42: Variable-depth hierarchy generation — sibling challenge; ATT&CK sub-technique migration is a shared worked example
- Ch 09 (archived): UUID/CWUUID cross-cutting strategy — predecessor question on renamed/split/merged controls, resolved only for identity scheme
- v0.1 schema spec § Schema-version migration policy — the other version-migration problem (see caution callout)
- Terminology: CURIE · managed / user_preserve · Ontology diff primitives
- SSSOM · STRM · SKOS→STRM direction convention
- v0.1.8 — Audit trail — the lineage/apply-phase substrate
- Ontology lifecycle — the Maintain phase this challenge feeds