From 53939ab8d038a99ae1dadb4408e74f2f1679a036 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 22:28:04 +0000 Subject: [PATCH 1/2] soa_config: rescope the classid low-half doc to one named pattern, drop a stale citation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The doc comment landed in #909 overgeneralized in two ways an operator correction caught after merge: - It cited "the zero-fallback ladder (CLAUDE.md, locked 2026-06-13)" as live justification. This repo's dev cycle is two weeks; a doc locked a month-plus back, spanning the 2026-07-02 classid canon-high flip, is not something to cite as current authority. Replaced with a plain statement of what this parser actually does (nothing — it neither enforces nor relies on any reading of a zero half). - It presented "low half + FieldMask = CSS-style screen-region addressing" as classid's general meaning. That is one rendering pattern's reading — MedCare-rs's Redmine-style QueryColumn fieldview (crates/medcare-server/src/views/fieldview.rs) — not a property of classids or ClassView in general. Classes are not only for display; routing, storage, RBAC, and action dispatch are classid consumers too, each free to read the low half differently. Made the domain-dependence concrete with a same-bit-pattern example: 0xFFFF is a defined sentinel (Unassigned) in the ontology/concept domain per ogar_codebook::canonical_concept_domain, and carries no such meaning outside it. The parser's own behavior is unchanged — still purely structural (0x-prefixed hex fitting u32) — only the doc comment's claims about what it does or doesn't imply are corrected. Also corrected PR #909's merged description, which repeated the same two claims. Gate: 17/17 soa_config (including the shipped-example cross-check against the edited YAML) · clippy clean · fmt clean. --- .../examples/soa-config.example.yaml | 35 ++++++---- crates/lance-graph/src/soa_config.rs | 68 +++++++++---------- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/crates/lance-graph/examples/soa-config.example.yaml b/crates/lance-graph/examples/soa-config.example.yaml index 981bbbe4..9f860c80 100644 --- a/crates/lance-graph/examples/soa-config.example.yaml +++ b/crates/lance-graph/examples/soa-config.example.yaml @@ -106,22 +106,31 @@ bakes: # concept 0xDDCC, domain in the top byte, so # classids sort/prefix-search by hierarchy. # - # The LOW half is NOT padding — it carries the - # app/render half: ClassView + WideFieldMask - # ergonomics and slot-schema switching. - # "0x0000" means "no app skin" — one legal - # value among many, and a slot a consumer - # FILLS (e.g. a session writing an ontology - # routing value there). A config carrying - # ...0000 declares the slot UNSET, not - # meaningless. + # The LOW half is NOT padding — it is a slot a + # DOMAIN-SPECIFIC CONSUMER fills, and what + # filling it means depends on which consumer is + # reading it, not on this file or this parser. + # The same bit pattern means different things + # in different domains: in the ontology/concept + # domain, 0xFFFF is a defined sentinel + # (ogar_codebook::canonical_concept_domain + # resolves it to Unassigned); in MedCare-rs's + # list-view rendering (the Redmine QueryColumn + # pattern), the low half instead selects a + # ClassView template and a field mask picks + # which columns show — a reading local to that + # ONE rendering pattern, not a general truth + # about classids. Classes are not only for + # display — routing, storage, RBAC, and action + # dispatch are classid consumers too, each free + # to read the low half differently, or not at + # all. Ask the consuming domain, not this file. # # The parser checks only that this is # 0x-prefixed hex fitting u32. It deliberately - # does NOT police the halves — a zero canon is - # a legal dormant state (zero-fallback ladder) - # and pre-flip forms are read via - # classid_canon_compat. + # does NOT police, consult, or assign meaning + # to either half; pre-flip stored forms are + # left for classid_canon_compat to read. # (An earlier draft of this file used 0x0D01 # for an "ontology" bake. 0x0D01 is real — it # is `hr_employee` in the HR domain. That is diff --git a/crates/lance-graph/src/soa_config.rs b/crates/lance-graph/src/soa_config.rs index 0c0d9be8..77957c13 100644 --- a/crates/lance-graph/src/soa_config.rs +++ b/crates/lance-graph/src/soa_config.rs @@ -109,40 +109,37 @@ pub struct BakeEntry { /// most-significant byte, which is what makes classids sort and /// prefix-search hierarchically. **Read the left bytes to route.** /// - /// The LOW half is not padding: it carries the app/render half — - /// `ClassView` + `WideFieldMask` ergonomics and slot-schema switching. - /// `0x0000` there means "no app skin", one legal value among many, and - /// it is a slot a consumer FILLS — e.g. a session writing an ontology - /// routing value into it. So a config carrying `…0000` is declaring the - /// slot unset, not declaring it meaningless. + /// The LOW half is not padding — it is a slot a *domain-specific + /// consumer* fills, and what filling it means is decided by whichever + /// consumer is reading it, not by this crate. The same bit pattern + /// means different things in different domains; do not generalise one + /// domain's reading to "what the low half means": /// - /// # The addressing model, and the one place the CSS analogy breaks + /// - In the ontology/concept domain, `0xFFFF` is a defined sentinel — + /// `ogar_codebook::canonical_concept_domain(0xFFFF)` resolves to + /// `Unassigned` ("outside the codebook"). + /// - In MedCare-rs's list-view rendering (`views/fieldview.rs`, the + /// Redmine `QueryColumn` pattern), the low half instead selects a + /// `ClassView` template and [`FieldMask`]/[`WideFieldMask`] picks + /// which of that view's columns are shown — a "screen-region + /// addressing" reading that is local to that one rendering pattern, + /// not a property of classids or `ClassView` in general. Classes are + /// not only for display — routing, storage, RBAC, and action dispatch + /// are all classid consumers too, each free to read the low half + /// differently, or not at all. /// - /// Low half + field mask compose into **screen-region addressing**, in - /// the CSS sense: the low half selects the `ClassView` (the per-app - /// template/skin) the way a selector picks an element, and the - /// [`FieldMask`]/[`WideFieldMask`] selects which of that view's fields - /// are in play the way declarations pick properties. That is the whole - /// basis of a2ui-rs's "don't push pixels — address the screen": a - /// `NodeDelta` carries a 16-byte key plus mask words, never a rendered - /// region. - /// - /// **Where the analogy must not be followed:** a field mask is - /// *presence, never semantics* (`class_view.rs` C2). `has(n)` answers - /// "is field n populated here" — it must NEVER gate "field n means - /// something different here." CSS's cascade does change which rule - /// wins; a mask never changes what a field means. Read the analogy for - /// addressing only. + /// **This parser makes no such interpretation.** [`parse`] validates + /// only that this is `0x`-prefixed hex fitting u32 — the width the + /// canonical node key's classid field reserves. It does not police, + /// consult, or assign meaning to either half: a zero canon is accepted + /// (a domain consumer may legitimately treat it as dormant/unset — this + /// parser neither enforces nor relies on that reading), and pre-flip + /// stored forms are left for `classid_canon_compat` to read. Use + /// [`BakeEntry::classid_u32`] to read the value; ask the consuming + /// domain, not this doc comment, what either half means there. /// /// [`FieldMask`]: lance_graph_contract::class_view::FieldMask /// [`WideFieldMask`]: lance_graph_contract::class_view::WideFieldMask - /// - /// [`parse`] validates only that this is `0x`-prefixed hex fitting u32. - /// It deliberately does **not** police the halves: a zero canon is a - /// legal dormant state under the zero-fallback ladder, and pre-flip - /// stored forms are legitimately read via `classid_canon_compat`. Use - /// [`BakeEntry::classid_u32`] to read the value and the codebook's own - /// accessors to split it. pub classid: String, /// Digest of the bake's slab, when the deployment pins one. Absent /// means "trust whatever is at `table` right now". @@ -285,12 +282,13 @@ pub fn parse(yaml: &str) -> Result { } // Structural only: it must be 0x-prefixed hex that fits the u32 the - // canonical node key reserves for it. NO semantic check on the halves - // — a zero canon is a legal dormant/bootstrap state under the - // zero-fallback ladder (CLAUDE.md: a zero tier is "not consulted", - // never an error), and pre-flip stored forms are legitimately read by - // `classid_canon_compat`. Rejecting either here would refuse valid - // configs on an inference about intent this parser has no basis for. + // canonical node key reserves for it. NO semantic check on the + // halves — what either half means is decided by whichever + // domain-specific consumer reads it (see the field doc comment on + // `BakeEntry::classid`), not by this parser, and this parser makes + // no claim about how any consumer treats a zero half. Rejecting + // either here would refuse valid configs on an inference about + // intent this parser has no basis for. parse_classid_hex(&bake.classid) .ok_or_else(|| ConfigError::BadClassid(bake.classid.clone()))?; } From e4b451d8ea0c7fcbd24ee3bae1f31c2d0f1808ff Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 22:32:27 +0000 Subject: [PATCH 2/2] =?UTF-8?q?soa=5Fconfig:=20fix=20the=20classid=20examp?= =?UTF-8?q?le=20=E2=80=94=200xFFFF=20is=20a=20canon-half=20fact,=20not=20l?= =?UTF-8?q?ow-half?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex P2 on #910: canonical_concept_domain takes the u16 concept id that classid_canon extracts from the HIGH half under CanonHigh. A classid like 0x0F01_FFFF still routes to Geo via its canon (0x0F01); 0xFFFF sitting in the LOW half carries no ontology meaning at all. The doc presented 0xFFFF as evidence of "what the low half means in the ontology domain" — backwards, since it's a fact about the high half, uniform across every classid whose canon happens to be 0xFFFF. Reframed as a contrast instead: the HIGH half has one global, consumer-independent reading (ogar-vocab's canonical_concept_domain, which is why 0xFFFF -> Unassigned holds for ANY classid with that canon). The LOW half has no such global registry — its meaning is whatever the specific consumer (MedCare-rs's fieldview pattern, or any other classid consumer) decides, which is the actual point this doc comment is making. Gate: 17/17 soa_config · fmt clean. --- .../examples/soa-config.example.yaml | 34 ++++++++++--------- crates/lance-graph/src/soa_config.rs | 29 ++++++++-------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/crates/lance-graph/examples/soa-config.example.yaml b/crates/lance-graph/examples/soa-config.example.yaml index 9f860c80..fcea7702 100644 --- a/crates/lance-graph/examples/soa-config.example.yaml +++ b/crates/lance-graph/examples/soa-config.example.yaml @@ -109,22 +109,24 @@ bakes: # The LOW half is NOT padding — it is a slot a # DOMAIN-SPECIFIC CONSUMER fills, and what # filling it means depends on which consumer is - # reading it, not on this file or this parser. - # The same bit pattern means different things - # in different domains: in the ontology/concept - # domain, 0xFFFF is a defined sentinel - # (ogar_codebook::canonical_concept_domain - # resolves it to Unassigned); in MedCare-rs's - # list-view rendering (the Redmine QueryColumn - # pattern), the low half instead selects a - # ClassView template and a field mask picks - # which columns show — a reading local to that - # ONE rendering pattern, not a general truth - # about classids. Classes are not only for - # display — routing, storage, RBAC, and action - # dispatch are classid consumers too, each free - # to read the low half differently, or not at - # all. Ask the consuming domain, not this file. + # reading it, not on this file, not on any + # single global registry. Contrast the HIGH + # half: 0xFFFF there is registered once, for + # everyone (classid_canon extracts it, + # ogar_codebook::canonical_concept_domain + # resolves it to Unassigned for ANY classid + # whose canon half is 0xFFFF). Nothing gives + # the LOW half that kind of universal reading — + # in MedCare-rs's list-view rendering (the + # Redmine QueryColumn pattern), the low half + # instead selects a ClassView template and a + # field mask picks which columns show, a + # reading local to that ONE rendering pattern. + # Classes are not only for display — routing, + # storage, RBAC, and action dispatch are + # classid consumers too, each free to read the + # low half differently, or not at all. Ask the + # consuming domain, not this file. # # The parser checks only that this is # 0x-prefixed hex fitting u32. It deliberately diff --git a/crates/lance-graph/src/soa_config.rs b/crates/lance-graph/src/soa_config.rs index 77957c13..59ae8a35 100644 --- a/crates/lance-graph/src/soa_config.rs +++ b/crates/lance-graph/src/soa_config.rs @@ -111,22 +111,23 @@ pub struct BakeEntry { /// /// The LOW half is not padding — it is a slot a *domain-specific /// consumer* fills, and what filling it means is decided by whichever - /// consumer is reading it, not by this crate. The same bit pattern - /// means different things in different domains; do not generalise one - /// domain's reading to "what the low half means": + /// consumer is reading it, not by this crate, and not by any single + /// global registry. Contrast with the HIGH half: `0xFFFF` there is + /// registered once, for everyone — `classid_canon` extracts it and + /// `ogar_codebook::canonical_concept_domain(0xFFFF)` resolves it to + /// `Unassigned` ("outside the codebook") for ANY classid whose canon + /// half is `0xFFFF` (e.g. `0xFFFF_0000`). Nothing gives the LOW half + /// that kind of universal reading: /// - /// - In the ontology/concept domain, `0xFFFF` is a defined sentinel — - /// `ogar_codebook::canonical_concept_domain(0xFFFF)` resolves to - /// `Unassigned` ("outside the codebook"). /// - In MedCare-rs's list-view rendering (`views/fieldview.rs`, the - /// Redmine `QueryColumn` pattern), the low half instead selects a - /// `ClassView` template and [`FieldMask`]/[`WideFieldMask`] picks - /// which of that view's columns are shown — a "screen-region - /// addressing" reading that is local to that one rendering pattern, - /// not a property of classids or `ClassView` in general. Classes are - /// not only for display — routing, storage, RBAC, and action dispatch - /// are all classid consumers too, each free to read the low half - /// differently, or not at all. + /// Redmine `QueryColumn` pattern), the low half selects a `ClassView` + /// template and [`FieldMask`]/[`WideFieldMask`] picks which of that + /// view's columns are shown — a "screen-region addressing" reading + /// local to that one rendering pattern. + /// - Nothing says a different consumer must read it the same way. + /// Classes are not only for display — routing, storage, RBAC, and + /// action dispatch are all classid consumers too, each free to read + /// the low half differently, or not at all. /// /// **This parser makes no such interpretation.** [`parse`] validates /// only that this is `0x`-prefixed hex fitting u32 — the width the