feat: ogar-from-elixir scaffold — wide / OGAR arm for HIRO/Bardioc Elixir#17
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc92d10d2f
ℹ️ 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".
| # the target OGAR shape can be locked first. | ||
|
|
||
| [lints] | ||
| workspace = true |
There was a problem hiding this comment.
Remove undeclared workspace lints inheritance
Because this new crate is added as a workspace member, Cargo loads its manifest for any workspace command; however, workspace = true here requires the root manifest to define [workspace.lints], which this repo does not. In the inspected workspace, cargo test -p ogar-from-elixir fails during manifest parsing with error inheriting lints from workspace root manifest's workspace.lints, so the entire workspace is currently unbuildable until this section is removed or the root workspace lints are added.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in the latest push. The [lints] workspace = true block was imported from ruff_ruby_spo's Cargo.toml without verifying OGAR's root defines [workspace.lints] (it doesn't — confirmed: no existing OGAR crate uses [lints] for exactly this reason). Removed from crates/ogar-from-elixir/Cargo.toml. Same fix piggybacked into #18's crates/ogar-adapter-surrealql/Cargo.toml since I'd copied the same broken pattern there before this review landed. cargo build --workspace should parse cleanly now.
…rkspace.lints]) Imported from ruff_ruby_spo's pattern; OGAR's root Cargo.toml doesn't declare [workspace.lints], so cargo fails manifest parsing with 'inheriting lints from workspace root manifest's workspace.lints'. Existing OGAR crates don't use [lints] for the same reason. Codex P1 on #17; same bug landed in #18. https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY
…no [workspace.lints]) Imported from ruff_ruby_spo's pattern; OGAR's root Cargo.toml doesn't declare [workspace.lints], so cargo fails manifest parsing with 'inheriting lints from workspace root manifest's workspace.lints'. Existing OGAR crates don't use [lints] for the same reason. Codex P1 on #17; same bug landed in #18. https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY
ogar-from-elixirscaffold — wide / OGAR arm for the OLD HIRO/Bardioc stackQueue item #2. Scaffold (per the
ruff_ruby_spopattern adopted in #16) for the wide / OGAR Elixir frontend that fillsogar-vocab::Class+ActionDefper the prefetch ledger inELIXIR-HIRO-PREFETCH.md §2.What lands
crates/ogar-from-elixir, added to workspace members.ogar-vocabonly (zero parser deps until tree-sitter wires in).src/lib.rs(~330 lines):pub fn extract(path) -> Vec<Class>— structural arm (Ecto.Schema)pub fn extract_action_defs(path) -> Vec<ActionDef>— behavior arm (GenServer / gen_statem / Phoenix / Oban)todo!()stubs, each doc-commented with the exact Elixir construct to parse + the §2.1/§2.2 prefetch-ledger row it implementsuse/@behaviourdirective (Ecto.Schema,GenServer,Phoenix.Controller,Phoenix.Channel,Phoenix.LiveView,Oban.Worker,:gen_statem,GenStateMachine)ecto_schema_class_shape_is_locked—Account(email + belongs_to owner)gen_statem_action_def_shape_is_locked— Raftfollowervote_requestcarrying all four §6 Rubicon terms (StateGuard,state_timeout_millis=150,guard_failure_policy=Postponable,on_enter=EnterEffect::transition("state","candidate"))phoenix_controller_action_def_shape_is_locked—create(User subject, Sync modal, no kausal)oban_worker_action_def_shape_is_locked—perform(System subject, Deferred temporal)dispatch_keys_are_the_expected_use_directives— pins the recognized dispatch keysThe locked-shape tests are the contract: when extraction is wired, the produced
Class/ActionDefmust match.Why this is the wide arm (not the narrow SPO arm)
Per #16 §10.1, the narrow SPO arm for Elixir is a future
ruff_elixir_spo(mirroringruff_ruby_spo's ndjson-emitting pattern viaruff_spo_triplet). This crate is the complement: produces OGAR's wide lifecycle IR forlance-graph-ontologyconsumption. Both arms will feed off the same parsed Elixir AST when wired — one parser, two emitters.Why
gen_statemis the load-bearing caserafted_value's Raft consensus runs ongen_statem, and the four §6 Rubicon statem terms (onEnter/guardFailurePolicy/StateTimeout/postpone) map 1:1 fromgen_statemreturns (state_enter,[:postpone],[{:state_timeout, ms, _}],{:next_state, T, _}). The locked-shape test forvote_requestcovers all four, so when extraction is wired, the Rubicon binding is the immediate consumer.What's NOT in this PR (intentional)
ruff_ruby_spouses).parse_modulesistodo!()).ogar-emitter/ogar-proposalintegration — those consumeogar-vocabtypes directly, so they Just Work once extraction wires in.Verification
cargo build --workspaceshould succeed;cargo test -p ogar-from-elixirshould pass the 5 locked-shape tests. Thetodo!()stubs panic at runtime — production code paths (extract,extract_action_defs) intentionally not exercised by tests.https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY