From 2dd458ec8254702a5e962d22f6ab6f8acf947f16 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 13:12:13 +0000 Subject: [PATCH] chore(op-canon): drop Member/Membership drift pin after OGAR #113 merged MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OGAR PR #113 (merged) added `("Member", PROJECT_MEMBERSHIP)` to OPENPROJECT_ALIASES alongside the existing `Membership` alias. The `port_and_snapshot_membership_vocab_mismatch_is_known` test I pinned in #56 was deliberately self-flipping: it asserted `class_id_of("Member") == None` so it'd fail the moment OGAR aligned the alias to the corpus name — forcing the next session to come back and drop the pin. That trigger fired; this is that drop. Replaces the pin with the successor positive assertion `member_and_membership_both_resolve_after_ogar_113`: - `class_id_of("Member")` → Some(PROJECT_MEMBERSHIP) (OGAR #113) - `class_id_of("Membership")` → Some(PROJECT_MEMBERSHIP) (kept synonym) - both equal each other → no vocab drift between OP corpus + port The overlap drift guard (`port_pull_agrees_with_the_snapshot`) now covers `Member` too — no silent skip on that name anymore. Lockfile: `cargo update -p ogar-vocab` → OGAR main @ 991450a (post-#113). cargo +1.95 test -p op-canon → 19 unit + 5 doctests pass (was 19+5; same count — same number of tests, just the membership one renamed to its positive successor). fmt + clippy --all-targets -- -D warnings clean. --- Cargo.lock | 8 ++++---- crates/op-canon/src/app.rs | 42 ++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05ebe09..270df11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1210,7 +1210,7 @@ version = "0.1.0" [[package]] name = "lance-graph-contract" version = "0.1.0" -source = "git+https://github.com/AdaWorldAPI/lance-graph?branch=main#d1a311ea4297594bb069f57f3c48b1aeb6be2484" +source = "git+https://github.com/AdaWorldAPI/lance-graph?branch=main#d8a59a44ccafdff107b1ca370f38da0b1252938c" dependencies = [ "glob", "serde", @@ -1504,7 +1504,7 @@ dependencies = [ [[package]] name = "ogar-class-view" version = "0.1.0" -source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#273fa7863ace43ac6089c3e1a5f29c89afe01471" +source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#991450a0dead2a2066239f31ee668927d8e63364" dependencies = [ "lance-graph-contract 0.1.0 (git+https://github.com/AdaWorldAPI/lance-graph?branch=main)", "ogar-vocab", @@ -1513,7 +1513,7 @@ dependencies = [ [[package]] name = "ogar-render-askama" version = "0.1.0" -source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#273fa7863ace43ac6089c3e1a5f29c89afe01471" +source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#991450a0dead2a2066239f31ee668927d8e63364" dependencies = [ "askama", "ogar-vocab", @@ -1522,7 +1522,7 @@ dependencies = [ [[package]] name = "ogar-vocab" version = "0.1.0" -source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#273fa7863ace43ac6089c3e1a5f29c89afe01471" +source = "git+https://github.com/AdaWorldAPI/OGAR?branch=main#991450a0dead2a2066239f31ee668927d8e63364" [[package]] name = "once_cell" diff --git a/crates/op-canon/src/app.rs b/crates/op-canon/src/app.rs index 8751182..7de3cd6 100644 --- a/crates/op-canon/src/app.rs +++ b/crates/op-canon/src/app.rs @@ -241,36 +241,34 @@ mod tests { ); } - /// Pins the one snapshot↔port vocabulary divergence the overlap guard - /// silently skips (flagged by the 5+3 review, R4 + B1): the OpenProject - /// corpus snapshot carries **`Member`** for `project_membership` (0x0108), - /// but `OPENPROJECT_ALIASES` aliases that concept under **`Membership`**. - /// So `class_id_of("Member")` is `None` today and the drift guard skips it. - /// - /// This test makes the divergence VISIBLE and tracked: when OGAR aligns - /// the alias to the corpus name (`Member`), this test flips and reminds us - /// to drop the pin. (The OGAR-side fix is the proper resolution; here we - /// only document the current state so it can't hide.) + /// **Closes** the previously-pinned `port_and_snapshot_membership_vocab_mismatch_is_known` + /// drift guard — its trigger fired on OGAR `main` after PR #113 (the + /// Member alias add). Now `class_id_of("Member")` and + /// `class_id_of("Membership")` BOTH resolve to `PROJECT_MEMBERSHIP`: + /// the port matches the OpenProject corpus snapshot (`Member`) AND + /// keeps the deprecated synonym (`Membership`) for any consumer + /// holding the old name. The vocab divergence is gone; this is the + /// successor positive assertion. #[test] - fn port_and_snapshot_membership_vocab_mismatch_is_known() { + fn member_and_membership_both_resolve_after_ogar_113() { let s = Snapshot::load(); let membership = s .concept("project_membership") .expect("snapshot carries project_membership"); + // Snapshot uses `Member` — that's the OP corpus name. assert!( membership.curator_classes.iter().any(|c| c == "Member"), - "snapshot is expected to carry `Member` for project_membership; saw {:?}", + "snapshot expected to carry `Member` for project_membership; saw {:?}", membership.curator_classes, ); - // KNOWN GAP: the port aliases this concept as `Membership`, not `Member`. - assert_eq!( - class_id_of("Member"), - None, - "if this is now Some(_), OGAR aligned the alias to the corpus name — \ - update the OPENPROJECT_ALIASES follow-up and remove this pin", - ); - // The port DOES resolve `Membership` to the same concept id, so the - // concept itself converges; only the surface spelling differs. - assert_eq!(class_id_of("Membership"), Some(membership.class_id_u16())); + // Both surface names now pull the same canonical id (OGAR #113): + // - `Member` — canonical, matches the corpus + Redmine + // - `Membership` — deprecated synonym kept for backcompat + // So the overlap drift guard above now covers `Member` too (no + // silent skip), and the cross-port convergence is byte-symmetric: + // OP `Member` ↔ RM `Member` → 0x0108. + let target = Some(membership.class_id_u16()); + assert_eq!(class_id_of("Member"), target); + assert_eq!(class_id_of("Membership"), target); } }