Skip to content

Commit e62f1c1

Browse files
authored
Merge pull request #617 from AdaWorldAPI/claude/medcare-bridge-lance-graph-wmx76z
knowledge(ast-address): the three-layer "why" — rails-shaped semantic AST → importable OGIT ERP primitives
2 parents b7eb02c + e34a7fa commit e62f1c1

1 file changed

Lines changed: 186 additions & 0 deletions

File tree

.claude/knowledge/ast-as-partof-isa-address.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

55241
1. **An AST has exactly two structural relations, and they ARE the two tile axes.**

0 commit comments

Comments
 (0)