Skip to content

ogar-from-ruff: keep invalid and unresolved Rails enums visible (O1b-a) - #374

Merged
AdaWorldAPI merged 1 commit into
mainfrom
ccr-8062bcc7-l7lkz9-o1b
Nov 7, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
ccr-8062bcc7-l7lkz9-o1b

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What was wrong

After #373, the Rails enum lift still had three problems.

  • A duplicate key dropped the whole declaration. lift_enum returned None, and lift_model's filter_map discarded the declaration without a trace.
  • An unrecovered variant list looked like an empty enum. When the Ruby walker could not see the variants (array form, a constant, or no argument), the declaration lifted to Static(vec[]). That reads as a known enum with no values.
  • The label repeated the key. The key was copied into the label slot, and ogar-emitter published that slot as ogar:variantValue, which asserts a value the source never declared.

The change

EnumSource gains three additive variants. The enum is already #[non_exhaustive], so this does not break other crates.

State Meaning
Unlabeled(keys) Fixed keys in source order. The source declares no label.
Unresolved(reason) The source declares an enum, but its variant list was not recovered. Asserts no values.
Invalid(reason) The declaration cannot be represented faithfully, for example a duplicate key. It stays on the class.

lift_enum now returns None only for an attribute that is not an enum. Otherwise:

Input Result
Unique keys Unlabeled
A duplicate key Invalid("duplicate enum key k")
No options Unresolved

Rails integers are still never stored in OGAR.

Downstream outputs:

  • Emitter, Unlabeled: one ogar:variantName per key and no ogar:variantValue.
  • Emitter, Unresolved and Invalid: a reason triple and no variants.
  • SurrealQL, Unlabeled: asserts the key set.
  • SurrealQL, Unresolved and Invalid: a plain string field with a comment, and no value assertion.

ogar-from-schema still produces Static and is not changed here.

Validation

  • cargo test -p ogar-vocab -p ogar-from-ruff -p ogar-emitter -p ogar-adapter-surrealql: all pass.
  • cargo clippy --workspace --all-targets -- -D warnings: clean.

Each guard was disabled on top of the committed change; every disable turned at least one test red:

Disable Failing tests
A duplicate key returns None lift_enum_duplicate_key_is_kept_as_invalid
Empty options give Static(vec[]) 3 tests, including lift_enum_without_visible_variants_is_unresolved_not_static
The label is the key again 3 tests, including lift_enum_unlabeled_carries_keys_and_no_rails_integer
Unlabeled emits variantValue unlabeled_enum_emits_names_and_no_variant_value

Follow-up

O1b-b will read ruff's typed enum forms (the array form, an unresolved constant, the legacy kwarg form) once that ruff change lands on ruff main.


Generated by Claude Code

A duplicate Rails enum key made lift_enum return None, and lift_model's
filter_map dropped the whole declaration without a trace. An enum whose
variant list the Ruby walker could not see lifted to Static(vec![]),
which reads as a known enum with no values. Rails labels were the key
copied into the label slot, which the emitter then published as
ogar:variantValue.

EnumSource gains three additive variants: Unlabeled(keys) for fixed
keys with no source label, Unresolved(reason) for an enum whose
variant list was not recovered, and Invalid(reason) for a declaration
that cannot be represented faithfully. lift_enum maps unique keys to
Unlabeled, a duplicate key to Invalid (the declaration stays on the
class), and empty options to Unresolved. It returns None only for
non-enum attributes. Rails integers stay out of OGAR.

The emitter writes variant names without variantValue for Unlabeled,
and a reason with no variants for Unresolved and Invalid. The
SurrealQL adapter asserts the key set for Unlabeled and emits a plain
string field for Unresolved and Invalid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d6295a14-e66b-4be6-aeb8-17e0f6dd89a7
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review November 7, 2026 23:44
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T23:45:49.727178Z 727b4c1 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@AdaWorldAPI
AdaWorldAPI merged commit 5263a26 into main Nov 7, 2026
4 checks 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