@@ -50,6 +50,192 @@ source (C#/…) ──ruff_*_spo harvest──► SPO triples ──► AR-shape
5050 ruff-lsp ──► editor
5151```
5252
53+ ## The purpose — the three-layer thesis (the * why* , grounded in shipped code)
54+
55+ The * what* above (store the AST as a ` (part_of:is_a) ` address) exists to serve
56+ one economic end: ** make minting an ERP in any consumer as cheap as importing
57+ pre-minted class primitives.** Three layers, each already backed by shipped
58+ contract code (verified this session):
59+
60+ ### Layer 1 — rails-shaped semantic AST at * assembler* cost
61+
62+ The structural AST's queries collapse to ** one hardware instruction each** ,
63+ because the node's identity * is* a 128-bit register (` facet::FacetCascade ` ) and
64+ the semantic operations * are* its four SIMD lanes:
65+
66+ | LSP / semantic query | ` (part_of:is_a) ` operation | assembler (facet.rs four-lane table) |
67+ | --- | --- | --- |
68+ | ` definition ` (symbol → node) | full-facet equality | ` vpcmpeqd ` + ` vmovmskps ` (row lane) |
69+ | ` documentSymbol ` (part_of tree) | ` hi_chain() ` compare | ` vpcmpeqw ` / ` pshufb ` (tile lane) |
70+ | ` typeHierarchy ` (is_a lattice walk) | ` lo_chain() ` longest-common-prefix | ` vpxor ` + ` tzcnt ` (prefix lane) |
71+ | ancestry / quadrant containment | Morton nibble prefix | GFNI ` vgf2p8affineqb ` (nibble lane) |
72+
73+ A graph traversal becomes a register XOR + trailing-zero count. ** Why the rails
74+ shape is the precondition, not a style choice:** a * declarative* class body (a
75+ flat bag of typed ` part_of | is_a ` declarations) maps onto fixed-width 6×(8:8)
76+ tiles; an * imperative* syntax tree (variable-arity, positional) does not. Only
77+ the declarative ** THINK arm** flattens to the address.
78+
79+ ### Layer 2 — static OGAR shape · dynamic ClassView · askama row-view
80+
81+ ` class_view.rs ` already states this exact ladder (its own doc comment):
82+
83+ ```
84+ SoA row = the XML document (agnostic bytes, no meaning)
85+ class / ObjectView = the XSD schema (the shape: which fields, in order)
86+ ClassView = the parser+schema (projects row → typed view, late-bound)
87+ askama template = the XSLT (renders the projected view)
88+ ```
89+
90+ Two shipped invariants make the static shape * reusable* and let it evolve like
91+ Redmine's 17-year row view without breaking persisted data:
92+
93+ - ** C2 — presence, NEVER semantics.** ` has(n) ` = "field n is populated here,"
94+ never "field n behaves differently here." Per-app variation lives in the
95+ ClassView projection + the askama template (the * render* ), never in the bits.
96+ - ** N3 — append-only field positions.** "Once instances persist, a field's bit
97+ position never moves and retired bits are never reused." * This is the
98+ mechanism* behind a row view that grows columns for 17 years without
99+ invalidating a single stored row.
100+
101+ ** View and action are duals of one ClassView.** A node's SoA value slab holds
102+ ** N × ` (facet_classid | 6×(8:8 part_of:is_a)) ` ** facets (the value-tenant
103+ migration's multiple tenants per node) plus a * little* DO. The ClassView projects
104+ those same static facets ** two** ways: row → typed ** view** (THINK → askama
105+ render) ** and** row → conditional ** classaction** (DO → an ` ActionDef ` fired under
106+ a ` KausalSpec ` ` StateGuard{field,value} ` that reads the SoA's own bits). So
107+ behavior is conditionalized * at the cost of one ClassView classaction dispatch* —
108+ a guard-read (assembler-cheap, exactly like the view projection) + an ` ActionDef `
109+ lookup by ` classid ` . Render and behavior are the two projections of one ClassView
110+ over one static SoA; the DO arm is as cheap and as reusable as the THINK arm
111+ because it is the ** same** projection mechanism — only the * little* DO needs to
112+ ride along, conditionalized, not a parallel engine.
113+
114+ ** In the consumer, DO is a classaction * pointer* , not logic.** Because the
115+ ontology→class conversion is lossless, a class identity is preserved bijectively
116+ * across* consumers — so its behavior need not be re-implemented, only * pointed
117+ at* . With separation of concerns + a DTO-carried invocation, the DO arm collapses
118+ in the consumer to an ** object-oriented reusable classaction pointer** : `classid
119+ → ActionDef` (the target = shared behavior, minted once), dispatched via an
120+ ` ActionInvocation ` DTO (` realizes → ActionDef.identity ` ; carries
121+ ` object_instance ` , ` idempotency_key ` , ` state ` ). The consumer holds only the
122+ * pointer* (` classid ` address) + its per-app ` KausalSpec ` guard (the * when/which* )
123+ + its own content; the * what* (the ` ActionDef ` body) lives once at the resolution
124+ target. This is exactly the ** OGAR consumer doctrine** — * the ` classid ` is pure
125+ address; the class-magic (` ActionDef ` +` KausalSpec ` ) is a property of the Core node
126+ the address resolves to, never of the address* (` ogar-consumer-preflight.md ` ). A
127+ vtable/strategy slot whose implementation is a universal OGAR primitive — and the
128+ lossless bijection is precisely what guarantees the pointer resolves to the
129+ * same* target for every consumer.
130+
131+ ` openproject-nexgen-rs ` (` op-codegen-projection ` ) and ` woa-rs ` already pull
132+ ` askama 0.12 ` — the render end is live.
133+
134+ ### Layer 3 — OGAR as importable ERP-primitive stdlib · lance as the compiler
135+
136+ ` ogar_codebook.rs ` is the import surface — a curated ` (concept, u16) ` codebook,
137+ ** wire-compatible, zero-dep** (a consumer * stamps* an id, never links a Core):
138+
139+ | economic step | shipped surface |
140+ | --- | --- |
141+ | ** import** a primitive | ` canonical_concept_id("account.move") → u16 ` → ` classid ` → ` ClassView ` |
142+ | ** customize** for an app | ` render_classid_for_concept(app_prefix, concept) ` — compose shared concept (lo u16, canon) with the consumer's render skin (hi u16, custom) |
143+ | ** compile** to a running app | lance-graph (OGAR-as-IR): ` classid → ClassView → askama ` |
144+
145+ ** Cost collapse:** transcode goes from O(whole app, hand-ported) to O(the
146+ consumer's * deltas* from the imported primitive). ` account.move ` /
147+ ` res.partner ` / OpenProject ` Issue ` / MedCare ` Patient ` are minted ** once** in
148+ OGAR (harvest → ` facet_mint ` ) and reused by every consumer.
149+
150+ ** The magnitude:** OpenProject is ** ~ 500K LOC** of Rails. Under this model a
151+ consumer's * marginal* cost collapses from "re-transcode ~ 500K LOC" to "import the
152+ OGIT class primitives + wire classaction pointers + per-app content & ` KausalSpec `
153+ guards." The primitive-mint is a real * one-time* cost, but it is ** amortized
154+ across every consumer** — MedCare / WoA / SMB / Odoo / OpenProject-nexgen all draw
155+ the * same* OGIT patterns (the regulatory ` NTO/{Audit, Compliance, Legal} ` set
156+ imported once; cf. boundary #1 ). That magnitude — "much cheaper than 500K LOC" —
157+ is precisely the CONJECTURE's payoff, and the brick-3 probe (MedCare harvest →
158+ mint → SoA → LSP query, MedCareV2 oracle) is what turns it from a claim into a
159+ measurement.
160+
161+ ** Headline target (CONJECTURE — the probe measures it):** OpenProject + Odoo
162+ together as ** ~ 2 MB of GUID-encoded ` (part_of:is_a) ` ** instead of ~ 20 MB / ~ 250K
163+ LOC — a ~ 10× collapse. Dimensionally credible: at 16 B/` FacetCascade ` ,
164+ 2 MB ≈ ** 131K class/member/field nodes** , enough to hold both ERPs' structural
165+ skeleton. The honest caveat: that 2 MB is the ** THINK-arm structure + classaction
166+ pointers** ; the DO-arm ` ActionDef ` * bodies* don't vanish — they are minted ** once**
167+ in OGAR and shared (amortized across every consumer), so the figure is the
168+ * per-consumer marginal* footprint over a shared primitive library, not the whole
169+ system reduced to 2 MB. The 10× ratio is the hypothesis the MedCare probe gives
170+ the first real datapoint for.
171+
172+ ** What the primitives actually are: laws and regulations, not CRUD shapes —
173+ content stays with the consumer.** An ERP's hard value is * compliance* (tax law,
174+ audit/GoBD immutability, SKR04 accounts, sanctions/AML, HIPAA), and regulation is
175+ ** universal** (jurisdiction-wide) and ** reusable** (every consumer in that
176+ jurisdiction needs it). So the importable primitive is the * law as a static
177+ pattern* — its legally-required fields/relations as an ` ObjectView ` , its
178+ regulatory rules as ` ActionDef ` /` KausalSpec ` guards — minted once, pulled by
179+ every consumer. The ** content** (this company's invoices, this clinic's patients)
180+ stays with the consumer (per ` I-VSA-IDENTITIES ` : bundle identities, store content
181+ in the consumer's own stores); only the ** pattern** is shared. This is grounded:
182+ OGIT already carries regulation-as-pattern in ` NTO/{Audit, Compliance, Legal} `
183+ (e.g. ` Compliance/{SanctionsEntry, legalBasis, sanctionedUnder, financiallySupports} ` ).
184+
185+ The enabling result (operator-proven; attributed, not re-verified here):
186+ ** classes convert bijectively and losslessly between OWL (the W3C ontology
187+ standard regulatory ontologies ship in — e.g. FIBO) and OGIT.** The mechanism is
188+ structural — OGIT's ` {entities, verbs, attributes} ` * is* the ` (part_of:is_a) `
189+ shape (entity → class, attribute → ` part_of ` field, verb → ` is_a ` /relation) — so
190+ a standard regulatory ontology published in OWL imports losslessly into the OGAR
191+ ` ClassView ` . ** Honest scope:** the bijection is over ** classes** (the THINK-arm
192+ structure — the legally-required fields); the regulatory * rules* (when a tax
193+ applies, an audit guard fires) ride the DO arm (` ActionDef ` /` KausalSpec ` ,
194+ wireable + membrane-governed per #2 below). What's local-verified is OGIT's
195+ regulatory namespaces + its native ` (part_of:is_a) ` shape; the formal
196+ OWL↔OGIT bijection proof is the operator's prior result, cited not re-run.
197+
198+ ### The three honest boundaries (so this isn't a promise it can't keep)
199+
200+ 1 . ** Mechanism shipped; the pattern * source* is imported — the * mint* is the
201+ remaining step.** Earlier framings said "stdlib mostly empty"; that's now
202+ too pessimistic. ** Complete OGIT is imported into OGAR** at
203+ ` OGAR/vocab/imports/ogit/ ` — ** ~ 1,940 TTL** across the full ` NTO ` (incl.
204+ ` Audit ` / ` Compliance ` / ` Legal ` / ` Security ` ) ** plus** the ` SDF ` automation
205+ schemas (` Automation/{event, change, incident, requirement} ` — the HIRO
206+ ActionHandler lineage, i.e. DO-arm source too). So the regulatory-pattern
207+ * source* is in place. What remains is ** minting** that source into
208+ ` FacetCascade ` codebook primitives (` facet_mint ` → publish to
209+ ` ogar_codebook ` ): the bricks all exist (` ruff_*_spo ` , ` facet_mint ` , the OGIT
210+ TTL/JSON input) — the ** source → codebook wire** is the work, not the
211+ harvest.
212+ 2 . ** The DO arm is * also* wireable — behavior has an OGAR shape too.** (An
213+ earlier framing treated behavior as bespoke; that is too pessimistic.) The DO
214+ arm has its own OGAR IR — ` ActionDef ` / ` ActionInvocation ` / ` KausalSpec `
215+ (` OGAR-AST-CONTRACT.md ` ) — and the ** arago/HIRO ActionHandler** model
216+ transcodes into exactly it (the OGIT ontology * is* arago/almato's — TTL
217+ creator ` chris.boos@almato.com ` ). An action handler becomes an ` ActionDef `
218+ keyed by ` classid ` , realized as an ` ActionInvocation ` with a lifecycle
219+ ` ActionState ` machine, guarded by ` KausalSpec ` . So behavior is
220+ mint-and-import-able on the ** same** mechanism as the THINK arm — ` odoo-rs ` 's
221+ ` od-posting ` becomes a * consumer* of imported ` ActionDef ` s, not hand-written
222+ logic. (Consistent with the boundary section below: behavior is keyed * by* the
223+ address as ` ActionDef ` , never flattened * into* it.) ** The remaining honesty —
224+ not a wall:** (a) same stdlib-population maturity as #1 — the IR + transcode
225+ path exist; the * published* per-domain action library is the work; (b) DO
226+ composition is ** ` KausalSpec ` -membrane-governed** (StateGuard / lifecycle /
227+ dependency-path) by design — behavior is reusable but its wiring is gated and
228+ auditable, not free code import. That governance is the feature, not the gap.
229+ The * conditionalization* (which ` ActionDef ` fires, when) is classaction-cheap
230+ — a guard-read + a ` classid ` dispatch; only an ` ActionDef ` 's * internal* compute
231+ (e.g. a tax algorithm) is still its content, imported as a primitive rather
232+ than re-derived per consumer.
233+ 3 . ** Cheapness requires pull-don't-reconstruct.** Holds only if consumers
234+ ** import** (` canonical_concept_id ` / ` *Port::class_id ` ) rather than
235+ re-harvest or copy the codebook — the ` ogar-consumer-preflight ` iron rule.
236+ The moment a consumer rebuilds the class graph locally, the cost is paid
237+ twice (the do-it-twice / SURREAL-AST trap this whole design rejects).
238+
53239## Why this is the convergence, not a detour
54240
552411 . ** An AST has exactly two structural relations, and they ARE the two tile axes.**
0 commit comments