Skip to content

Commit 283bd6c

Browse files
authored
Merge pull request #104 from AdaWorldAPI/claude/ogar-as-ir
docs(framing): OGAR as IR — the compiler framing as a one-pager
2 parents 561c7bb + 5e94226 commit 283bd6c

4 files changed

Lines changed: 105 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ alignment costs. Until measured: 3×4 stands.
198198
an anti-pattern catalogue paired with the right shapes. MANDATORY
199199
before authoring any consumer call site that mentions `class_id`,
200200
`APP_PREFIX`, `PortSpec`, `ClassView`, or any `*Bridge`/`UnifiedBridge`.
201+
9. `docs/OGAR-AS-IR.md` — the **compiler framing.** lance-graph is a
202+
multi-phase compiler whose IR is OGAR; this doc names the phases
203+
(front-end / symbol table / linker / semantic analysis / optimization
204+
/ codegen back-ends / native codegen / runtime), restates each existing
205+
doctrine in compiler vocabulary, lists six IR-shape tests new design
206+
must pass, and labels every prior design doc as already-compiler-shaped.
207+
READ BEFORE adding a field to `Class`, a variant to `ActionDef`, a
208+
slot to `KausalSpec`, a new lowering pass, or any other IR-surface
209+
change. The framing changes no existing decision; it changes every
210+
future one.
201211
8. `docs/ARCHITECTURAL-DECISIONS-2026-06-04.md` — ADR-001..025
202212
(ADR-026 pending).
203213
9. `.claude/agents/` — the 5+3 hardening pattern (5 research savants +

README.de.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Auth — führe KEINE `*Bridge` als Notlösung wieder ein.
8282

8383
| Wächter | Lesen vor |
8484
|---|---|
85+
| [OGAR als IR](docs/OGAR-AS-IR.md) | Entwurf jeder IR-Erweiterung (neues `Class`-Feld, `ActionDef`-Variante, `KausalSpec`-Slot, Lowering-Pass) |
8586
| [Consumer Best Practices](docs/OGAR-CONSUMER-BEST-PRACTICES.md) | jeder Consumer-Aufrufstelle (classid · `APP_PREFIX` · `ClassView` · `*Bridge`) |
8687
| [SurrealQL-AST-Fallen-Pre-Flight](docs/SURREAL-AST-TRAP-PREFLIGHT.md) | Producer→IR · Transcode · Codegen · `.surql`-Authoring |
8788
| [SurrealQL-AST als Adapter](docs/SURREAL-AST-AS-ADAPTER.md) | Entscheidung Rückgrat vs. Adapter |

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Until it ships, keep existing auth — do NOT re-introduce a `*Bridge` as a stop
8080

8181
| Guard | Read before |
8282
|---|---|
83+
| [OGAR as IR](docs/OGAR-AS-IR.md) | designing any IR addition (a new `Class` field, `ActionDef` variant, `KausalSpec` slot, lowering pass) |
8384
| [Consumer best practices](docs/OGAR-CONSUMER-BEST-PRACTICES.md) | any consumer call site (classid · `APP_PREFIX` · `ClassView` · `*Bridge`) |
8485
| [SurrealQL-AST trap pre-flight](docs/SURREAL-AST-TRAP-PREFLIGHT.md) | producer→IR · transcode · codegen · `.surql` authoring |
8586
| [SurrealQL AST as adapter](docs/SURREAL-AST-AS-ADAPTER.md) | deciding spine vs. adapter |

docs/OGAR-AS-IR.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# OGAR as IR — the compiler framing
2+
3+
> **For designers and reviewers.** lance-graph is a multi-phase compiler
4+
> whose IR is OGAR. Every existing architectural decision in this repo
5+
> restates a standard compiler discipline. New decisions should pass the
6+
> IR-shape tests in §3 before landing.
7+
>
8+
> Status: **FRAMING v1** (2026-06-22).
9+
10+
This doc is a *lens*, not a rule. It does not add a new abstraction
11+
layer; it labels the layer that is already here, in vocabulary that has
12+
been field-tested for fifty years of compiler engineering. Reach for the
13+
labels when designing; reach for the tests when reviewing.
14+
15+
---
16+
17+
## §1. The mapping
18+
19+
| Compiler phase | OGAR / lance-graph piece |
20+
|---|---|
21+
| Source readers / front-end parsers | `ogar-from-ruby` (`ruff_ruby_spo`) · `ogar-from-python` · `ogar-from-elixir` · `ogar-sql-ddl` · future readers |
22+
| AST / IR | `ogar-vocab::{Class, ActionDef, ActionInvocation, KausalSpec, Identity}` |
23+
| Symbol table | `ogar-vocab::class_ids` + `ports::*Port` alias tables |
24+
| Linker / name resolution | cross-fork convergence — `Stundenzettel` / `TimeEntry` / `HrAttendance` resolve to the same `0x0103` symbol |
25+
| Public ABI / wire-compat surface | `lance_graph_contract::ogar_codebook` — the BBB membrane, zero-`ogar-vocab` mirror, parity-tested against the canonical table |
26+
| Semantic analysis | `lance-graph-ontology` (registry validity); the pending `lance-graph-rbac::authorize` keystone |
27+
| Optimization passes | `lance-graph-planner` — 16 strategies, ontology-aware traversal, thinking-style selection |
28+
| Codegen back-ends | `ogar-adapter-surrealql` (DDL) · `ogar-to-postgres` · `ogar-to-openapi` · `ogar-to-typescript` · the SoA columnar back-end (Arrow IPC / Lance) |
29+
| Native codegen | `jitson` (Cranelift) compiling the 36 thinking-style scan kernels into native machine code |
30+
| Runtime / dynamic linking | `lance-graph-callcenter` dispatching messages to `ogar/Class` actors |
31+
32+
---
33+
34+
## §2. Existing decisions, restated in compiler vocabulary
35+
36+
Each principle this repo already pins, re-named so future contributors reach for the right primitive:
37+
38+
| Rule as the repo states it | Standard compiler primitive |
39+
|---|---|
40+
| "The classid is pure address; the magic is what it resolves to." | **SSA value-id with a symbol table.** The id names the value; the table behind it carries the type, the methods, the effects. |
41+
| "Behaviour flows producer → OGAR `Class`+`ActionDef` → adapter; never producer → DDL." | **No `eval` at codegen time.** Lowering passes emit; they do not interpret. The IR is the source of truth. |
42+
| "Spine vs membrane — the BBB-barrier." | **Internal IR types vs public ABI.** Membrane consumers link against the wire-compat mirror; spine-internal can use the full IR. |
43+
| "One concept, many renders." | **Same canonical symbol, multiple lowering targets.** Compile once, emit N. |
44+
| "SurrealQL DDL is an adapter, not the spine." | **A codegen back-end is not the IR.** Putting lifecycle in DDL = encoding the source program inside the assembly output. |
45+
| "The adapter is lossy on the behavioural arm." | **Codegen back-ends discard IR information the target cannot represent.** DDL has no FSM vocabulary, so the behavioural arm cannot survive lowering. |
46+
| "Pull the classid; never re-mint the Core." | **Link against the symbol table; do not fork it.** Local copies drift on the next symbol-table version. |
47+
| "Append-only canon; regrade in place." | **Symbol ids are stable across versions.** A symbol once minted is never re-numbered. |
48+
| "No serialization in the hot path." | **IR is the runtime wire-truth; there is no parse step at runtime.** Compiled output runs, not source code. |
49+
| "RBAC is a relation, not a stamp — classid + role + membership." | **Authorization is a semantic-analysis pass over the IR.** It verifies a property; it does not invent one. |
50+
51+
---
52+
53+
## §3. Six tests for new IR design
54+
55+
Before adding a field to `Class`, a variant to `ActionDef`, a slot to `KausalSpec`, or any other surface that future producers and back-ends will need to round-trip — a proposal must pass these six tests.
56+
57+
1. **SSA / dataflow-explicit.** Each operand and result is a named value. No implicit hidden state. Lifecycle transitions in `KausalSpec` traverse as a control-flow graph: basic blocks, edges, joins at phi-shaped merge points.
58+
2. **Effect annotations are first-class.** Each `ActionDef` declares what it reads, what it writes, what side effects it has (audit, network, persistence, mutation). Pure-vs-effectful is a *type*, not a comment. Without this, no optimization is sound.
59+
3. **Typed signature, not field bag.** `Class.attributes` is a typed signature: every attribute carries a stable type symbol from the type system, not an opaque string blob. The structural arm IS the type system.
60+
4. **Lowering passes are named, not implicit.** Each back-end is an explicit pass with a stated signature `IR → target`. Adapters are lowering passes; they do not transform the IR. If a back-end needs IR changes, the IR changes come first, then the lowering.
61+
5. **Optimization passes declare a semantic-preservation guarantee.** Each transformation states what it preserves: "observable behaviour modulo X." A pass without a guarantee is a rewriter, not an optimizer.
62+
6. **The IR is the canonical artifact.** Source ASTs and target outputs are interchangeable over time; only the IR is preserved. If a design lets a target dialect creep into the IR, it is conflating layers and will rot at the next back-end.
63+
64+
A proposal that fails any test is not rejected — it is **rerouted**. The right place for the proposed structure may be the source reader (a parsing concern), the back-end (a lowering concern), or the optimizer (an analysis result) — but it is *not* the IR. Keep the IR small, typed, dataflow-explicit, effect-annotated.
65+
66+
---
67+
68+
## §4. Cross-references — already compiler-shaped, now labeled
69+
70+
The docs below were already compiler-shaped in design. This framing makes the labels explicit so future contributors can reach for the right vocabulary.
71+
72+
| Doc | What it is, in compiler vocabulary |
73+
|---|---|
74+
| [THE-FIREWALL.md](THE-FIREWALL.md) (ADR-022/023) | "No serialization in the hot path" = **IR is the runtime wire-truth; there is no parse step.** Compiled output runs, not source. |
75+
| [OGAR-AST-CONTRACT.md](OGAR-AST-CONTRACT.md) | The typed IR header — the OGAR equivalent of an LLVM IR include. `Class`/`ActionDef`/`Identity`/`KausalSpec` are the IR node kinds. |
76+
| [SURREAL-AST-AS-ADAPTER.md](SURREAL-AST-AS-ADAPTER.md) | The carved decision that DDL is a **codegen back-end, not the IR**. The structural arm lowers; the behavioural arm cannot survive lowering and stays in the IR. |
77+
| [APP-CLASS-CODEBOOK-LAYOUT.md](APP-CLASS-CODEBOOK-LAYOUT.md) | The symbol-table layout. `hi u16 ‖ lo u16` = **object-file identifier ‖ symbol id.** The APP prefix selects a lowering target's view; the concept is the linker-canonical name. |
78+
| [CLASSID-RBAC-KEYSTONE-SPEC.md](CLASSID-RBAC-KEYSTONE-SPEC.md) | The pending **semantic-analysis pass.** `authorize(actor, classid, op) → AccessDecision` is the verification predicate over the IR. |
79+
| [OGAR-CONSUMER-BEST-PRACTICES.md](OGAR-CONSUMER-BEST-PRACTICES.md) | The consumer rule "pull the classid via `PortSpec`, never re-mint" = **link against the public symbol table; do not fork it.** §2's spine-vs-membrane split is **ABI tiering**. |
80+
| [CONSUMER-MIGRATION-HOWTO.md](CONSUMER-MIGRATION-HOWTO.md) | The bridge-removal recipe = **switch from a private linker (a bridge wrapping the registry) to the public linker (`PortSpec` / `contract::ogar_codebook`).** |
81+
| [SURREAL-AST-TRAP-PREFLIGHT.md](SURREAL-AST-TRAP-PREFLIGHT.md) | The pre-flight against treating a back-end's vocabulary as the IR's. The five questions are *"are you trying to encode IR-only concepts in a target-language form?"* |
82+
83+
---
84+
85+
## §5. Why this framing
86+
87+
Two reasons.
88+
89+
First, the **vocabulary**. Every contributor reaching for a new abstraction now has fifty years of compiler engineering to draw from. "Should this be in the IR or the back-end?" has a known shape; "Should this be a pass or a structural change?" has a known shape; "Is this semantic-preserving?" has a known shape. Saying "OGAR is a graph ontology" loses those shapes; saying "OGAR is the IR of a compiler" recovers them.
90+
91+
Second, the **discipline**. Compiler IRs are designed to be optimized, to be lowered to many targets, to be analyzed for correctness. Database schemas are designed to be queried. The work already shipped in this repo — multi-target lowering, semantic analysis, optimization passes, native codegen via jitson — is compiler work. Naming it as compiler work makes the next design choices automatic.
92+
93+
The framing changes no existing decision. It changes every future one.

0 commit comments

Comments
 (0)