From cc5060b20ba0c9dd5b24513829783f78c7da8c23 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:10:01 +0000 Subject: [PATCH 1/7] docs: ClassView field-view via Askama + a field bitmask (Redmine-ERB, compiled) Capture the consumer-side pattern: render a ClassView as an HTML field view the way Redmine renders model fields with ERB, but compiled, type-safe, JSON-free, and driven by a u64 field mask instead of per-field conditionals. One generic Askama loop over a mask-filtered, generated FieldDesc[] table (no if-noise). The render-mask = the read-mask: the same selector that chooses which facets to decode chooses which fields to show (the render-side twin of the compiled-ClassView spine). Discipline: field/idx/bit from ONE generated source (I-LEGACY-API-FEATURE-GATED). Residual novel fields -> generic Vec view or build.rs codegen. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md diff --git a/docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md b/docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md new file mode 100644 index 0000000..500d56a --- /dev/null +++ b/docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md @@ -0,0 +1,137 @@ +# ClassView field-view via Askama + a field bitmask + +> **Consumer-side rendering pattern.** Render an OGAR `ClassView` as an HTML +> field view the way Redmine renders a model's fields with ERB — but **compiled, +> type-safe, JSON-free, and driven by a field bitmask instead of per-field +> conditionals**. This is the *render-side twin* of §1.5 ("the spine is the +> COMPILED ClassView"): the read-mask that selects which facets to decode and the +> render-mask that selects which fields to show are the **same bits**. + +## The problem + +A `ClassView` has a field set. Different contexts want different *subsets* of it: +a `V1` vs `V2` facet layout, an RBAC-restricted view, a compact card vs a full +record, a tenant projection. Redmine solves this with ERB: a generic field +partial loops a **column list** (`available_columns` filtered to the selected +`column_names`) and renders each. The visibility lives in the *data*, not the +template — there is no `<% if show_dose %>` per field. + +The naive port to a *compile-time* engine (Askama) reaches for per-field +conditionals — `{% if self.shows(Dose) %}…{% endif %}` — and that is **wrong**: +it is `if`-noise, it does not scale to wide classes, and it is not how Redmine +does it. A compiled template looks like it forbids dynamic field sets. It does +not. The fix is to move selection out of the template and **into an iterated, +mask-filtered list** — one loop, zero conditionals. + +## The shape (no `if` noise) + +Selection is data. The template is a dumb iterator over the **already-filtered** +field list; a `u64` mask decides membership in Rust. + +```rust +// FieldDesc[] and the bit indices are GENERATED from the ClassView schema +// (derive macro or build.rs) — never hand-written next to hand-numbered bits. +struct FieldDesc { idx: u8, label: &'static str, kind: FieldKind } + +struct ClassFieldView<'a> { + fields: &'a [FieldDesc], // the maximal, ordered field set for this class + mask: u64, // which fields are SELECTED (1 << idx) + rec: &'a Record, // the SoA-backed values +} + +impl ClassFieldView<'_> { + fn selected(&self) -> impl Iterator { + self.fields.iter().filter(move |f| self.mask & (1 << f.idx) != 0) + } + fn unselected(&self) -> impl Iterator { + self.fields.iter().filter(move |f| self.mask & (1 << f.idx) == 0) + } + fn value(&self, f: &FieldDesc) -> Cell<'_> { self.rec.cell(f.idx) } +} +``` + +```jinja +{# the ERB-shaped field partial — ONE loop, zero ifs #} +{% for f in self.selected() %} + {{ f.label }}{{ self.value(f)|fmt }} +{% endfor %} +``` + +The bitmask **is** the selected / unselected partition: + +- **bit set** → the field is in the loop → rendered in the view. +- **bit clear** → the field is out → available but hidden. `unselected()` is + exactly Redmine's "available columns" palette for a column chooser. + +Versions, roles, and projections are simply **different masks over the same +template**. There is no template per version — one compiled artifact, any subset. + +## Why this is right (not just convenient) + +1. **§1.5 alignment — render-mask = read-mask.** "One compiled reader subsumes + V1/V2/V3 — no hardcoded facet versions." The render mask is the *same selector* + the ClassView reader uses to choose which facets to decode. V1 is one bit + pattern, V2 another, a role view another; all over one template. +2. **Mirror of columnar projection.** Arrow / lance-graph prune *columns* with a + selection mask; this prunes *view fields* with a selection mask. SoA + a + selection mask = a dynamic projection — same shape at the data layer and the + view layer. The "schema glove" over the SoA columns *is* the mask. +3. **JSON-free.** `Record` struct → Askama → HTML, entirely in Rust. The field + views never touch a serializer or a JS frontend. htmx-friendly without React. +4. **No `if` noise.** The template never branches per field; it iterates a + pre-filtered set. Wide classes stay readable; the structure is compile-checked. +5. **Auto-escaping by default** → XSS-safe, which matters on a clinical/PII + surface (and the no-German-PII rule). Baked into the binary → no runtime parse, + no template-file I/O, no path traversal. + +## The one discipline (iron rule) + +**`field ↔ idx ↔ bit` must come from ONE generated source.** Generate the +`FieldDesc[]` table *and* the bit indices from the ClassView definition (derive +macro or `build.rs`) so the mask indexes the **same ordered field set** the loop +renders. Never hand-number bits next to a hand-written list — that is precisely +where bit 17 silently starts meaning a different field across a version bump. +This is `I-LEGACY-API-FEATURE-GATED`: a bitmask over a layout is exactly where +bits alias. The read-mask and the render-mask **share** the generated constants. + +Corollary discipline: **mask logic lives in Rust, the template is dumb.** Compute +*which* bits are set (role × version × projection) in Rust; hand the template a +struct that only answers `selected()` / `unselected()` / `value(f)`. Conditionals +gate presence (and here there are none); filters (`|fmt`, `|escape`) shape the +shown value. The ClassView is the data, the mask is the selector, the template is +the skin. + +## The residual (what the mask cannot do) + +The mask selects **presence over the known maximal field set** — facet, version, +role, projection. That is the entire common case. The one thing it *cannot* do is +render a field that was **never compiled** (a genuinely novel field from a +runtime-imported ontology). That residual has two blessed routes, in order: + +1. a **generic `Vec<(name, value)>` view** + one Askama template that loops the + tuples — covers the whole dynamic tail with one compiled template; or +2. **`build.rs` codegen** that emits a `FieldDesc[]` (and template, if bespoke) + per class from the ontology manifest — compile-time codegen, which the stack + explicitly blesses ("build-time serde codegen *is* compile types"). + +Reach for a *runtime* template engine (MiniJinja/Tera) only for genuinely +user-authored, per-tenant templates — never as the default. + +## Summary + +One generic Askama field partial + a generated `FieldDesc[]` table + a `u64` +mask = the whole dynamic ClassView field view: Redmine-shaped, JSON-free, no +conditionals in the template, type-checked structure, dynamic across +versions/roles/projections. **The mask carves; the loop renders.** Askama's +compile-time nature is not a cage — the mask is the runtime knob, and it is the +same selector the data layer already uses to prune columns. + +## Cross-references + +- §1.5 "the spine is the COMPILED ClassView" — the read-side twin (the render + mask = the facet read selector). +- `docs/OGAR-AS-IR.md` — ClassView as a compiler IR surface. +- `docs/OGAR-CONSUMER-BEST-PRACTICES.md` — the consumer muscle-memory guide this + pattern slots into. +- `I-LEGACY-API-FEATURE-GATED` — why the mask bits must be generated, never + hand-numbered alongside a layout. From f3b07e0d79ae725ffac13c31f96fcff04a0f1ec4 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:26:38 +0000 Subject: [PATCH 2/7] =?UTF-8?q?docs:=20capstone=20=E2=80=94=20OGAR=20as=20?= =?UTF-8?q?a=20semantic=20transpiler=20sinking=20into=20the=20v3=20substra?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Capture the synthesis before it dilutes (PROPOSAL, pending 5+3 hardening): - OGAR = semantic transpiler; v3 substrate = the sink (s1.5 'sinks into OGAR'). - Two front-ends: serialization (syntax incidental) vs semantic-application (Odoo/Redmine/OpenProject) where syntax is PRESERVED (semantic->semantic). - Three arms: THINK/Class+fieldview structure-preserving; DO/ActionDef re-imagined as classid-keyed adapters = the God-object/SoC dividend; membrane/KausalSpec. - The universal selector: one generated bitmask = read=query=render=version=auth. - classid/HHTL cascade = the semantic zoom + renderer dispatch by signature. - living ractor mailbox-owned SoA; JSON-free end to end. - Honest edges flagged for grading (generated-bits iron rule, Biolink upper layer, renderer scale ceiling). All claims [G]/[H]/[S]-gradable. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 151 ++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md new file mode 100644 index 0000000..d03994d --- /dev/null +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -0,0 +1,151 @@ +# OGAR as a semantic transpiler that sinks into the v3 substrate + +> **Status:** PROPOSAL — captured before dilution; pending the 5+3 hardening pass +> before it enters the canon. **Grade the claims [G]/[H]/[S] during review.** +> +> Capstone synthesis. Names the whole arc in one frame: OGAR is a **semantic +> transpiler**; the **v3 substrate** is its **sink**; and the patterns already +> established (the compiled ClassView §1.5, the SoA-schema-glove, the bitmask +> field-view, the classid/HHTL address, the ractor mailbox-owned SoA, the no-wire +> FFI) are the **superpowers** that make the sunk graph a living, multi-scale, +> queryable, renderable knowledge graph — without per-source code. + +## 1. The frame + +A transpiler is a source-to-source compiler. OGAR transpiles **source format → +substrate**: every front-end (GFA/VCF, OWL/OBO, SNOMED, RxNorm, DICOM, FHIR, and +whole applications — Odoo, Redmine, OpenProject) lowers into the OGAR AST and +**sinks** into the v3 node store. "Sink" is §1.5's own word: the ClassView +"recombines the carvings while *sinking into OGAR* and getting compiled into the +binary." The transpiler does not emit rows into a database — it emits **typed, +classid-addressed, compiled** nodes into a substrate that can route, group, and +render them from the key alone (the key prerenders with zero value decode). + +## 2. Two kinds of front-end (syntax is NOT generically lost) + +The earlier framing — "the format dissolves, only meaning survives" — is correct +for **one** class of source and wrong for the other. The distinction is load-bearing. + +- **Serialization formats** (GFA, VCF, raw RDF triples, DICOM pixels). Syntax is + incidental; the meaning *is* the columns. "GFA = SoA wearing a schema glove" — + a ~200-line parser, no DO arm, nothing behavioural to preserve. Here syntax + genuinely dissolves into SoA columns + a classid schema. +- **Semantic application sources** (Odoo models/views/actions, Redmine ERB field + views + models, OpenProject work-package schema). The source is *already + semantic syntax*. This is **semantic-syntax → semantic-syntax**, structure-for- + structure. **Syntax is preserved — re-hosted, not dissolved.** Redmine's + ERB-field-view-with-column-masking transcodes into the Askama bitmask + field-view *structure-for-structure* (see `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md`): + the field-partial-with-selection survived; it only changed host language. + +## 3. The three arms — what is preserved vs what is re-imagined + +Per `OGAR-AST-CONTRACT.md` (THINK arm `Class` / DO arm `ActionDef`+`ActionInvocation` +/ membrane `KausalSpec`), an application transcode splits cleanly: + +- **THINK arm — `Class` / ClassView / fieldview (data + view): STRUCTURE-PRESERVING.** + Odoo view → ClassView; Redmine ERB field partial → Askama bitmask partial; + OpenProject WP schema → Class facets. Semantic syntax survives. +- **DO arm — `ActionDef` / `ActionInvocation` (behaviour): RE-IMAGINED as + classid-keyed adapters.** This is the *only* part that is not a structure-for- + structure carry. And — the load-bearing insight — **re-imagining actions as + adapters is not a tax; it is the separation-of-concerns / God-object fix you + would want regardless.** Odoo and Rails (Redmine/OpenProject) fuse data + view + + behaviour into one fat model class — the canonical God object. The transcode + is *forced* to split it into `Class` (data) + fieldview (view) + adapter + (behaviour), so you exit with the three-way separation the monolith never had. + The "cost" is a **refactor dividend** — paying down the source codebase's + architectural debt as a side effect of the port. +- **membrane — `KausalSpec`.** + +This is the Core-First Transcode Doctrine applied to whole apps (the +adapter-shaper / core-gap-auditor ensemble): identity = `classid`, state = SoA +value tenants, composition = `ClassView`, **invocation = adapter** — and the iron +rule that an adapter *never carries its own state*; a Core gap means **extend the +Core, never hack the adapter**. "Don't let the adapter hold state" *is* "kill the +God object, don't smear its responsibilities." + +## 4. The superpower — one selector, five jobs + +The field bitmask documented in `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` is not a +UI trick. It is the **universal selector**, and it is the same generated bit set +everywhere: + +| job | the mask selects… | +|------------|-------------------| +| **read** | which facets to decode (§1.5 compiled reader) | +| **query** | which columns to project (Arrow / lance-graph column pruning) | +| **render** | which fields the Askama loop emits (no `if`-noise) | +| **version**| V1 vs V2 vs V3 = different masks over one compiled reader/template | +| **auth** | which fields a role may see (RBAC) | + +Decode, query, render, version, authorize — **one set of bits.** That is why a +sunk node is *instantly* usable: the transpiler assigns the classid + the facet +mask, and every downstream operation is already wired because they consume the +same selector over the same SoA columns. You do not build a query layer, a view +layer, a versioning layer, and an auth layer — you **generate the bits once** and +reuse them five ways. (Iron-rule gate: `field ↔ idx ↔ bit` must come from ONE +generated source — `I-LEGACY-API-FEATURE-GATED` — or bit 17 silently re-aliases +across a version bump and corrupts all five jobs at once.) + +## 5. The address is the zoom + +The HHTL / canonical-GUID cascade is the multi-scale "Google Earth" axis for free: +classid prefix → class + **topology signature** → renderer dispatch; the tiers → +the centroid mipmap → the zoom levels. Planet → organ → cell → chromosome → gene → +atom is **prefix routing**, not an application switch. The renderer it dispatches +to (branching-network / mesh / molecular) is chosen by the structural signature +carried in the classid — VG variation graphs and arterial trees land on the *same* +tube renderer because they share a signature, not a domain. Layout is one more +lance-graph pass that annotates positions; renderers stay dumb. + +## 6. Living, not a dump; JSON-free, end to end + +- **Living substrate.** The ractor mailbox-owned SoA gives `n × 64k` concurrent, + compile-time race-free node updates — the sunk graph is a living kanban, not the + batch-built static snapshot every other biomedical KG ships. The renderer sits + on a surface being updated under it, safely. +- **JSON-free.** The transpiler writes SoA columns; the JS engine (JSC/V8) is + in-process via op/FFI so Rust↔JS is a memory handoff; Askama renders records to + HTML in pure Rust; the only wire is Arrow IPC / binary columns to the browser. + The format dissolved (or was re-hosted) at the front door and never + reconstitutes as JSON at the back. + +## 7. The dots, connected + +**Parse once per source (cheap) → sink into classid-keyed SoA → and query, render, +version, authorize, zoom, and live-update all come free, because it is the same +node, the same mask, the same address everywhere.** The biomedical "holy grail" +graph is not an app per layer — it is **the transpiler + the sink + the universal +selector**. Genomics (VG/GFA) is simply the next serialization front-end to lower +in; Odoo/Redmine/OpenProject are the semantic-application front-ends where syntax +is *preserved* and behaviour is *upgraded* (God object → adapters). The Askama +bitmask field-view is the render-side face of the exact selector the substrate +already uses to read, query, and version. One mechanism, wearing every glove. + +## 8. Honest edges (do not let the synthesis become poetry) + +1. **"One mask, five jobs" holds only if the bits are generated from one source.** + Hand-number them and `I-LEGACY-API-FEATURE-GATED` bites — and it bites all five + jobs at once. This is the single highest-leverage discipline in the capstone. +2. **The cross-ontology upper layer is still real work.** Mapping FMA / SNOMED / + VG / RxNorm into one category tree — **adopt Biolink Model**, do not invent it. +3. **The renderer has a scale ceiling.** three.js goes geometry-bound in the + millions of tris (the `/helix` mobile-freeze evidence); the multi-scale viewer + leans on the LOD/HHTL cascade, not raw draw calls. +4. **Grade required.** Each claim above is [G] coded / [H] bounded-plausible / [S] + analogy-only until the 5+3 pass grades it. The transpiler frame, the three-arm + split, and the one-selector identity are the claims most in need of a + runtime-archaeologist CODED-vs-CLAIMED check. + +## Cross-references + +- `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` — the render-side face of the universal + selector (the pattern this capstone frames). +- §1.5 "the spine is the COMPILED ClassView" — the sink + the read-mask twin. +- `OGAR-AST-CONTRACT.md` — the THINK / DO / membrane arms. +- `OGAR-AS-IR.md` — OGAR as a multi-phase compiler IR. +- `OGAR-CONSUMER-BEST-PRACTICES.md` — the consumer surface these transcodes target. +- `SURREAL-AST-AS-ADAPTER.md` / `core-first-transcode-doctrine` — actions → adapters, + the God-object/SoC dividend. +- `I-LEGACY-API-FEATURE-GATED` — why the universal-selector bits must be generated. From 594bcb3eb05785348b5259e57676ce3c29df0de0 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:40:30 +0000 Subject: [PATCH 3/7] docs(capstone): harden via 5+3 + operator corrections - ractor = RUNTIME ownership guarantee (mailbox serializes at runtime); NOT a compile-time borrow proof. n actors x up-to-64k partitions run concurrently, race-free by single-owner-per-partition. - field count is a representation parameter ([u64;N] -> 256+), NOT a blocker. - transpile is a landing zone (a destination, ahead of code): claims tagged CODED-today vs LANDING-ZONE rather than downgraded for being unbuilt. - payoff stated: Odoo ERP at the cost of an import; past Palantir Foundry (whole-app transpile incl. DO arm -> ractor StateMachines, not rebuilt). - factual fixes kept: DO arm = ractor StateMachine (not thin adapter); selector = N3 presence FieldMask doing 3 jobs (read/render/auth-projection); query rides a 2nd physical-tenant basis; version = radix lookup; auth verdict/scope = I-K8 folds. Two FieldMask bases must be type-separated. - Firewall: Arrow/HTML egress is the OUTER crossing (ADR-022 s5 + D-KV-RENDER), inner path moves keys; no inner serialization. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 328 ++++++++++++---------- 1 file changed, 183 insertions(+), 145 deletions(-) diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md index d03994d..f0e52df 100644 --- a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -1,151 +1,189 @@ # OGAR as a semantic transpiler that sinks into the v3 substrate -> **Status:** PROPOSAL — captured before dilution; pending the 5+3 hardening pass -> before it enters the canon. **Grade the claims [G]/[H]/[S] during review.** +> **Status:** CAPSTONE / landing-zone (a *destination*, ahead of the code by +> design). Hardened by the 5+3 pass — factual mechanics corrected, the vision +> kept whole. Each claim is tagged **CODED-today** (shipped, file:line) or +> **LANDING-ZONE** (the target we transpile *toward*). A landing-zone claim is +> not weaker for being unbuilt; it is the direction. > -> Capstone synthesis. Names the whole arc in one frame: OGAR is a **semantic -> transpiler**; the **v3 substrate** is its **sink**; and the patterns already -> established (the compiled ClassView §1.5, the SoA-schema-glove, the bitmask -> field-view, the classid/HHTL address, the ractor mailbox-owned SoA, the no-wire -> FFI) are the **superpowers** that make the sunk graph a living, multi-scale, -> queryable, renderable knowledge graph — without per-source code. - -## 1. The frame - -A transpiler is a source-to-source compiler. OGAR transpiles **source format → -substrate**: every front-end (GFA/VCF, OWL/OBO, SNOMED, RxNorm, DICOM, FHIR, and -whole applications — Odoo, Redmine, OpenProject) lowers into the OGAR AST and -**sinks** into the v3 node store. "Sink" is §1.5's own word: the ClassView -"recombines the carvings while *sinking into OGAR* and getting compiled into the -binary." The transpiler does not emit rows into a database — it emits **typed, -classid-addressed, compiled** nodes into a substrate that can route, group, and -render them from the key alone (the key prerenders with zero value decode). - -## 2. Two kinds of front-end (syntax is NOT generically lost) - -The earlier framing — "the format dissolves, only meaning survives" — is correct -for **one** class of source and wrong for the other. The distinction is load-bearing. - -- **Serialization formats** (GFA, VCF, raw RDF triples, DICOM pixels). Syntax is - incidental; the meaning *is* the columns. "GFA = SoA wearing a schema glove" — - a ~200-line parser, no DO arm, nothing behavioural to preserve. Here syntax - genuinely dissolves into SoA columns + a classid schema. -- **Semantic application sources** (Odoo models/views/actions, Redmine ERB field - views + models, OpenProject work-package schema). The source is *already - semantic syntax*. This is **semantic-syntax → semantic-syntax**, structure-for- - structure. **Syntax is preserved — re-hosted, not dissolved.** Redmine's - ERB-field-view-with-column-masking transcodes into the Askama bitmask - field-view *structure-for-structure* (see `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md`): - the field-partial-with-selection survived; it only changed host language. - -## 3. The three arms — what is preserved vs what is re-imagined - -Per `OGAR-AST-CONTRACT.md` (THINK arm `Class` / DO arm `ActionDef`+`ActionInvocation` -/ membrane `KausalSpec`), an application transcode splits cleanly: - -- **THINK arm — `Class` / ClassView / fieldview (data + view): STRUCTURE-PRESERVING.** - Odoo view → ClassView; Redmine ERB field partial → Askama bitmask partial; - OpenProject WP schema → Class facets. Semantic syntax survives. -- **DO arm — `ActionDef` / `ActionInvocation` (behaviour): RE-IMAGINED as - classid-keyed adapters.** This is the *only* part that is not a structure-for- - structure carry. And — the load-bearing insight — **re-imagining actions as - adapters is not a tax; it is the separation-of-concerns / God-object fix you - would want regardless.** Odoo and Rails (Redmine/OpenProject) fuse data + view - + behaviour into one fat model class — the canonical God object. The transcode - is *forced* to split it into `Class` (data) + fieldview (view) + adapter - (behaviour), so you exit with the three-way separation the monolith never had. - The "cost" is a **refactor dividend** — paying down the source codebase's - architectural debt as a side effect of the port. -- **membrane — `KausalSpec`.** - -This is the Core-First Transcode Doctrine applied to whole apps (the -adapter-shaper / core-gap-auditor ensemble): identity = `classid`, state = SoA -value tenants, composition = `ClassView`, **invocation = adapter** — and the iron -rule that an adapter *never carries its own state*; a Core gap means **extend the -Core, never hack the adapter**. "Don't let the adapter hold state" *is* "kill the -God object, don't smear its responsibilities." - -## 4. The superpower — one selector, five jobs - -The field bitmask documented in `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` is not a -UI trick. It is the **universal selector**, and it is the same generated bit set -everywhere: - -| job | the mask selects… | -|------------|-------------------| -| **read** | which facets to decode (§1.5 compiled reader) | -| **query** | which columns to project (Arrow / lance-graph column pruning) | -| **render** | which fields the Askama loop emits (no `if`-noise) | -| **version**| V1 vs V2 vs V3 = different masks over one compiled reader/template | -| **auth** | which fields a role may see (RBAC) | - -Decode, query, render, version, authorize — **one set of bits.** That is why a -sunk node is *instantly* usable: the transpiler assigns the classid + the facet -mask, and every downstream operation is already wired because they consume the -same selector over the same SoA columns. You do not build a query layer, a view -layer, a versioning layer, and an auth layer — you **generate the bits once** and -reuse them five ways. (Iron-rule gate: `field ↔ idx ↔ bit` must come from ONE -generated source — `I-LEGACY-API-FEATURE-GATED` — or bit 17 silently re-aliases -across a version bump and corrupts all five jobs at once.) - -## 5. The address is the zoom - -The HHTL / canonical-GUID cascade is the multi-scale "Google Earth" axis for free: -classid prefix → class + **topology signature** → renderer dispatch; the tiers → -the centroid mipmap → the zoom levels. Planet → organ → cell → chromosome → gene → -atom is **prefix routing**, not an application switch. The renderer it dispatches -to (branching-network / mesh / molecular) is chosen by the structural signature -carried in the classid — VG variation graphs and arterial trees land on the *same* -tube renderer because they share a signature, not a domain. Layout is one more -lance-graph pass that annotates positions; renderers stay dumb. - -## 6. Living, not a dump; JSON-free, end to end - -- **Living substrate.** The ractor mailbox-owned SoA gives `n × 64k` concurrent, - compile-time race-free node updates — the sunk graph is a living kanban, not the - batch-built static snapshot every other biomedical KG ships. The renderer sits - on a surface being updated under it, safely. -- **JSON-free.** The transpiler writes SoA columns; the JS engine (JSC/V8) is - in-process via op/FFI so Rust↔JS is a memory handoff; Askama renders records to - HTML in pure Rust; the only wire is Arrow IPC / binary columns to the browser. - The format dissolved (or was re-hosted) at the front door and never - reconstitutes as JSON at the back. - -## 7. The dots, connected - -**Parse once per source (cheap) → sink into classid-keyed SoA → and query, render, -version, authorize, zoom, and live-update all come free, because it is the same -node, the same mask, the same address everywhere.** The biomedical "holy grail" -graph is not an app per layer — it is **the transpiler + the sink + the universal -selector**. Genomics (VG/GFA) is simply the next serialization front-end to lower -in; Odoo/Redmine/OpenProject are the semantic-application front-ends where syntax -is *preserved* and behaviour is *upgraded* (God object → adapters). The Askama -bitmask field-view is the render-side face of the exact selector the substrate -already uses to read, query, and version. One mechanism, wearing every glove. - -## 8. Honest edges (do not let the synthesis become poetry) - -1. **"One mask, five jobs" holds only if the bits are generated from one source.** - Hand-number them and `I-LEGACY-API-FEATURE-GATED` bites — and it bites all five - jobs at once. This is the single highest-leverage discipline in the capstone. -2. **The cross-ontology upper layer is still real work.** Mapping FMA / SNOMED / - VG / RxNorm into one category tree — **adopt Biolink Model**, do not invent it. -3. **The renderer has a scale ceiling.** three.js goes geometry-bound in the - millions of tris (the `/helix` mobile-freeze evidence); the multi-scale viewer - leans on the LOD/HHTL cascade, not raw draw calls. -4. **Grade required.** Each claim above is [G] coded / [H] bounded-plausible / [S] - analogy-only until the 5+3 pass grades it. The transpiler frame, the three-arm - split, and the one-selector identity are the claims most in need of a - runtime-archaeologist CODED-vs-CLAIMED check. +> **The one-line payoff:** an Odoo ERP *at the cost of an import* — and the same +> substrate that holds the ERP also holds anatomy, ontologies, and genomics under +> one address space. This is whole-app transpilation into a compiled, living +> substrate, not data-integration-into-an-ontology. It is past Palantir Foundry, +> not chasing it. + +## 1. The frame — and why it beats Foundry + +A transpiler is a source-to-source compiler. OGAR transpiles **source → substrate**: +every front-end lowers into the OGAR AST and **sinks** into the v3 node store +(§1.5's own word: the ClassView "recombines the carvings while *sinking into +OGAR* and getting compiled into the binary"). The transpiler does not emit rows +into a database — it emits **typed, classid-addressed, compiled** nodes that +route, group, and skeleton-render from the key alone (`D-KEYKV` **[G]**, "the key +prerenders with zero value decode"). + +**Two kinds of front-end — name them distinctly up front:** + +- **Dissolving front-ends** (GFA/VCF, raw RDF, DICOM pixels). No DO arm; meaning + *is* the columns. "GFA = SoA wearing a schema glove" — a thin parser; syntax + dissolves into SoA columns + a classid schema. +- **Re-hosting front-ends** (Odoo, Redmine, OpenProject — whole applications). + The source is *already semantic syntax*. This is **semantic-syntax → semantic- + syntax**: the **selection structure is re-hosted, not dissolved** (Redmine's + ERB field-view → the Askama bitmask field-view; the host language changes, the + field-selection structure survives). *(Edge: OWL-with-inference straddles the + two — its subClassOf/domain-range semantics are a behavioural arm; classify it + case-by-case.)* + +**Why this is past Foundry.** Palantir Foundry integrates *data* into an Ontology +you build on top of a data lake: you re-model the source and **rebuild its +workflows** in Foundry's own action layer; it is a proprietary, batch-pipeline +metadata surface. OGAR imports the **whole app** — the THINK arm *and* the DO arm +— into **one classid-addressed, compiled, living substrate**. You do not rebuild +the ERP; you **transpile** it. That is the "at the cost of an import" claim +Foundry structurally cannot make, and the substrate is **domain-universal** (the +same address space holds FMA anatomy, SNOMED, RxNorm, genomics — not just +enterprise tables). + +## 2. The three arms — what is preserved, what is *carried*, what re-hosts + +Per `OGAR-AST-CONTRACT.md`: + +- **THINK arm — `Class` → ClassView → fieldview (a three-level chain, not one + layer):** `Class` is the source-of-truth IR node (data + declared hooks); + **ClassView** is a per-app render skin (hi-u16); **fieldview** is a presence + mask over ClassView. Structure-preserving: Odoo view → ClassView; Redmine ERB + partial → Askama bitmask partial; OpenProject WP schema → `Class` facets. + **CODED-today** (`lance-graph-contract/src/class_view.rs`: `ClassView`, + `render_rows`, `project`; impl `ogar-class-view`). +- **DO arm — `ActionDef` / `ActionInvocation` → a generated ractor `StateMachine` + (with `KausalSpec` state-guards).** This is the catch that makes "ERP at the + cost of an import" real: Odoo's action methods are **carried into actual state + machines**, not stubbed as stateless adapters. (The "classid-keyed adapter" of + the Core-First doctrine is the *data-shaped leaf-method* lowering only — its + scope boundary; behaviour-bearing actions are the `StateMachine` path.) Foundry + rebuilds these workflows by hand; OGAR transpiles them. **LANDING-ZONE** (the + `Class`→`StateMachine` codegen is specced; gate **F1** — delegation ≡ Odoo + `_inherit` — proves behavioural parity and **has not run yet**; the God-object→ + three-way-split "refactor dividend" is **CONJECTURE** until F1 is green). +- **DO-arm guard — `KausalSpec`:** the state-guard *field on* `ActionDef` that + gates a transition (not a separate co-equal "arm"). + +The split is itself the separation-of-concerns the source monolith never had — +`Class` (data) + ClassView/fieldview (view) + `StateMachine` (behaviour) out of +one fat Odoo/Rails model. We *argue* this is a net architectural win; F1 is the +falsifier. + +## 3. The universal selector — one representation, the jobs it really does + +The presence `FieldMask` over the **N3 append-only field basis** is a genuine, +shipped, single-bit-space selector. Be exact about which jobs it does: + +| job | mask / mechanism | owner of the bits | status | +|---|---|---|---| +| **read** (facet decode) | N3 presence `FieldMask` | compiled reader | **CODED** (`class_view.rs`) | +| **render** (field view) | same N3 `FieldMask`, bit-gated loop | compiled template | **CODED** (`render_rows`) | +| **auth field-projection** | same N3 `FieldMask`, OR-folded | role × lo-u16 grant lattice | **CODED** (`lance-graph-rbac::authorize_scoped`, `permission.rs::projection`) | +| **query** (column pruning) | a **second** `FieldMask` on the **physical value-tenant** basis | the value-slab layout | **CODED but a DIFFERENT basis** (`canonical_node.rs::ValueSchema::field_mask`) | +| **version** (V1/V2/V3) | a `classid → ReadMode/ValueSchema` **radix lookup** (not a mask op) | `ENVELOPE_LAYOUT_VERSION` registry | **CODED as a lookup** | +| **auth verdict + row-scope** | boolean gate + **AND**-folded scope | RBAC keystone **I-K8** (four orthogonal axes) | **CODED, not the mask** | + +**The honest collapse is THREE jobs over the N3 basis — read + render + auth- +field-projection — shipped and tested** (`distinct_roles_carry_disjoint_projections_of_one_class`). +That is the real universal selector, and it is real today. `query` rides a +*second* mask on the physical basis; `version` is a radix lookup; auth's +verdict/scope are ordered folds with a different algebra (AND-scope vs OR- +projection — one mask cannot be both). Collapse the three; keep the others +named-distinct. + +**Two disciplines (both load-bearing, neither a blocker):** + +1. **Field count is a representation parameter, not a ceiling.** A presence mask + is `[u64; N]` — `[u64; 4]` = 256 fields, wider as needed; Odoo's 109-field + `account.move` is a `[u64; 2]`, not a wall. Widen the basis; the algebra is + unchanged. *(`I-LEGACY-API-FEATURE-GATED` still applies: `field ↔ idx ↔ bit` + must be generated from one source, never hand-numbered, or a version bump + re-aliases bits.)* +2. **The two bases must be type-separated (a live fix).** The N3 *logical* mask + and the value-tenant *physical* mask are both `FieldMask(u64)` today — nothing + stops a caller intersecting them and getting a silently-wrong result. Make + them un-intersectable: `FieldMask` vs `FieldMask`. This is a + real defect to close, surfaced by the hardening pass. + +## 4. The address is the zoom + +**CODED-today.** The classid/HHTL cascade is the multi-scale axis: a longer +Morton-nibble prefix is simultaneously a finer tile AND a deeper partonomy node +(`FMA-SKELETON` §2.1: `address_prefix_is_partonomy_containment`, +`morton_address_encodes_laterality`, **[G]**). Planet → organ → cell → +chromosome → gene is **prefix routing** over the **3×4 path** (`D-3X4`, tier = +`nibble >> 2`). The renderer for a node is **resolved *from* the classid** (per +the Non-negotiable "classid is pure address; the magic is what it resolves to") — +the structural signature lives at the resolution target, not in the address bits. + +**LANDING-ZONE.** Renderer-dispatch-*by-signature* across domains (one tube +renderer for VG graphs *and* arterial trees) is a target, not built: +`StructuralSignature` today is a group-by family key, not a renderer selector, +and no tube/mesh/molecular renderer exists yet. A coordinate-free source (a VG +sequence graph has no rest-pose centroid) needs an explicit address-assignment +step before it lands here — that is a future landing zone, named, not a finished +claim. + +## 5. Living substrate; the Firewall-correct egress + +- **Living, not a dump.** ractor gives a **runtime ownership guarantee**: each + actor owns its SoA partition and its mailbox serializes access to that partition + at runtime, so the fleet runs **n actors × up-to-64k partitions concurrently** — + parallel across actors, race-free because each partition has exactly one owner. + This is a *runtime* actor-ownership guarantee (the mailbox is the runtime + serializer), **not** a compile-time borrow proof (`MailboxSoA`, `kanban_actor`). + The graph is live (kanban updates streaming in), not a batch snapshot. +- **JSON-free, Firewall-correct.** **LANDING-ZONE / [H]** (`D-KV-RENDER`, pending + the no-serde probe). The inner path moves **keys** (a tree of keys), content + materializes **only at the egress membrane, exactly once**. The Rust→browser + transport (Arrow IPC / binary columns / rendered HTML) is the **OUTER firewall + crossing** — legitimate boundary tax paid once per crossing (`THE-FIREWALL.md` + §5; ADR-022/023 are **not** violated — there is no Arrow encode on the *inner* + hot path). The JS engine (JSC/V8) is in-process via op/FFI, so the runtime↔Rust + handoff is memory, not a wire. No JSON reconstitution on the core path. + +## 6. The dots, connected + +Parse once per source → sink into classid-keyed SoA → and the jobs that *share +the N3 basis* (read, render, auth-field-projection) come from the same mask, while +query/version/scope stay distinct selectors. Genomics (VG/GFA) is the next +*dissolving* front-end; Odoo/Redmine/OpenProject are the *re-hosting* front-ends +where structure is preserved and behaviour is carried into state machines. The +Askama bitmask field-view is the render-side face of the N3 selector the +substrate already uses to read and project. **An ERP at the cost of an import, +in the same substrate as the anatomy and the genome** — that is the destination, +and the spine of it (sink, N3 selector ×3, address-as-zoom) is shipped today; the +rest is a named set of landing zones, not hand-waving. + +## 7. Honest edges (sharp, not subjunctive) + +1. **Two `FieldMask` bases must be type-separated** (logical N3 vs physical + value-tenant) — a live aliasing defect; `FieldMask`. +2. **Field count widens, it does not block** — `[u64; N]`; the only discipline is + single-source bit generation (`I-LEGACY-API-FEATURE-GATED`). +3. **DO-arm parity is unproven** — gate **F1** (delegation ≡ `_inherit`) must run + before the God-object→adapter "dividend" is more than CONJECTURE. +4. **Cross-domain renderer-by-signature is a landing zone** — needs a coded + signature→renderer map and an address-assignment for coordinate-free sources. +5. **Upper ontology: adopt Biolink**, do not invent the category tree. +6. **First brick (coded surface, not genomics):** render an existing OpenProject + `WorkPackage` / medcare `Patient` row through `ClassView::render_rows(class, + FieldMask)`, proving one N3 mask drives projection *and* render. ~60 LOC; it + promotes the three-job selector claim from CODED-in-parts to end-to-end. ## Cross-references -- `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` — the render-side face of the universal - selector (the pattern this capstone frames). -- §1.5 "the spine is the COMPILED ClassView" — the sink + the read-mask twin. -- `OGAR-AST-CONTRACT.md` — the THINK / DO / membrane arms. -- `OGAR-AS-IR.md` — OGAR as a multi-phase compiler IR. -- `OGAR-CONSUMER-BEST-PRACTICES.md` — the consumer surface these transcodes target. -- `SURREAL-AST-AS-ADAPTER.md` / `core-first-transcode-doctrine` — actions → adapters, - the God-object/SoC dividend. -- `I-LEGACY-API-FEATURE-GATED` — why the universal-selector bits must be generated. +- `lance-graph-contract/src/class_view.rs` (`ClassView`/`FieldMask`/`render_rows`), + `canonical_node.rs` (the physical value-tenant basis), `lance-graph-rbac` + (`authorize_scoped`, `permission.rs::projection`) — the real receipts for §3. +- `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` (this PR) + `integration/CLASSVIEW-MATERIALIZATION-PLAN.md` — the render-side face. +- §1.5 compiled-ClassView spine; `OGAR-AST-CONTRACT.md` (arms); `OGAR-AS-IR.md`. +- `CLASSID-RBAC-KEYSTONE-SPEC.md` **I-K8** (four orthogonal auth axes). +- `THE-FIREWALL.md` §5 + `D-KV-RENDER` (egress is an outer crossing); ADR-022/023/024. +- `D-KEYKV`, `D-3X4`, `D-BOTHCASC`, `FMA-SKELETON` §2.1 (address = zoom, coded); + `I-LEGACY-API-FEATURE-GATED`; `core-first-transcode-doctrine` (leaf-adapter scope). From c09e5cfb59be54c1d81ed781e95ba9e12511ca7b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:46:07 +0000 Subject: [PATCH 4/7] docs(capstone): ractor = COMPILE-time ownership (safety); Lance BatchWriter = throughput Correct the concurrency framing into two distinct mechanisms: - ractor: compile-time ownership guarantee (mailbox-as-owner, Rust move semantics, UB becomes a compile error; E-CE64-MB-4). The SAFETY. n compile-time-owned partitions update in parallel, race-free by construction. - Lance BatchWriter: the THROUGHPUT, and where cognition hides. On initiation, while one SoA batch lowers (persists to Lance), the next batch already thinks (computes) -- compute/persist overlap on a double-buffered SoA; cost ~ max(compute, write), not compute + write. ractor is no longer the straw puppet carrying the concurrency story; it is the compile-time safety, the BatchWriter overlap is the latency-hidden throughput. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md index f0e52df..f770f8d 100644 --- a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -131,13 +131,19 @@ claim. ## 5. Living substrate; the Firewall-correct egress -- **Living, not a dump.** ractor gives a **runtime ownership guarantee**: each - actor owns its SoA partition and its mailbox serializes access to that partition - at runtime, so the fleet runs **n actors × up-to-64k partitions concurrently** — - parallel across actors, race-free because each partition has exactly one owner. - This is a *runtime* actor-ownership guarantee (the mailbox is the runtime - serializer), **not** a compile-time borrow proof (`MailboxSoA`, `kanban_actor`). - The graph is live (kanban updates streaming in), not a batch snapshot. +- **Living, not a dump — and the thinking hides behind the write.** Two + mechanisms, kept distinct (ractor is the *safety*, not the throughput story): + - **Safety — ractor's compile-time ownership guarantee.** The mailbox owns its + SoA partition; Rust move/ownership semantics prove no aliasing / no data race + / no use-after-free **at compile time** — UB becomes a compile *error* + (`MailboxSoA`, `kanban_actor`, E-CE64-MB-4). n compile-time-owned partitions + update in parallel, race-free by construction. + - **Throughput — the Lance `BatchWriter` overlap (where cognition hides).** On + initiation, while one SoA batch **lowers** (its columns persist to Lance), the + next batch is **already thinking** (computing). Compute and persist overlap on + a double-buffered SoA, so the thinking is hidden behind the batch-write + latency — cost ≈ `max(compute, write)`, not `compute + write`. The graph is + live (kanban updates streaming in), not a batch snapshot. - **JSON-free, Firewall-correct.** **LANDING-ZONE / [H]** (`D-KV-RENDER`, pending the no-serde probe). The inner path moves **keys** (a tree of keys), content materializes **only at the egress membrane, exactly once**. The Rust→browser From 7bdb0583f38e8813b6899c426ac8ae4e694e0493 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:58:55 +0000 Subject: [PATCH 5/7] =?UTF-8?q?docs(capstone):=20finalize=20=E2=80=94=20ad?= =?UTF-8?q?d=20orchestration=20&=20cognition=20layer=20(rs-graph-llm=20/?= =?UTF-8?q?=20rig)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DO arm: ActionDef -> StateMachine REALIZED AS an rs-graph-llm workflow graph; control-flow maps node-for-node => DO is lossless; F1 becomes a graph-equivalence check. - New section 6 Orchestration & cognition: ActionDef -> rs-graph-llm graph -> ractor (compile-time execution ownership) -> Lance BatchWriter (overlap); rig = RAG + LLM boundary + thinking-replay; LLM API = removable training wheels; replay distils LLM traces into offline DeepNSM cognition. - Edges: pin the lifecycle owner; use the REAL rs-graph-llm (not the graph-flow stub); offline-replay fidelity is LANDING-ZONE. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 74 +++++++++++++++++++---- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md index f770f8d..22c2600 100644 --- a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -56,15 +56,17 @@ Per `OGAR-AST-CONTRACT.md`: partial → Askama bitmask partial; OpenProject WP schema → `Class` facets. **CODED-today** (`lance-graph-contract/src/class_view.rs`: `ClassView`, `render_rows`, `project`; impl `ogar-class-view`). -- **DO arm — `ActionDef` / `ActionInvocation` → a generated ractor `StateMachine` - (with `KausalSpec` state-guards).** This is the catch that makes "ERP at the - cost of an import" real: Odoo's action methods are **carried into actual state - machines**, not stubbed as stateless adapters. (The "classid-keyed adapter" of - the Core-First doctrine is the *data-shaped leaf-method* lowering only — its - scope boundary; behaviour-bearing actions are the `StateMachine` path.) Foundry - rebuilds these workflows by hand; OGAR transpiles them. **LANDING-ZONE** (the - `Class`→`StateMachine` codegen is specced; gate **F1** — delegation ≡ Odoo - `_inherit` — proves behavioural parity and **has not run yet**; the God-object→ +- **DO arm — `ActionDef` / `ActionInvocation` → a `StateMachine` *realized as an + rs-graph-llm workflow graph*** (with `KausalSpec` state-guards), ractor-owned at + execution and Lance-overlapped (see §6). This is the catch that makes "ERP at + the cost of an import" real **and lossless**: a source action's control-flow + maps **node-for-node** into the graph — carried, not stubbed as a stateless + adapter, not hand-re-implemented. (The "classid-keyed adapter" of the Core-First + doctrine is the *data-shaped leaf-method* lowering only — its scope boundary; + behaviour-bearing actions are the graph/`StateMachine` path.) Foundry rebuilds + these workflows by hand; OGAR transpiles them. **LANDING-ZONE** (the + `Class`→graph codegen is specced; gate **F1** — delegation ≡ Odoo `_inherit` — + is now a **graph-equivalence check** and **has not run yet**; the God-object→ three-way-split "refactor dividend" is **CONJECTURE** until F1 is green). - **DO-arm guard — `KausalSpec`:** the state-guard *field on* `ActionDef` that gates a transition (not a separate co-equal "arm"). @@ -153,7 +155,52 @@ claim. hot path). The JS engine (JSC/V8) is in-process via op/FFI, so the runtime↔Rust handoff is memory, not a wire. No JSON reconstitution on the core path. -## 6. The dots, connected +## 6. Orchestration & cognition — what makes it *runnable*, not just representable + +The substrate above *represents* the ERP; this layer *runs* it. Four execution +layers + one cognition layer, each one job, none carrying another's: + +**Execution (the DO arm, top to bottom):** + +- **`ActionDef`** — the source IR of the behaviour. +- **rs-graph-llm — the action handler + kanban orchestration.** The + `OGAR-AST-CONTRACT` `StateMachine` is *realized as an rs-graph-llm workflow + graph* (nodes = steps/states, edges = transitions/guards). This is why **DO is + lossless**: a source action's control-flow maps **node-for-node** into the + graph. Gate **F1** (behavioural parity ≡ Odoo `_inherit`) is therefore a + **graph-equivalence check**, not a re-implementation. +- **ractor** — owns each node's execution partition **at compile time** (the + safety floor; §5). +- **Lance `BatchWriter`** — persists one batch while the next node already thinks + (the throughput overlap; §5). + +**Cognition (rig + removable training wheels):** + +- **rig** sits behind rs-graph-llm as **RAG + the LLM boundary + thinking-replay** + (LangGraph-style checkpoint / time-travel over graph state). +- **The replay does double duty:** (a) debug-time time-travel over the thought + graph, and (b) the **capture** for offline cognition — replay the + LLM-bootstrapped thought-graphs, distill them into the substrate's own offline + thinking (DeepNSM / the cognitive shader), then **remove the LLM**. +- **The LLM API is training wheels** (optional, offline-first): it generates the + first traces; the replay records them; the substrate learns to regenerate them + offline (DeepNSM's transformer-inference → struct-math, reached by *distillation + through replay*, not from scratch). + +**Honest edges for this layer:** + +- **Pin the lifecycle owner:** the rs-graph-llm graph *is* the `StateMachine`; + ractor owns node *execution*; `ActionDef` is the source IR. Don't let two layers + claim the lifecycle, or the God object reappears. +- **Use the real `rs-graph-llm`, not the `crates/stubs/graph-flow` placeholder** + (architectural-compliance: the lance-graph-stub incident — wire the real crate, + never let the stub become the architecture). +- **Offline-replay *fidelity* is LANDING-ZONE:** whether DeepNSM/VSA replay + reproduces LLM reasoning well enough to drop the wheels is the open + "thinking-is-a-struct" bet. The architecture (LLM optional, replay as bridge) is + the direction; the fidelity is unproven. + +## 7. The dots, connected Parse once per source → sink into classid-keyed SoA → and the jobs that *share the N3 basis* (read, render, auth-field-projection) come from the same mask, while @@ -166,7 +213,7 @@ in the same substrate as the anatomy and the genome** — that is the destinatio and the spine of it (sink, N3 selector ×3, address-as-zoom) is shipped today; the rest is a named set of landing zones, not hand-waving. -## 7. Honest edges (sharp, not subjunctive) +## 8. Honest edges (sharp, not subjunctive) 1. **Two `FieldMask` bases must be type-separated** (logical N3 vs physical value-tenant) — a live aliasing defect; `FieldMask`. @@ -193,3 +240,8 @@ rest is a named set of landing zones, not hand-waving. - `THE-FIREWALL.md` §5 + `D-KV-RENDER` (egress is an outer crossing); ADR-022/023/024. - `D-KEYKV`, `D-3X4`, `D-BOTHCASC`, `FMA-SKELETON` §2.1 (address = zoom, coded); `I-LEGACY-API-FEATURE-GATED`; `core-first-transcode-doctrine` (leaf-adapter scope). +- **Orchestration & cognition (§6):** `rs-graph-llm` (the real crate — the DO action + handler / kanban orchestration graph; **not** `crates/stubs/graph-flow`); `rig` + (RAG + LLM boundary + thinking-replay); DeepNSM / cognitive-shader (the offline + thinking the replay distils into); `OGAR-AST-CONTRACT` `StateMachine` (realized as + the graph). Architectural-compliance: wire the real `rs-graph-llm`, never the stub. From f303573439004104c14aa9a2d6aabbf50e13fa7f Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 20:19:16 +0000 Subject: [PATCH 6/7] docs(capstone): address codex P2s + wire action-auth to lance-graph-rbac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - auth field-projection: downgrade from CODED to [H] cross-repo lag (coded in sibling lance-graph-rbac, but OGAR canon/CLASSID-RBAC-KEYSTONE-SPEC still grades the projecting Allow{scope,mask} CONJECTURE). Don't depend on it as shipped-from-OGAR. (codex P2 #1) - field-count: keep both truths — widening to [u64;N] is a cheap ClassView index (no architectural wall), but shipped code is single-u64 (field_basis_fits_in_one_u64_mask guard; X7/F14), so fields >64 drop TODAY until the widening lands. Tracked limitation, not hidden. (codex P2 #2) - action authorization (verb x class) rides the existing lance-graph-rbac gate (I-K8 axis-1) = the easiest real link; field-projection (axis-4) is the separate pending leg. Added to the s3 table and s6 orchestration layer. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01RhpwkHGgia2TuDFvdnuQdE --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 48 +++++++++++++++-------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md index 22c2600..400336e 100644 --- a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -85,27 +85,35 @@ shipped, single-bit-space selector. Be exact about which jobs it does: |---|---|---|---| | **read** (facet decode) | N3 presence `FieldMask` | compiled reader | **CODED** (`class_view.rs`) | | **render** (field view) | same N3 `FieldMask`, bit-gated loop | compiled template | **CODED** (`render_rows`) | -| **auth field-projection** | same N3 `FieldMask`, OR-folded | role × lo-u16 grant lattice | **CODED** (`lance-graph-rbac::authorize_scoped`, `permission.rs::projection`) | +| **auth field-projection** | same N3 `FieldMask`, OR-folded | role × lo-u16 grant lattice | **[H] — cross-repo lag**: coded in sibling `lance-graph-rbac` (`authorize_scoped`/`field_mask`), but OGAR canon still grades the projecting `Allow{scope,mask}` **CONJECTURE** (`CLASSID-RBAC-KEYSTONE-SPEC` I-K8, `README` `[H]`) | +| **action authorization (verb × class)** | `lance-graph-rbac` verb-gate (I-K8 axis-1) | role × classid | **the easy link** — the DO action handler rides the existing RBAC gate before firing a node; reuse, don't rebuild | | **query** (column pruning) | a **second** `FieldMask` on the **physical value-tenant** basis | the value-slab layout | **CODED but a DIFFERENT basis** (`canonical_node.rs::ValueSchema::field_mask`) | | **version** (V1/V2/V3) | a `classid → ReadMode/ValueSchema` **radix lookup** (not a mask op) | `ENVELOPE_LAYOUT_VERSION` registry | **CODED as a lookup** | | **auth verdict + row-scope** | boolean gate + **AND**-folded scope | RBAC keystone **I-K8** (four orthogonal axes) | **CODED, not the mask** | -**The honest collapse is THREE jobs over the N3 basis — read + render + auth- -field-projection — shipped and tested** (`distinct_roles_carry_disjoint_projections_of_one_class`). -That is the real universal selector, and it is real today. `query` rides a -*second* mask on the physical basis; `version` is a radix lookup; auth's -verdict/scope are ordered folds with a different algebra (AND-scope vs OR- -projection — one mask cannot be both). Collapse the three; keep the others -named-distinct. +**The honest collapse is read + render over the N3 basis — shipped and tested**; +**auth-field-projection is the *same mask* but cross-repo-pending** (coded in +`lance-graph-rbac`, ungraded in OGAR canon — do not depend on it as shipped *from +OGAR* yet). `query` rides a *second* mask on the physical basis; `version` is a +radix lookup; auth's verdict/scope are ordered folds with a different algebra +(AND-scope vs OR-projection — one mask cannot be both). **Action authorization +(verb × class) is the easiest real integration today** — the DO handler calls the +existing `lance-graph-rbac` gate (I-K8 axis-1) before firing a node; field- +projection (axis-4) is the separate, still-pending leg. Collapse the genuinely- +shared jobs; keep the rest named-distinct. **Two disciplines (both load-bearing, neither a blocker):** -1. **Field count is a representation parameter, not a ceiling.** A presence mask - is `[u64; N]` — `[u64; 4]` = 256 fields, wider as needed; Odoo's 109-field - `account.move` is a `[u64; 2]`, not a wall. Widen the basis; the algebra is - unchanged. *(`I-LEGACY-API-FEATURE-GATED` still applies: `field ↔ idx ↔ bit` - must be generated from one source, never hand-numbered, or a version bump - re-aliases bits.)* +1. **Field count is a representation parameter, not an architectural ceiling — but + it is NOT widened in shipped code yet.** Widening the presence mask to `[u64; N]` + (`[u64; 4]` = 256; Odoo's 109-field `account.move` = `[u64; 2]`) is a cheap + **ClassView-index** change — the algebra is unchanged, nothing structural costs. + **Today, however, the implementation is a single `u64`** (`ogar-class-view` + guard `field_basis_fits_in_one_u64_mask`; `INTEGRATION-MAP` X7/F14 track the + 109-field case as a live blocker), so until the widening lands, **fields beyond + 64 silently drop in the current render path**. Cheap to fix, not yet fixed — a + tracked limitation (X7/F14), not a wall. *(`I-LEGACY-API-FEATURE-GATED` still + applies: `field ↔ idx ↔ bit` generated from one source, never hand-numbered.)* 2. **The two bases must be type-separated (a live fix).** The N3 *logical* mask and the value-tenant *physical* mask are both `FieldMask(u64)` today — nothing stops a caller intersecting them and getting a silently-wrong result. Make @@ -169,6 +177,11 @@ layers + one cognition layer, each one job, none carrying another's: lossless**: a source action's control-flow maps **node-for-node** into the graph. Gate **F1** (behavioural parity ≡ Odoo `_inherit`) is therefore a **graph-equivalence check**, not a re-implementation. +- **Authorization — ride the existing `lance-graph-rbac` (the easiest link).** + Before a node fires, the handler authorizes the action through + `lance-graph-rbac`'s **verb × class** gate (RBAC keystone **I-K8 axis-1**) — + reuse, don't build a parallel auth path. (Field-projection masking, axis-4, is + the separate still-pending leg; see §3.) - **ractor** — owns each node's execution partition **at compile time** (the safety floor; §5). - **Lance `BatchWriter`** — persists one batch while the next node already thinks @@ -217,8 +230,11 @@ rest is a named set of landing zones, not hand-waving. 1. **Two `FieldMask` bases must be type-separated** (logical N3 vs physical value-tenant) — a live aliasing defect; `FieldMask`. -2. **Field count widens, it does not block** — `[u64; N]`; the only discipline is - single-source bit generation (`I-LEGACY-API-FEATURE-GATED`). +2. **Field count widens *cheaply* (`[u64; N]`) but is *not widened yet*** — shipped + code is single-`u64` (`field_basis_fits_in_one_u64_mask` guard; X7/F14), so + fields >64 drop today until the (cheap, ClassView-index) widening lands. Not a + ceiling, a tracked limitation. Discipline: single-source bit generation + (`I-LEGACY-API-FEATURE-GATED`). 3. **DO-arm parity is unproven** — gate **F1** (delegation ≡ `_inherit`) must run before the God-object→adapter "dividend" is more than CONJECTURE. 4. **Cross-domain renderer-by-signature is a landing zone** — needs a coded From 62e380a5fe72f179d86060286942dca3176016ce Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 20:24:47 +0000 Subject: [PATCH 7/7] docs(capstone): RBAC verb-gate is hardcoded const in OGAR [G], not just rbac reuse; add Tuersteher AGI-gatekeeper payoff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §3 action-auth row + prose: required_role is a compile-time const on the ActionDef in lance-graph-ogar/src/actions.rs ([G]-tested), most-shipped of the auth jobs; lance-graph-rbac supplies only the runtime grant map. - §6 Authorization bullet: RBAC hardcoded on the class = the Tuersteher floor (def-match -> RBAC -> Libet -> MUL in commit); cognition decides above it, never lowers it. - §6 punchline: capability-bounding not alignment-bounding -> thinking can upgrade to AGI, OGAR still gatekeeps every action structurally (closed DO surface + unforgeable commit gate). The legible pitch for compliance buyers. - cross-ref ACTIONHANDLER-TURSTEHER.md + actions.rs receipt. --- docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md | 46 ++++++++++++++++++----- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md index 400336e..c32d2ea 100644 --- a/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md +++ b/docs/OGAR-SEMANTIC-TRANSPILER-CAPSTONE.md @@ -86,7 +86,7 @@ shipped, single-bit-space selector. Be exact about which jobs it does: | **read** (facet decode) | N3 presence `FieldMask` | compiled reader | **CODED** (`class_view.rs`) | | **render** (field view) | same N3 `FieldMask`, bit-gated loop | compiled template | **CODED** (`render_rows`) | | **auth field-projection** | same N3 `FieldMask`, OR-folded | role × lo-u16 grant lattice | **[H] — cross-repo lag**: coded in sibling `lance-graph-rbac` (`authorize_scoped`/`field_mask`), but OGAR canon still grades the projecting `Allow{scope,mask}` **CONJECTURE** (`CLASSID-RBAC-KEYSTONE-SPEC` I-K8, `README` `[H]`) | -| **action authorization (verb × class)** | `lance-graph-rbac` verb-gate (I-K8 axis-1) | role × classid | **the easy link** — the DO action handler rides the existing RBAC gate before firing a node; reuse, don't rebuild | +| **action authorization (verb × class)** | `required_role` **`const` on the `ActionDef`** (OGAR DO surface) + runtime grant map | OGAR class (the required role) × `lance-graph-rbac` (who holds it) | **CODED in OGAR `[G]`** — `required_role` is a compile-time literal on every mutating action (`lance-graph-ogar/src/actions.rs`, test `…hardcoded_rbac_on_every_mutating_action`); rbac supplies only the runtime *grant map* | | **query** (column pruning) | a **second** `FieldMask` on the **physical value-tenant** basis | the value-slab layout | **CODED but a DIFFERENT basis** (`canonical_node.rs::ValueSchema::field_mask`) | | **version** (V1/V2/V3) | a `classid → ReadMode/ValueSchema` **radix lookup** (not a mask op) | `ENVELOPE_LAYOUT_VERSION` registry | **CODED as a lookup** | | **auth verdict + row-scope** | boolean gate + **AND**-folded scope | RBAC keystone **I-K8** (four orthogonal axes) | **CODED, not the mask** | @@ -97,10 +97,13 @@ shipped, single-bit-space selector. Be exact about which jobs it does: OGAR* yet). `query` rides a *second* mask on the physical basis; `version` is a radix lookup; auth's verdict/scope are ordered folds with a different algebra (AND-scope vs OR-projection — one mask cannot be both). **Action authorization -(verb × class) is the easiest real integration today** — the DO handler calls the -existing `lance-graph-rbac` gate (I-K8 axis-1) before firing a node; field- -projection (axis-4) is the separate, still-pending leg. Collapse the genuinely- -shared jobs; keep the rest named-distinct. +(verb × class) is the *most* shipped of these — the required role is a hardcoded +`const` on the `ActionDef` in OGAR's own DO surface** (`lance-graph-ogar/src/actions.rs`, +`[G]`-tested: every mutating action carries `Some(role)`), so the grant surface is +`grep required_role`, not a policy table; `lance-graph-rbac` supplies only the +runtime grant *map* (which actor holds the role). Field-projection (axis-4) is the +separate, still-pending leg. Collapse the genuinely-shared jobs; keep the rest +named-distinct. **Two disciplines (both load-bearing, neither a blocker):** @@ -177,11 +180,15 @@ layers + one cognition layer, each one job, none carrying another's: lossless**: a source action's control-flow maps **node-for-node** into the graph. Gate **F1** (behavioural parity ≡ Odoo `_inherit`) is therefore a **graph-equivalence check**, not a re-implementation. -- **Authorization — ride the existing `lance-graph-rbac` (the easiest link).** - Before a node fires, the handler authorizes the action through - `lance-graph-rbac`'s **verb × class** gate (RBAC keystone **I-K8 axis-1**) — - reuse, don't build a parallel auth path. (Field-projection masking, axis-4, is - the separate still-pending leg; see §3.) +- **Authorization — RBAC is hardcoded on the class (`[G]`); the Türsteher floor.** + Each mutating `ActionDef` carries its `required_role` as a compile-time `const` + (`lance-graph-ogar/src/actions.rs`) — the grant surface is `grep required_role`, + legible to a compliance reviewer who never reads the semantics. The handler + adjudicates `def-match → RBAC → state-guard (Libet) → MUL` inside `commit`; + cognition decides *above* that floor and can never lower it. `lance-graph-rbac` + supplies the runtime grant *map* (who holds the role); field-projection (axis-4) + is the separate still-pending leg (see §3). Full doctrine: + `ACTIONHANDLER-TURSTEHER.md`. - **ractor** — owns each node's execution partition **at compile time** (the safety floor; §5). - **Lance `BatchWriter`** — persists one batch while the next node already thinks @@ -213,6 +220,21 @@ layers + one cognition layer, each one job, none carrying another's: "thinking-is-a-struct" bet. The architecture (LLM optional, replay as bridge) is the direction; the fidelity is unproven. +**The Türsteher payoff — the smaller story that sells without the rest.** The +cognition above can upgrade all the way to AGI; OGAR still contains it +*structurally, not by trust*. The bound is **capability-bounding, not alignment- +bounding**: an arbitrarily-clever agent acts only through `const ActionDef`s that +exist, with `required_role`s it cannot edit, through a `commit` gate it cannot +bypass — the DO surface is **closed at the Core** (no runtime "register a new +action" path; the manifest is harvested and reviewed), and move/ownership +semantics make the gate unforgeable (the Firewall, ADR-022/023). So the whole +stack carries a second, smaller pitch that needs *none* of the substrate vision to +land: **the thinking can become anything; OGAR is the gatekeeper that gets +everything which tries to act.** That is the legible artifact for the compliance +buyer who does not (yet) care about transpilation, anatomy, or genomes — +`ACTIONHANDLER-TURSTEHER.md` §5, *"OGAR kriegt sie alle"*, `[H]` (the falsifier: +any path reaching an external mutation without transiting `commit`). + ## 7. The dots, connected Parse once per source → sink into classid-keyed SoA → and the jobs that *share @@ -253,6 +275,10 @@ rest is a named set of landing zones, not hand-waving. - `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` (this PR) + `integration/CLASSVIEW-MATERIALIZATION-PLAN.md` — the render-side face. - §1.5 compiled-ClassView spine; `OGAR-AST-CONTRACT.md` (arms); `OGAR-AS-IR.md`. - `CLASSID-RBAC-KEYSTONE-SPEC.md` **I-K8** (four orthogonal auth axes). +- `ACTIONHANDLER-TURSTEHER.md` — RBAC-as-class-`const` doctrine, the Rung + Flughöhe, and the structural-containment (`OGAR kriegt sie alle`) claim; + `lance-graph-ogar/src/actions.rs` (`OgarActionProvider`, the hardcoded + `required_role` surface + its `[G]` test). - `THE-FIREWALL.md` §5 + `D-KV-RENDER` (egress is an outer crossing); ADR-022/023/024. - `D-KEYKV`, `D-3X4`, `D-BOTHCASC`, `FMA-SKELETON` §2.1 (address = zoom, coded); `I-LEGACY-API-FEATURE-GATED`; `core-first-transcode-doctrine` (leaf-adapter scope).