Skip to content

Commit 4e31f7f

Browse files
committed
chore: canon-HIGH flip integration — merge main (#68), sync vendors, banner stale docs
Merges origin/main (PR #68: op-canon literals flipped to canon-HIGH) — clean merge, zero conflicts with this branch's 12 commits. Syncs the vendor mirrors to the lockstep upstream state: lance-graph-contract @ post-#628 (7 modules changed; ClassidOrder::CanonHigh + compose/ decompose + mint-forward legacy reader live in ogar_codebook; C6 RouteBucketTyped diff re-applied cleanly — still absent upstream) and ogar-vocab @ post-#147 (class‖APP composition flipped in app.rs; the mistakenly-added reified person-profiling surface is REMOVED upstream and now removed here — only upstream's slot-history comment remains per RESERVE-DON'T-RECLAIM). ogar-class-view re-synced with the recorded path deviation re-applied. Full workspace green post-merge+sync (op-canon's gated flip now compiles against the flipped vocab). Sweep: nexgen src literals all canon-HIGH; the 2026-06-30 convergence handover carried PRE-FLIP examples inline including a work-recipe — bannered as historical with pointer to the flip doc so stale bit-math can't be copied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY
1 parent 533ecf1 commit 4e31f7f

11 files changed

Lines changed: 1285 additions & 411 deletions

File tree

.claude/handovers/2026-06-30-1200-op-redmine-ogar-convergence-assessment.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
# Handover — OP + Redmine → OGAR convergence (assessment + increment plan)
2+
> **⚠ HISTORICAL CLASSID ORDER.** Every u32 classid example in this document
3+
> uses the PRE-FLIP order (`APP prefix HIGH / canon LOW`, e.g.
4+
> `0x0001_0102`). As of 2026-07-02 the canonical order is **canon HIGH /
5+
> prefix LOW** (`0x0102_0001`) — see
6+
> `2026-07-02-classid-canon-high-flip.md` and
7+
> `lance_graph_contract::ogar_codebook::ClassidOrder::CanonHigh`. Flip any
8+
> literal you copy from here, including the §"next step" test expectations.
9+
210

311
> 2026-06-30. Captures a grounded 6-agent assessment (1.04M tokens) of
412
> converging OpenProject + Redmine onto the OGAR transpile / ClassView

vendor/AdaWorldAPI-OGAR/crates/ogar-class-view/src/lib.rs

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,74 @@ use lance_graph_contract::{
6464
ontology::{DisplayTemplate, FieldRef, ObjectView},
6565
};
6666
use ogar_vocab::{
67+
Class,
68+
accounting_account,
6769
// 0x0CXX — automation (HIRO MARS CMDB + DO-arm actuators)
68-
action_applicability, Class,
69-
accounting_account, action_handler, anatomical_structure, auth_ory_keto, auth_store,
70-
auth_zanzibar, auth_zitadel, automation_trigger, billable_work_entry, billing_party, bone,
71-
canonical_concept_id, commercial_document, commercial_line_item, currency_policy, diagnosis,
72-
hr_department, hr_employee, hr_employment_contract, hr_job, joint, knowledge_item, lab_value,
73-
mars_application, mars_machine, mars_node_template, mars_resource, mars_software, medication,
74-
osint_person, osint_system, patient, payment_record, pricelist, pricelist_rule, priority,
75-
product, project, project_actor,
76-
project_attachment, project_changeset, project_comment, project_custom_field,
77-
project_custom_value, project_enabled_module, project_forum, project_journal,
78-
project_member_role, project_membership, project_message, project_news, project_query,
79-
project_relation, project_repository, project_role, project_status, project_type,
80-
project_version, project_watcher, project_wiki_page, project_work_item, skeleton, tax_policy,
81-
treatment, unit_of_measure, visit, vital_sign,
70+
action_applicability,
71+
action_handler,
72+
anatomical_structure,
73+
auth_ory_keto,
74+
auth_store,
75+
auth_zanzibar,
76+
auth_zitadel,
77+
automation_trigger,
78+
billable_work_entry,
79+
billing_party,
80+
bone,
81+
canonical_concept_id,
82+
commercial_document,
83+
commercial_line_item,
84+
currency_policy,
85+
diagnosis,
86+
hr_department,
87+
hr_employee,
88+
hr_employment_contract,
89+
hr_job,
90+
joint,
91+
knowledge_item,
92+
lab_value,
93+
mars_application,
94+
mars_machine,
95+
mars_node_template,
96+
mars_resource,
97+
mars_software,
98+
medication,
99+
patient,
100+
payment_record,
101+
pricelist,
102+
pricelist_rule,
103+
priority,
104+
product,
105+
project,
106+
project_actor,
107+
project_attachment,
108+
project_changeset,
109+
project_comment,
110+
project_custom_field,
111+
project_custom_value,
112+
project_enabled_module,
113+
project_forum,
114+
project_journal,
115+
project_member_role,
116+
project_membership,
117+
project_message,
118+
project_news,
119+
project_query,
120+
project_relation,
121+
project_repository,
122+
project_role,
123+
project_status,
124+
project_type,
125+
project_version,
126+
project_watcher,
127+
project_wiki_page,
128+
project_work_item,
129+
skeleton,
130+
tax_policy,
131+
treatment,
132+
unit_of_measure,
133+
visit,
134+
vital_sign,
82135
};
83136

84137
/// All promoted canonical concepts: `(canonical_concept_name, Class)`.
@@ -128,9 +181,6 @@ fn all_canonical_classes() -> Vec<(&'static str, Class)> {
128181
("pricelist", pricelist()),
129182
("pricelist_rule", pricelist_rule()),
130183
("unit_of_measure", unit_of_measure()),
131-
// ── 0x07XX — OSINT (AIRO/AIwar dual-use intelligence) ──
132-
("osint_system", osint_system()),
133-
("osint_person", osint_person()),
134184
// ── 0x09XX — health (OGIT Healthcare) ──
135185
("patient", patient()),
136186
("diagnosis", diagnosis()),

vendor/AdaWorldAPI-OGAR/crates/ogar-vocab/src/app.rs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,76 @@
1-
//! **APP‖class composition** — the high-u16 render-prefix machinery
1+
//! **class‖APP composition** — the render-prefix machinery
22
//! (`docs/APP-CLASS-CODEBOOK-LAYOUT.md` §0, §4).
33
//!
4-
//! A full 32-bit `classid` is two orthogonal halves:
4+
//! A full 32-bit `classid` is two orthogonal halves. Since the 2026-07-02
5+
//! canon:custom half-order flip (lance-graph
6+
//! `classid-canon-custom-flip-v1.md` P1/P2 — the operator's `0x07:01::1000`
7+
//! ruling), the CANON concept sits HIGH and the APP/render prefix LOW:
58
//!
69
//! ```text
7-
//! classid : u32 = [ hi u16 : APP / render prefix ] [ lo u16 : concept ]
8-
//! 0xAAAA (per-app ClassView lens) 0xDDCC (shared RBAC+ontology)
10+
//! classid : u32 = [ hi u16 : CANON concept ] [ lo u16 : APP / render prefix ]
11+
//! 0xDDCC (shared RBAC+ontology) 0xAAAA (per-app ClassView lens)
912
//! ```
1013
//!
1114
//! The per-port reserved prefix is [`PortSpec::APP_PREFIX`] (the §2 allocation
12-
//! table as typed data); this module composes and decomposes the full id so
13-
//! consumers re-export ONE source of the bit math instead of each
14-
//! re-implementing `(prefix << 16) | concept`. `0x0000` is the shared
15-
//! canonical core (every existing id is `0x0000_DDCC` — additive, invariant
16-
//! I-APP1).
15+
//! table as typed data; the prefix VALUES are order-invariant); this module
16+
//! composes and decomposes the full id so consumers re-export ONE source of
17+
//! the bit math instead of each re-implementing
18+
//! `((concept as u32) << 16) | prefix`. `0x0000` is the shared canonical core
19+
//! (every existing id renders under the core lens as `0xDDCC_0000` —
20+
//! additive, invariant I-APP1). Pre-flip stored ids (`0x0000_DDCC` /
21+
//! `0xAAAA_DDCC`) are the LEGACY order — readers of persisted data resolve
22+
//! them through concrete legacy-alias registry keys, never by
23+
//! reinterpreting the halves (mint-forward).
1724
//!
18-
//! Composing the high half is **reserving/stamping**, not minting a class_id
19-
//! (§2: "reserving costs nothing") — concept (low-u16) mints stay gated on the
20-
//! 5+3 codebook pass. The low half is the cross-app currency: concept/domain
21-
//! routing reads it alone (`lance_graph_contract::classid_concept_domain`
22-
//! does `… as u16`), so it is identical under every render prefix.
25+
//! Composing the prefix half is **reserving/stamping**, not minting a class_id
26+
//! (§2: "reserving costs nothing") — concept mints stay gated on the
27+
//! 5+3 codebook pass. The concept half is the cross-app currency:
28+
//! concept/domain routing reads it alone (`lance_graph_contract::
29+
//! classid_concept_domain` routes the canon half), so it is identical under
30+
//! every render prefix.
2331
2432
use crate::ports::PortSpec;
2533

26-
/// Compose a full render `classid` from an app `prefix` (high u16) and a
27-
/// canonical `concept` id (low u16): `(prefix << 16) | concept`.
34+
/// Compose a full render `classid` from an app `prefix` (CUSTOM half, low
35+
/// u16) and a canonical `concept` id (CANON half, high u16):
36+
/// `((concept as u32) << 16) | prefix`.
2837
///
29-
/// `render_classid(0x0001, 0x0102)` → `0x0001_0102` (OpenProject's
38+
/// `render_classid(0x0001, 0x0102)` → `0x0102_0001` (OpenProject's
3039
/// `project_work_item`); the Redmine twin `render_classid(0x0007, 0x0102)` →
31-
/// `0x0007_0102` — same concept, different render lens.
40+
/// `0x0102_0007` — same concept, different render lens.
3241
#[must_use]
3342
pub const fn render_classid(prefix: u16, concept: u16) -> u32 {
34-
((prefix as u32) << 16) | (concept as u32)
43+
((concept as u32) << 16) | (prefix as u32)
3544
}
3645

3746
/// Compose a render `classid` for a specific port, reading its reserved
3847
/// [`PortSpec::APP_PREFIX`]: `render_classid_for::<OpenProjectPort>(concept)`
39-
/// → `0x0001_DDCC`. This is the helper consumers call so the prefix and the
48+
/// → `0xDDCC_0001`. This is the helper consumers call so the prefix and the
4049
/// bit math both come from OGAR (one source of truth), not a local literal.
4150
#[must_use]
4251
pub fn render_classid_for<P: PortSpec>(concept: u16) -> u32 {
4352
render_classid(P::APP_PREFIX, concept)
4453
}
4554

46-
/// The APP / render prefix — the **high u16** of a full `classid`. `0x0000`
47-
/// ([the shared core]) is the abstract/default-`ClassView` anchor; a non-zero
48-
/// value selects an app's render lens. This is the §4 `resolve_codebook`
49-
/// routing key (`classid >> 16`).
55+
/// The APP / render prefix — the CUSTOM half (**low u16** since the flip) of
56+
/// a full `classid`. `0x0000` ([the shared core]) is the
57+
/// abstract/default-`ClassView` anchor; a non-zero value selects an app's
58+
/// render lens. This is the §4 `resolve_codebook` routing key
59+
/// (`classid as u16`).
5060
///
5161
/// [the shared core]: PortSpec::APP_PREFIX
5262
#[must_use]
5363
pub const fn app_of(classid: u32) -> u16 {
54-
(classid >> 16) as u16
64+
classid as u16
5565
}
5666

57-
/// The canonical concept id — the **low u16** of a full `classid`. The shared
58-
/// RBAC + ontology + cross-app identity key; concept/domain routing reads only
59-
/// this half, so it is identical for every render prefix.
67+
/// The canonical concept id — the CANON half (**high u16** since the flip) of
68+
/// a full `classid`. The shared RBAC + ontology + cross-app identity key;
69+
/// concept/domain routing reads only this half, so it is identical for every
70+
/// render prefix.
6071
#[must_use]
6172
pub const fn concept_of(classid: u32) -> u16 {
62-
classid as u16
73+
(classid >> 16) as u16
6374
}
6475

6576
#[cfg(test)]
@@ -70,9 +81,10 @@ mod tests {
7081

7182
#[test]
7283
fn render_classid_composes_the_two_halves() {
73-
assert_eq!(render_classid(0x0001, 0x0102), 0x0001_0102);
74-
assert_eq!(render_classid(0x0007, 0x0102), 0x0007_0102);
75-
assert_eq!(render_classid(0x0002, 0x0202), 0x0002_0202);
84+
// Canon-high order (2026-07-02 flip): concept HIGH, prefix LOW.
85+
assert_eq!(render_classid(0x0001, 0x0102), 0x0102_0001);
86+
assert_eq!(render_classid(0x0007, 0x0102), 0x0102_0007);
87+
assert_eq!(render_classid(0x0002, 0x0202), 0x0202_0002);
7688
}
7789

7890
#[test]
@@ -81,22 +93,22 @@ mod tests {
8193
// under different prefixes — "two renders, one concept" (§1).
8294
assert_eq!(
8395
render_classid_for::<OpenProjectPort>(class_ids::PROJECT_WORK_ITEM),
84-
0x0001_0102,
96+
0x0102_0001,
8597
);
8698
assert_eq!(
8799
render_classid_for::<RedminePort>(class_ids::PROJECT_WORK_ITEM),
88-
0x0007_0102,
100+
0x0102_0007,
89101
);
90102
assert_eq!(
91103
render_classid_for::<OdooPort>(class_ids::COMMERCIAL_DOCUMENT),
92-
0x0002_0202,
104+
0x0202_0002,
93105
);
94106
}
95107

96108
#[test]
97109
fn app_of_and_concept_of_decompose() {
98110
let cid = render_classid(0x0005, class_ids::PATIENT); // Medcare patient
99-
assert_eq!(cid, 0x0005_0901);
111+
assert_eq!(cid, 0x0901_0005);
100112
assert_eq!(app_of(cid), 0x0005);
101113
assert_eq!(concept_of(cid), class_ids::PATIENT);
102114
}
@@ -119,18 +131,19 @@ mod tests {
119131

120132
#[test]
121133
fn core_prefix_is_additive_and_bit_identical() {
122-
// I-APP1/I-APP5: a core (hi=0x0000) classid equals the bare concept
123-
// widened to u32 — no renumber, no version cost.
134+
// I-APP1/I-APP5 (post-flip form): a core (prefix=0x0000) classid is
135+
// the bare concept in the CANON (high) half — no renumber, no version
136+
// cost; `concept_of` recovers it exactly.
124137
let core = render_classid(0x0000, class_ids::PROJECT_WORK_ITEM);
125-
assert_eq!(core, 0x0000_0102);
126-
assert_eq!(core, u32::from(class_ids::PROJECT_WORK_ITEM));
138+
assert_eq!(core, 0x0102_0000);
139+
assert_eq!(core, u32::from(class_ids::PROJECT_WORK_ITEM) << 16);
127140
assert_eq!(app_of(core), 0x0000);
128141
assert_eq!(concept_of(core), class_ids::PROJECT_WORK_ITEM);
129142
}
130143

131144
#[test]
132145
fn render_prefix_never_changes_the_concept_half() {
133-
// The high half is the render lens; it must not perturb the low-half
146+
// The prefix half is the render lens; it must not perturb the CANON
134147
// concept that RBAC + ontology key on.
135148
let op = render_classid_for::<OpenProjectPort>(class_ids::BILLABLE_WORK_ENTRY);
136149
let rm = render_classid_for::<RedminePort>(class_ids::BILLABLE_WORK_ENTRY);

0 commit comments

Comments
 (0)