Skip to content

canon + feat: E-KEEP-AR-REMOVE-ORM + compile_graph_ruby (the Rails CompiledClass keystone)#144

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

canon + feat: E-KEEP-AR-REMOVE-ORM + compile_graph_ruby (the Rails CompiledClass keystone)#144
AdaWorldAPI merged 4 commits into
mainfrom
claude/odoo-rs-transcode-lf8ya5

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

Two commits, one arc — the canon correction and the first concrete brick it names.

1. canon: E-KEEP-AR-REMOVE-ORM — append-only EPIPHANIES.md entry recording an operator correction: the consumer "open-heart operation" keeps ActiveRecord and removes the ORM. A prior session read it backwards as "castrate the hand-rolled Rails ActiveRecord betrayal." Wrong: KEEP the AR pattern (class = record + behavior — literally what OGAR's Class/ClassView is; OGAR = Open Graph Active Record, named after AR in OpenProject); REMOVE the ORM (hand-rolled persistence plumbing — op-db SQL/FromRow, op-api row→DTO); WIRE pure AR on Rails directly onto the OGAR graph, no ORM intermediary. Plus Redmine-as-root (fieldview/erb → classview/askama) and a guard against re-inversion.

2. feat(ogar-from-ruff): compile_graph_ruby — the keystone gap the canon entry names: a Rails-correct sibling of compile_graph_python. Same 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).

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.

Test Plan

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 — compile_graph_ruby_stamps_language_ruby_not_python, openproject_work_package_compiles_to_project_work_item_rail_class, openproject_and_redmine_compile_to_the_same_concept_different_render_skin — + 41 pre-existing, unbroken by the drive-by fix).
  • cargo clippy -p ogar-from-ruff --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 — same root cause as the surrealdb-ast 403 — out of scope here.)
  • cargo doc -p ogar-from-ruff --no-deps — doc-links resolve; the 4 pre-existing warnings are in emit.rs, unrelated to this change.

🤖 Generated with Claude Code

… (OGAR=AR)

Corrects a session inversion: the consumer pivot removes the hand-rolled
ORM (op-db SQL/FromRow plumbing) and KEEPS ActiveRecord — OGAR is named
after AR in OpenProject. AR re-wires onto the OGAR graph (pure AR on
Rails, no ORM intermediary); the ClassView IS the active record.
Redmine-as-root: fieldview/erb → classview/askama. Guard against
re-inversion; additive-then-subtractive only. Cross-refs the 6-agent
convergence assessment + the compile_graph_ruby keystone gap.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76dbc8b2e2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


**Status:** FRAMING (`[G]` for the name origin + the keep/remove split, operator-stated 2026-06-30; the convergence wiring it implies is `[H]`, gated per the OP assessment). Corrects a session inversion (mine) that read the consumer pivot as "castrate the hand-rolled Rails ActiveRecord betrayal" — **backwards**.

**The correction (operator):** *"We don't remove Active Record — that's exactly what we keep. We just do an open-heart operation to remove the ORM and wire pure AR on Rails. Hence OGAR (Open Graph Active Record) — the name was literally inspired by AR in OpenProject."*

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required Scope line to this epiphany

The .claude/AGENTS.md instructions for this log require each EPIPHANIES entry to have ## ... plus a **Status:** line, a **Scope:** line, body, and **Cross-ref:**; this new entry goes directly from Status to the correction text. Please add the missing Scope line so the append-only log keeps the documented structure future agents are told to rely on.

Useful? React with 👍 / 👎.

…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.
@AdaWorldAPI AdaWorldAPI changed the title canon: E-KEEP-AR-REMOVE-ORM — open-heart op keeps AR, removes the ORM (OGAR=AR) canon + feat: E-KEEP-AR-REMOVE-ORM + compile_graph_ruby (the Rails CompiledClass keystone) Jun 30, 2026
AdaWorldAPI pushed a commit that referenced this pull request Jun 30, 2026
…oc/attr nits)

ogar-vocab has never been workspace-clippy-gated — the same surrealdb-ast
403 root cause that blocks the whole OGAR workspace from resolving
in-sandbox also meant 'cargo clippy --workspace' has never run here. The
probe workspace used to verify compile_graph_ruby (PR #144) made this
debt visible for the first time. Mechanical fixes only, no behavior
change:

- 9 manual impl Default blocks (MethodKind/RecordSemantics/
  GuardFailurePolicy/ActionSubject/TemporalSpec/ModalSpec/ActionState/
  AssociationKind/Language) replaced with #[derive(Default)] +
  #[default] on the already-documented default variant
  (clippy::derivable_impls). Language's impl lived at the very end of
  the file, after #[cfg(test)] mod tests — also tripped
  items_after_test_module; moving the derive to the enum's declaration
  (already well before the test module) fixes both at once.
- One blank line between #[non_exhaustive] and
  removed (clippy::empty_line_after_outer_attr).
- Two doc-comment lines re-indented to read as a paragraph continuation
  rather than an unindented markdown list item — the actual cause is a
  '+' at the start of a wrapped sentence ('... seeds X + BillingCore
  (0x61); ...') being parsed as a list bullet by rustdoc's CommonMark
  parser (clippy::doc_lazy_continuation).

Verification (same probe workspace as PR #144's compile_graph_ruby):
clippy -D warnings clean for ogar-vocab AND the full probe workspace
(both crates) at the pinned 1.95.0 toolchain; 95/95 ogar-vocab unit
tests + 2/3 doctests (1 pre-existing #[ignore]) pass; 44/44
ogar-from-ruff tests still pass (Class::language: Language construction
unaffected — Default::default() now resolves through the derive instead
of the manual impl, same value). cargo fmt --check clean.
…oc/attr nits)

ogar-vocab has never been workspace-clippy-gated — the same surrealdb-ast
403 root cause that blocks the whole OGAR workspace from resolving
in-sandbox also meant 'cargo clippy --workspace' has never run here. The
probe workspace used to verify compile_graph_ruby (PR #144) made this
debt visible for the first time. Mechanical fixes only, no behavior
change:

- 9 manual impl Default blocks (MethodKind/RecordSemantics/
  GuardFailurePolicy/ActionSubject/TemporalSpec/ModalSpec/ActionState/
  AssociationKind/Language) replaced with #[derive(Default)] +
  #[default] on the already-documented default variant
  (clippy::derivable_impls). Language's impl lived at the very end of
  the file, after #[cfg(test)] mod tests — also tripped
  items_after_test_module; moving the derive to the enum's declaration
  (already well before the test module) fixes both at once.
- One blank line between #[non_exhaustive] and the ActionDef struct
  declaration removed (clippy::empty_line_after_outer_attr).
- Two doc-comment lines re-indented to read as a paragraph continuation
  rather than an unindented markdown list item — the actual cause is a
  '+' at the start of a wrapped sentence ('... seeds X + BillingCore
  (0x61); ...') being parsed as a list bullet by rustdoc's CommonMark
  parser (clippy::doc_lazy_continuation).

Verification (same probe workspace as PR #144's compile_graph_ruby):
clippy -D warnings clean for ogar-vocab AND the full probe workspace
(both crates) at the pinned 1.95.0 toolchain; 95/95 ogar-vocab unit
tests + 2/3 doctests (1 pre-existing #[ignore]) pass; 44/44
ogar-from-ruff tests still pass (Class.language construction
unaffected — Default::default() now resolves through the derive instead
of the manual impl, same value). cargo fmt --check clean.
@AdaWorldAPI AdaWorldAPI force-pushed the claude/odoo-rs-transcode-lf8ya5 branch from 308a347 to 8508a49 Compare June 30, 2026 18:24
Step 2 of the gating order in the OP+Redmine convergence handover
(openproject-nexgen-rs .claude/handovers/2026-06-30-1200-...md §4): before
this commit, emit_rust/csharp/python had only ever run on an Odoo-lifted
CompiledClass (compile_graph_python, in emit.rs's own tests). This adds
a Rails fixture (compile_graph_ruby::<OpenProjectPort> on a WorkPackage
graph with a typed attribute, an untyped attribute, a belongs_to with a
class_name override, and a has_many) and asserts emit_rust renders it
correctly — closing the "pull-back codegen leg unproven on Rails" gap
named in the handover's risk list. Fully offline, OGAR-only — no
openproject-nexgen-rs change.

Found and fixed a real (if narrow) bug along the way: screaming_snake()
only split on '.'/'_', so it silently produced WORKPACKAGE_CLASSID
instead of WORK_PACKAGE_CLASSID for any already-PascalCase Rails class
name (Rails class names carry no separator at all — Odoo's underscored
names happened to mask this). Fixed to also split on a lower->upper case
transition; added a direct unit test
(screaming_snake_splits_bare_pascal_case_rails_names) covering
WorkPackage/TimeEntry/Project plus the original dotted-Odoo-name case.

Verification: standalone probe workspace (same as the rest of this PR).
46/46 tests pass (2 new). clippy -D warnings clean, both --no-deps and
full workspace, at the pinned 1.95.0 toolchain. cargo fmt --check clean
for the lines this commit touches (the crate carries pre-existing,
unrelated fmt drift from never being cargo-fmt-gated — same root cause
as the clippy debt fixed earlier in this PR; left untouched, out of
scope here).
@AdaWorldAPI AdaWorldAPI merged commit 8d70a56 into main Jun 30, 2026
1 check passed
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