Skip to content

Commit 19373a2

Browse files
authored
Merge pull request #147 from AdaWorldAPI/claude/v3-substrate-migration-review-o0yoxv
vocab+mint: classid canon:custom half-order flip — canon HIGH / APP-render prefix LOW
2 parents a0c7936 + f7201a5 commit 19373a2

23 files changed

Lines changed: 680 additions & 403 deletions

.claude/board/EPIPHANIES.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@
77
88
---
99

10+
## 2026-07-02 — E-CLASSID-CANON-HIGH-FLIP — the composed classid half-order flips: canon concept HIGH, APP/render prefix LOW
11+
12+
**Status:** FINDING (`[G]`, operator-triggered). Doc-sweep companion to `docs/DISCOVERY-MAP.md` D-CLASSID-CANON-HIGH-FLIP — read that entry for the full ledger; this entry records the same correction in the session-findings log.
13+
14+
**Scope:** the composed 32-bit classid ONLY (`ogar_vocab::app` compose/decompose + every doc/worked example carrying a composed literal). Bare u16 concept ids, `APP_PREFIX` values, the 16-byte GUID key layout, and the HEEL/HIP/TWIG tiers are untouched; already-baked old-order ids stay valid via the legacy registry aliases; consumer repos flip in their own lockstep PRs.
15+
16+
**The trigger:** the operator's `0x07:01::1000` mnemonic — read as `domain:appid::marker` — exposed that the working composed classid stored the APP/render prefix in the **high** u16 and the canonical concept in the **low** u16, backwards from the mnemonic's own read order (domain/concept first, appid second).
17+
18+
**The ruling:** flip the composed order to `classid : u32 = [hi u16: canon concept][lo u16: APP/render prefix]`. `ogar_vocab::app::{render_classid, app_of, concept_of}` flip in lockstep with lance-graph-contract's `CLASSID_ORDER = CanonHigh` (PR #628 there) — `app_of` now reads `classid as u16`, `concept_of` now reads `classid >> 16`. **APP_PREFIX values are unchanged** (`0x0000` Core … `0x0007` Redmine) — only their bit position moves. V3 marker forms move in lockstep (`0x1000_0700``0x0701_1000`; FMA `0x1000_0A01``0x0A01_1000`; CPIC `0x1000_0E00``0x0E01_1000`, appid normalized `:00``:01`). Auth RBAC literals: `0x0000_0B0N``0x0B0N_0000` for N∈{1,2,3,4}.
19+
20+
**Legacy is aliased, never rewritten.** Already-baked/persisted classids in the old order resolve via a read-only legacy registry alias (mint-forward doctrine; RESERVE-DON'T-RECLAIM held throughout). Retirement of the alias path is gated on a corpus proof, never assumed.
21+
22+
**Supersedes, without editing:** D-APPCLASS (`docs/DISCOVERY-MAP.md`, 2026-06-22 — `classid = APP(hi u16) ‖ class(lo u16)`) and the `0x1000_0701` literal in D-OSINT-APPID-NOT-CONCEPT (same-day predecessor, 2026-07-02). Both entries stand as written per the append-only rule; this entry and its DISCOVERY-MAP twin are the correction of record for the half-order going forward.
23+
24+
**Cross-ref:** `docs/DISCOVERY-MAP.md` D-CLASSID-CANON-HIGH-FLIP (canonical ledger entry); the doc-wide sweep landed the same session across `APP-CLASS-CODEBOOK-LAYOUT.md`, `APP-CODEBOOK-MIGRATION-PLAN.md`, `OGAR-CONSUMER-BEST-PRACTICES.md`, `OGAR-TRANSPILE-SUBSTRATE.md`, `OGAR-AS-IR.md`, `SURREAL-AST-TRAP-PREFLIGHT.md`, `NODEGUID-CANON-AUDIT.md`, `FOUNDRY-ODOO-MARS-LENS.md`, `CLASSID-RBAC-KEYSTONE-SPEC.md`, `ODOO-REDMINE-OPENPROJECT-LANDING.md`, `PHILOSOPHY.md`/`PHILOSOPHIE.md`, `README.md`/`README.de.md`, `integration/AR-OGAR-MAILBOX-INTEGRATION-PLAN.md` §7, and this repo's `CLAUDE.md`.
25+
26+
---
27+
1028
## 2026-07-01 — E-OSINT-SUBSTRATE-CONVERGES-PER-SOA — the massive cognitive stack converges into the V3 2+14 tenant SoA; the dedup IS the convergence
1129

1230
**Status:** FRAMING (`[G]` for the shipped crates + the tenant carve + the sole-writer canon E-CE64-MB-4; `[H]` for the convergence *program* — the deltas + baby-step probes P0–P8 are unrun). Operator-framed 2026-07-01 (*"massive codebase massive entropy … the V3 2+14 tenants converge the awareness massively per SoA"*).

CLAUDE.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,17 @@ alignment costs. Until measured: 3×4 stands.
211211
10. `docs/OGAR-TRANSPILE-SUBSTRATE.md`**the power, in one doc.** OGAR
212212
as the bidirectional per-class transpiler: pull-in (`source →
213213
ogar-from-<lang> → ModelGraph → lift + mint → CompiledClass`),
214-
rail-facet addressing (`classid = (APP_PREFIX<<16)|concept`, the 16-byte
215-
`FacetCascade`, cross-app convergence), pull-back (runtime wrapper
216-
contract like `lance-graph-contract`, or codegen emit like
214+
rail-facet addressing (`classid = (concept<<16)|APP_PREFIX`, the
215+
16-byte `FacetCascade`, cross-app convergence), pull-back (runtime
216+
wrapper contract like `lance-graph-contract`, or codegen emit like
217217
`ogar-adapter-surrealql`), and the **85/15 split** (mechanical logic
218218
minted into OGAR; the "impossible" 15% = a per-language adapter +
219219
ClassView + ontological grounding). READ to understand why a consumer
220220
collapses to "a compiler-store caller + adapters, at the cost of an
221-
import." Worked example: `account.move → 0x0002_0202`.
221+
import." Worked example: `account.move → 0x0202_0002`. (Order
222+
flipped 2026-07-02 — canon HIGH / custom LOW; pre-flip docs and
223+
baked data use the legacy order — see `docs/DISCOVERY-MAP.md`
224+
D-CLASSID-CANON-HIGH-FLIP.)
222225
8. `docs/ARCHITECTURAL-DECISIONS-2026-06-04.md` — ADR-001..025
223226
(ADR-026 pending).
224227
9. `.claude/agents/` — the 5+3 hardening pattern (5 research savants +
@@ -241,11 +244,13 @@ alignment costs. Until measured: 3×4 stands.
241244
resolution target:** before authoring consumer code that pulls a
242245
classid, composes a render address, authorizes, or migrates off a
243246
bridge, read `docs/OGAR-CONSUMER-BEST-PRACTICES.md` (the muscle-
244-
memory guide). The hi u16 chooses **render** skin (per-app
245-
ClassView/template), the lo u16 names the **shared concept** (RBAC +
247+
memory guide). The lo u16 chooses **render** skin (per-app
248+
ClassView/template), the hi u16 names the **shared concept** (RBAC +
246249
ontology); **neither half carries behavior** — class-magic
247250
(`ActionDef`+`KausalSpec`) is a property of the Core node the
248-
address resolves to, never of the address.
251+
address resolves to, never of the address. (Order flipped 2026-07-02
252+
— canon HIGH / custom LOW; pre-flip docs and baked data use the
253+
legacy order — see `docs/DISCOVERY-MAP.md` D-CLASSID-CANON-HIGH-FLIP.)
249254
- **PII:** never emit German PII labels (medcare-rs leaf-rename at the
250255
adapter is the guarantee). Word-boundary abort-guard before commit.
251256
- **No model identifier** in any committed artifact (chat only).

README.de.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,24 @@ Das [Active-Record-Muster](https://martinfowler.com/eaaCatalog/activeRecord.html
88
(Martin Fowler, 2003) als kanonische 32-Bit-`classid`. Ein Codebook;
99
jeder Consumer zieht, prägt niemals neu.
1010

11+
> Reihenfolge geflippt 2026-07-02 — Kanon HOCH / App-eigen NIEDRIG: das
12+
> kanonische Konzept sitzt im hohen u16, der App-Render-Präfix im
13+
> niedrigen u16. Material von vor dem Flip und bereits gebackene Daten
14+
> nutzen die alte Reihenfolge; siehe `docs/DISCOVERY-MAP.md`
15+
> D-CLASSID-CANON-HIGH-FLIP.
16+
1117
```rust
1218
let cid: u16 = HealthcarePort::class_id("Patient"); // 0x0901
13-
let render = HealthcarePort::APP_PREFIX | (cid as u32); // 0x0005_0901
14-
authorize(actor, cid, Op::Read); // geteilter Grant auf lo u16
19+
let render = ((cid as u32) << 16) | HealthcarePort::APP_PREFIX; // 0x0901_0005
20+
authorize(actor, cid, Op::Read); // geteilter Grant auf hi u16
1521
// // lokal anreichern — deins
1622
```
1723

1824
```
19-
classid : u32 = 0xAAAA0xDDCC beide Hälften sind ADRESSE
25+
classid : u32 = 0xDDCC0xAAAA beide Hälften sind ADRESSE
2026
│ │
21-
│ └─ lo u16 — WELCHES KONZEPT (geteilte Identität)
22-
└─────────── hi u16 — WESSEN RENDER (App-eigene Haut)
27+
│ └─ lo u16 — WESSEN RENDER (App-eigene Haut)
28+
└─────────── hi u16 — WELCHES KONZEPT (geteilte Identität)
2329
2430
──────► löst auf zu ──────►
2531
├─ ClassView die HAUT (pro App)
@@ -49,16 +55,16 @@ Prisma — gleiches Vokabular, ein IR.
4955

5056
## Render-Linse — ein Konzept, viele Apps
5157

52-
| classid | Konzept (lo u16) | Render (hi u16) | App |
58+
| classid | Konzept (hi u16) | Render (lo u16) | App |
5359
|---------------|-----------------------------|--------------------------|----------------------|
54-
| `0x0001_0102` | `0x0102` project_work_item | `0x0001` OpenProject | openproject-nexgen-rs |
55-
| `0x0007_0102` | `0x0102` project_work_item | `0x0007` Redmine | (Consumer TBD) |
56-
| `0x0005_0901` | `0x0901` patient | `0x0005` Medcare | medcare-rs |
57-
| `0x0003_0103` | `0x0103` billable_work_entry | `0x0003` WoA | woa-rs |
58-
| `0x0004_0103` | `0x0103` billable_work_entry | `0x0004` SMB | smb-office-rs |
59-
| `0x0001_0103` | `0x0103` billable_work_entry | `0x0001` OpenProject | openproject-nexgen-rs |
60-
| `0x0007_0103` | `0x0103` billable_work_entry | `0x0007` Redmine | (Consumer TBD) |
61-
| `0x0002_0103` | `0x0103` billable_work_entry | `0x0002` Odoo | odoo-rs |
60+
| `0x0102_0001` | `0x0102` project_work_item | `0x0001` OpenProject | openproject-nexgen-rs |
61+
| `0x0102_0007` | `0x0102` project_work_item | `0x0007` Redmine | (Consumer TBD) |
62+
| `0x0901_0005` | `0x0901` patient | `0x0005` Medcare | medcare-rs |
63+
| `0x0103_0003` | `0x0103` billable_work_entry | `0x0003` WoA | woa-rs |
64+
| `0x0103_0004` | `0x0103` billable_work_entry | `0x0004` SMB | smb-office-rs |
65+
| `0x0103_0001` | `0x0103` billable_work_entry | `0x0001` OpenProject | openproject-nexgen-rs |
66+
| `0x0103_0007` | `0x0103` billable_work_entry | `0x0007` Redmine | (Consumer TBD) |
67+
| `0x0103_0002` | `0x0103` billable_work_entry | `0x0002` Odoo | odoo-rs |
6268

6369
Gleiche `0x0103` → gleicher RBAC-Grant, gleiche Ontologie, gleiche
6470
Cross-Fork-Identität. Fünf Apps rendern *abrechenbare Zeit* auf fünf
@@ -70,7 +76,7 @@ Arten; Planer-Stunden stimmen mit der Abrechnung per Codebook-Lookup
7076
| Zug | Aufruf | Deiner? |
7177
|-----------|--------------------------------------------|-----------|
7278
| pull | `Port::class_id(name) -> Option<u16>` | nein — reine Funktion |
73-
| render | `Port::APP_PREFIX \| (cid as u32)` | nein — typisierter Helfer |
79+
| render | `((cid as u32) << 16) \| Port::APP_PREFIX` | nein — typisierter Helfer |
7480
| authorize | `authorize(actor, cid, op)` ² | nein — geteiltes Grant-Gitter |
7581
| enrich | deine Domänen-Logik, an `cid` verschlüsselt | **ja** |
7682

README.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,23 @@ The [Active Record pattern](https://martinfowler.com/eaaCatalog/activeRecord.htm
88
(Martin Fowler, 2003) as a canonical 32-bit `classid`. One codebook;
99
every consumer pulls, never re-mints.
1010

11+
> Order flipped 2026-07-02 — canon HIGH / custom LOW: the canonical
12+
> concept sits in the high u16, the per-app render prefix sits in the
13+
> low u16. Pre-flip material and already-baked data use the legacy
14+
> order; see `docs/DISCOVERY-MAP.md` D-CLASSID-CANON-HIGH-FLIP.
15+
1116
```rust
1217
let cid: u16 = HealthcarePort::class_id("Patient"); // 0x0901
13-
let render = HealthcarePort::APP_PREFIX | (cid as u32); // 0x0005_0901
14-
authorize(actor, cid, Op::Read); // shared grant on lo u16
18+
let render = ((cid as u32) << 16) | HealthcarePort::APP_PREFIX; // 0x0901_0005
19+
authorize(actor, cid, Op::Read); // shared grant on hi u16
1520
// // enrich locally — yours
1621
```
1722

1823
```
19-
classid : u32 = 0xAAAA0xDDCC both halves are ADDRESS
24+
classid : u32 = 0xDDCC0xAAAA both halves are ADDRESS
2025
│ │
21-
│ └─ lo u16 — WHICH CONCEPT (shared identity)
22-
└─────────── hi u16 — WHOSE RENDER (per-app skin)
26+
│ └─ lo u16 — WHOSE RENDER (per-app skin)
27+
└─────────── hi u16 — WHICH CONCEPT (shared identity)
2328
2429
──────► resolves to ──────►
2530
├─ ClassView the SKIN (per-app)
@@ -49,16 +54,16 @@ Django, Prisma — same vocabulary, one IR.
4954

5055
## Render lens — one concept, many apps
5156

52-
| classid | concept (lo u16) | render (hi u16) | app |
57+
| classid | concept (hi u16) | render (lo u16) | app |
5358
|---------------|-----------------------------|--------------------------|----------------------|
54-
| `0x0001_0102` | `0x0102` project_work_item | `0x0001` OpenProject | openproject-nexgen-rs |
55-
| `0x0007_0102` | `0x0102` project_work_item | `0x0007` Redmine | (consumer TBD) |
56-
| `0x0005_0901` | `0x0901` patient | `0x0005` Medcare | medcare-rs |
57-
| `0x0003_0103` | `0x0103` billable_work_entry | `0x0003` WoA | woa-rs |
58-
| `0x0004_0103` | `0x0103` billable_work_entry | `0x0004` SMB | smb-office-rs |
59-
| `0x0001_0103` | `0x0103` billable_work_entry | `0x0001` OpenProject | openproject-nexgen-rs |
60-
| `0x0007_0103` | `0x0103` billable_work_entry | `0x0007` Redmine | (consumer TBD) |
61-
| `0x0002_0103` | `0x0103` billable_work_entry | `0x0002` Odoo | odoo-rs |
59+
| `0x0102_0001` | `0x0102` project_work_item | `0x0001` OpenProject | openproject-nexgen-rs |
60+
| `0x0102_0007` | `0x0102` project_work_item | `0x0007` Redmine | (consumer TBD) |
61+
| `0x0901_0005` | `0x0901` patient | `0x0005` Medcare | medcare-rs |
62+
| `0x0103_0003` | `0x0103` billable_work_entry | `0x0003` WoA | woa-rs |
63+
| `0x0103_0004` | `0x0103` billable_work_entry | `0x0004` SMB | smb-office-rs |
64+
| `0x0103_0001` | `0x0103` billable_work_entry | `0x0001` OpenProject | openproject-nexgen-rs |
65+
| `0x0103_0007` | `0x0103` billable_work_entry | `0x0007` Redmine | (consumer TBD) |
66+
| `0x0103_0002` | `0x0103` billable_work_entry | `0x0002` Odoo | odoo-rs |
6267

6368
Same `0x0103` → same RBAC grant, same ontology, same cross-fork
6469
identity. Five apps render *billable time* five ways; planner hours
@@ -69,7 +74,7 @@ align with billing by codebook lookup, not translation.
6974
| Move | Call | Yours? |
7075
|-----------|--------------------------------------------|-----------|
7176
| pull | `Port::class_id(name) -> Option<u16>` | no — pure function |
72-
| render | `Port::APP_PREFIX \| (cid as u32)` | no — typed helper |
77+
| render | `((cid as u32) << 16) \| Port::APP_PREFIX` | no — typed helper |
7378
| authorize | `authorize(actor, cid, op)` ² | no — shared grant lattice |
7479
| enrich | your domain logic keyed on `cid` | **yes** |
7580

0 commit comments

Comments
 (0)