Skip to content

feat+docs(transpile-substrate): §1.6 three SDKs + emit_csharp/emit_python codegen#138

Merged
AdaWorldAPI merged 4 commits into
mainfrom
claude/odoo-rs-transcode-lf8ya5
Jun 29, 2026
Merged

feat+docs(transpile-substrate): §1.6 three SDKs + emit_csharp/emit_python codegen#138
AdaWorldAPI merged 4 commits into
mainfrom
claude/odoo-rs-transcode-lf8ya5

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Answers the operator ask — "for Rust via lance-graph; for Python and C# we
need sort of an 'SDK' that does that for the others"
— with both the doc and
its codegen implementation
for two of the three languages.

Code — ogar-from-ruff::emit: two new emitters on the existing seam

emit_rust is the reference; this adds emit_csharp and emit_python
on the same &CompiledClass -> String seam (the codegen mode of the
per-language SDKs):

  • emit_csharppublic sealed record AccountMove { public const uint ClassId = 0x00020202; public OgScalar name {get;init;} public ToOne<ResPartner> partner_id {…} public ToMany<AccountMoveLine> line_ids {…} }
  • emit_python@dataclass class AccountMove: CLASSID: ClassVar[int] = 0x00020202; name: OgScalar; partner_id: ToOne["ResPartner"]; line_ids: ToMany["AccountMoveLine"]

All three emitters use the same wrapper-contract type names (OgScalar /
ToOne / ToMany); only the bracket syntax differs (<T> Rust/C#, [T]
Python). A shared assoc_target() relation classifier drives all three — that
shared vocabulary is exactly what makes an SDK a mechanical transliteration
of one compiled spine, not a re-implementation. The classid travels with the
class; compute behaviour stays a trailing comment (the 15% adapter).
emit_rust's association loop was refactored onto the shared classifier (no
behavioural change).

Docs — new §1.6 "Three SDKs, one compiled spine (Rust · C# · Python)"

Every language SDK is three thin layers: (1) the address algebra
(FacetCascade + CascadeShape, byte-identical across languages), (2) a
ClassView reader over a pulled CompiledClass, (3) the per-language adapter
host for the 15% + the late classid → OGIT grounding resolve. Layer 1 is ~80
lines of core-only const fn, so an SDK transliterates rather than
re-implements. Two pull-back modes per host: codegen emit (this PR) and a thin
runtime reader over the rail artifact (never SurrealQL). Plus: §1.5 status
promoted (the arithmetic is now implemented as CascadeShape — lance-graph
#621); §6 "Built" lists the three emitters; §6.2 "Next" narrowed to the runtime
SDKs + wrapper-contract packages.

Test Plan

  • 6 emit tests green (3 new: emits_csharp_record_with_wrapper_contract_types,
    emits_python_dataclass_with_wrapper_contract_types,
    all_three_emitters_share_the_same_type_vocabulary).
  • clippy clean + rustfmt clean on emit.rs.
  • Probe-workspace verified offline (the OGAR workspace's surrealdb-ast git dep
    is unresolvable offline; ruff_* patched to the local /home/user/ruff
    checkout, scoping resolution to ogar-from-ruff + ogar-vocab).

Companion to lance-graph #621 (facet::CascadeShape, the layer-1 algebra).

🤖 Generated with Claude Code

https://claude.ai/code

@AdaWorldAPI AdaWorldAPI changed the title docs(transpile-substrate): §1.6 three SDKs (Rust/C#/Python), one compiled spine feat+docs(transpile-substrate): §1.6 three SDKs + emit_csharp/emit_python codegen Jun 29, 2026
claude added 3 commits June 29, 2026 20:30
…iled spine

Address the operator ask: 'for Rust via lance-graph; for Python and C# we need
sort of an SDK that does that for the others.'

- New §1.6: every language SDK is three thin layers — (1) the address algebra
  (FacetCascade + CascadeShape, byte-identical across languages), (2) a
  ClassView reader over a pulled CompiledClass, (3) the per-language adapter
  host for the 15% + the late classid→OGIT grounding resolve. Layer 1 is ~80
  lines of core-only const fn, so an SDK is a mechanical transliteration; the
  shared byte format means the SDKs cannot drift on layout.
- Two pull-back modes per host: (b) codegen emit (emit_csharp → assembly,
  emit_python → bytecode-on-import — the strongest 'compiled' form) and (a) a
  thin runtime reader over the rail-facet artifact (zero-parse, never SurrealQL).
- §1.5 status promoted: the per-carving tier-byte arithmetic is now pinned +
  implemented as lance_graph_contract::facet::CascadeShape (was 'to pin before
  coding'). §6 roadmap + §7 extension table point at §1.6.

Co-Authored-By: Claude <noreply@anthropic.com>
Realize §1.6's codegen mode for two more languages on the same
&CompiledClass -> String seam emit_rust already defines.

- emit_csharp: a 'public sealed record' with 'public const uint ClassId',
  OgScalar properties, ToOne<T>/ToMany<T> relations (shared <T> syntax).
- emit_python: an '@DataClass' with 'CLASSID: ClassVar[int]', OgScalar
  annotations, ToOne["T"]/ToMany["T"] forward-ref relations ([T] syntax).
- Shared assoc_target() relation classifier drives all three emitters; the
  wrapper-contract type NAMES (OgScalar/ToOne/ToMany) are identical across
  languages — only the bracket syntax differs. That is the mechanical
  transliteration §1.6 promises (the SDK is a reader over one compiled spine,
  not a re-implementation). The classid travels with the class; compute
  behaviour stays a trailing comment (the 15% adapter).
- emit_rust's association loop refactored onto the shared classifier (no
  behavioural change).

+3 tests (emits_csharp_*, emits_python_*, all_three_emitters_share_the_same_
type_vocabulary); 6 emit tests green, clippy clean, rustfmt clean
(probe-workspace verified offline — the OGAR workspace's surrealdb-ast git
dep is unresolvable offline; ruff_* patched to the local checkout).

Doc: substrate §6 'Built' updated (the emitters ship here); §6.2 'Next'
narrowed to the runtime SDKs + wrapper-contract packages.

Co-Authored-By: Claude <noreply@anthropic.com>
…sid switch

Mirror the lance-graph #621 review corrections into the substrate doc:

- §1.5(a): carvings are VIEW *rotations*, not co-equal recombinations. The two
  byte-aligned carvings (6×(1:2), 3×(1:2:3:4)) are defaults (group_of = shift);
  4×(1:2:3) is the WORST CASE (group_of divides, straddles tiers) — prevented on
  the common path, kept only as the rare rotation / escape hatch a ClassView may
  rotate to when a rare Odoo class needs to relieve classid-stacking entropy.
- New callout: carvings address the VIEW only; functions are reached by the
  classid as an additional THINK/DO switch (facet::ClassArm { View, Functions }),
  never by slicing tier-bytes. A straddling carve to reach a function is exactly
  the worst case 4×(1:2:3) warns against.
- §1.5 status: updated to the shipped API (CascadeShape::ALIGNED / ROTATIONS,
  shift(), is_byte_aligned(), ClassArm).

Co-Authored-By: Claude <noreply@anthropic.com>
@AdaWorldAPI AdaWorldAPI force-pushed the claude/odoo-rs-transcode-lf8ya5 branch from 9bd8f98 to ae2c36e Compare June 29, 2026 20:30
…C over packed

Operator (2026-06-29): the 512-byte node = 512/16 = 32 sixteen-byte GUID slots
(key + edges = 2; value slab = 30). In the worst case you Tetris each concern
into its own clean slot rather than bit-pack — preference clean / SoC over
packed. The 32-slot capacity is *why* the CascadeShape::G4D3 straddle (packing)
is almost never needed, and the headroom behind 'rotate / spread to a fresh
slot instead of minting another classid' (the rare classid-stacking-entropy
case). Pinned as lance_graph_contract::canonical_node::GUIDS_PER_NODE = 32.

Co-Authored-By: Claude <noreply@anthropic.com>
@AdaWorldAPI AdaWorldAPI merged commit 2af8f48 into main Jun 29, 2026
1 check passed
AdaWorldAPI pushed a commit that referenced this pull request Jun 30, 2026
…sembler

Adds the keystone gap named in E-KEEP-AR-REMOVE-ORM / the OP convergence
assessment: a Rails-correct sibling of compile_graph_python. Identical
shape (mint_graph::<P> + per-class facet resolution) but routes through
the existing lift_model_graph (Language::Ruby) instead of
lift_model_graph_python — pure operator-reuse, no new lift, and
project_odoo_fields is correctly never invoked for Rails (it would
double-count; lift_model_graph_python's own doc-comment says so).

Proves the convergence claim in code: compile_graph_ruby::<OpenProjectPort>
on a WorkPackage graph and compile_graph_ruby::<RedminePort> on an Issue
graph mint to the SAME low-u16 concept (0x0102 project_work_item) and
DIFFERENT high-u16 render prefixes (0x0001 vs 0x0007) — one canonical
concept, two render skins, machine-checked rather than asserted.

Drive-by fix: 3 pre-existing Function{...} literal constructions
(emit.rs, mint.rs's account_move fixture, lib.rs) broke against the
already-merged ruff#38 (writes/calls fields) because this crate's
ruff_spo_triplet dep floats on branch=main. Added ..Default::default()
to each — no behavior change, restores compilation.

Verification: standalone probe workspace (path-dep ogar-vocab +
ogar-from-ruff, git-dep ruff branch=main) — the OGAR workspace itself
can't resolve in-sandbox (ogar-adapter-surrealql's surrealdb-ast git dep
403s), the same pattern prior PRs (#131/#132/#136/#138/#141) used.
44/44 tests pass (3 new + 41 pre-existing unbroken); clippy --no-deps
-D warnings clean at the pinned 1.95.0 toolchain (ogar-vocab itself has
pre-existing unrelated clippy debt from never being --workspace-gated,
out of scope here); doc-links resolve.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants