V3 criticals: five proofs + WoA 1:1 parity (D-PARITY-PROBE-WOA-1) + PG-facet adapter#158
Conversation
Add lift_ogit_entity: lowers an OGIT entity TTL plus its attribute TTLs into the canonical Class (controller-DTO wire shape), matching attributes by localized name. Pins wire names via tests/membrane_probe.rs against the real OGIT NTO DocumentInfoRecord fixture (documentNumber/Type/PartId/Version). Corrects the mission's vocab/ogar.ttl pointer: that file is owl:Class meta-vocab which the rdfs:Class walker (ttl::detect_kind) does not parse; the OGIT NTO corpus is the real fixture family for this probe. Makes ttl::local_name_from_curie pub(crate) so the new pipeline helper can localize curie-form attribute references to wire names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r skeleton (SPEC-7) Realizes Ruling (b, refined): PostgreSQL = transactional System-of-Record (writes/GoBD/ACID); lance-graph = read-optimized hot-path, never sole booking store; moka cache PG-side only, never in front of lance-graph (zero-copy guardrail encoded in module docs). New sibling crate ogar-adapter-postgres-ddl (precedent: ogar-adapter-clickhouse-ddl), emit-only (no DB driver, no network): - emit_postgres_ddl(&[Class]) -> per-class CREATE TABLE, typed + nullable from the schema stratum (options.required == Some(true) -> NOT NULL). - emit_facet_table_ddl(table_name) -> the V3 facet table: classid + 12 axis-indexable payload columns (p0..p11 SMALLINT), one B-tree index per column. Verified against ruff_spo_address::Facet (16 B total = 4 B classid + 6 tiers x 2 B is_a/part_of rank == 12 payload bytes), confirming the 12-column layout without guessing a 16-slot variant. - parity::check_parity(sink_in, legacy) -> ParityReport, the drift-fuse skeleton for the legacy-parity revival mode (COUNT_FUSE pattern); documents (does not build) the transactional-outbox dual-write runtime. Both TimesheetActivity-tied tests (woa_timesheet_activity_ddl_roundtrips_field_set, woa_timesheet_activity_sink_in_matches_hand_legacy) use a Class fixture hand-transcribed directly from WoA/models.py:1746 (read-only source) as a documented stand-in: SPEC-5's real CompiledClass lift output lives on an unmerged sibling branch (claude/v3c-woa-parity) not present here. cargo test -p ogar-adapter-postgres-ddl: 10 passed. cargo test --workspace: all green, nothing regressed. cargo clippy -p ogar-adapter-postgres-ddl --all-targets --all-features -D warnings: clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ndExecutor) Add tests/lifted_action_dispatch.rs: a ruff_spo_triplet::Model method is lifted via ogar_from_ruff::lift_actions into an ActionDef, then dispatched through the reference NativeCommandExecutor -- the executable half of Falsifier #3 ("lifted action -> ActionHandler -> result"). The header documents the remaining gap precisely: the kanban transition + Lance tombstone half needs the lance-graph ractor runtime, not present in this repo. ogar-from-ruff is added as a dev-dependency (execution probe only, not a runtime dependency of this crate). Also includes a trivial cargo-fmt-only fixup to membrane_probe.rs (SPEC-3 commit, no semantic change). SPEC-4 part (ii) (cognition typ-test, ActionDef -> UnifiedStep) is left OFFEN: the spec designates crates/ogar-class-view/tests/cognition_step_mapping.rs as its home (that crate already deps lance-graph-contract), but this grind's authorized file scope is limited to ogar-from-schema/** and ogar-action-handler/** only -- ogar-class-view is out of scope. Reported in the mission handoff rather than worked around. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d-trip (SPEC-2)
Three deliverables from SPEC-2 (fieldmask + render dual-target), OGAR side
only (FieldMask widening in lance-graph-contract is a separate PR):
(i) Pin test documenting today's silent drop of fields beyond the 64-bit
FieldMask ceiling: FieldMask::with(n) for n >= MAX_FIELDS is a no-op,
and the FULL sentinel still bypasses per-bit gating (emits overflow
fields too). Pinned against the `field_present` primitive directly,
since (ii) below makes the same input via `render_class_with_methods`
loud-fail instead of returning Ok with a silent drop (see deviation
note in the final report).
(ii) Loud-fail guard: `render_class_with_methods` now returns
`Result<String, RenderError>`. A class with more fields than a single
u64 FieldMask can address, under a non-FULL mask, returns
`RenderError::TooManyFieldsForMask` instead of silently dropping
fields 64+. FULL and <=64-field classes are unaffected (Ok). Swept
the one in-workspace call site (examples/render_osm.rs `.expect`,
compiles unchanged since RenderError: Debug).
(iii) Falsifier #2, dual-target: one (fields, mask) fixture
(tests/fixtures/mask_roundtrip.json) drives both the askama (Rust)
and jinja2 (Python) engines; both yield the identical field-name set.
New tests/mask_dual_target.rs (Rust) + tests/jinja/render_mask.py.j2
+ tests/jinja/test_mask_roundtrip.py (Python, run via
`uv run --with jinja2`).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three CONFIRMED PR #156 findings, each closed with a red-before-green regression test: (a) ogar-from-rails::extract_app / extract_app_with routed through the schema-blind ruff_ruby_spo::extract_app_with, so the physical db/migrate/tables/*.rb column stratum never reached the shipped API (project_rails_fields had nothing to project; the "18/18" parity only held on a direct lift_model call with a hand-built fields vector). Now routes through ruff_ruby_spo::extract_app_with_schema. Guarded by a compile-level pin (extract_app_uses_schema_aware_symbol, non-ignored) and a real-corpus #[ignore]d test documenting the wiring. (b) is_fk_shadowed_by_association only matched the <name>_id naming convention, ignoring an association's explicit foreign_key: option, so `belongs_to :author, foreign_key: "user_id"` double-projected user_id (scalar) and author (association). Now checks the explicit foreign_key first, falling back to the naming convention. (c) project_rails_fields pushed every physical column unconditionally, so a model with both `attribute :foo, :string` (AR-DSL) and a physical foo column duplicated Class.attributes. Now skips a physical column whose name already matches a lifted attribute, keeping the AR-DSL declaration as the single authoritative entry. Drive-by: ogar-class-view/Cargo.toml's stale "68 promoted canonical concepts" doc corrected to 79 (the enforced ogar-vocab COUNT_FUSE). cargo test -p ogar-from-ruff / -p ogar-from-rails / -p ogar-class-view all green. Fixes (b) and (c) verified red-before-fix by stashing each hunk individually and re-running the paired regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Type-level test that ogar_vocab::ActionDef lowers onto lance-graph-contract's UnifiedStep orchestration shape. Confirmed against the pinned source (lance-graph 598f8727, orchestration.rs) that UnifiedStep/StepStatus are plain public structs/enums (not #[non_exhaustive]), so the full mapping is built directly via struct literal rather than downgraded to the documented-gap variant. StepDomain's variant set matches RECON R5 exactly (Crew/Ladybug/N8n/ LanceGraph/Ndarray/Smb/Medcare/Kanban) with no ERP/controller arm yet; an exhaustive match pins that seam so a silent variant addition fails to compile. No new dependency: ogar-class-view already deps lance-graph-contract and ogar-vocab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…IT-2) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 1/2) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…delGraph Part B: new ogar-from-ruff::sqlalchemy module — project_sqlalchemy_fields (Rails-style total-nullability wiring + FK-dedup + SPEC-0(c) attribute-dup guard), lift_model_sqlalchemy/lift_model_graph_sqlalchemy (stamp Language::Python via the SQLAlchemy projection, not the Odoo one), plus mint::compile_graph_sqlalchemy<P: PortSpec>. Implemented as a new module file + a single `mod sqlalchemy;` line in lib.rs (WS-G-D merge constraint: lib.rs is being edited concurrently by another agent) rather than SPEC-5's preferred shared project_total_schema_fields helper threaded through lib.rs — documented as a named, reported trade-off in the module docs. Part C: crates/ogar-from-ruff/tests/woa_parity_probe.rs — a synthetic ModelGraph transcribed verbatim from the real, read-only WoA TimesheetActivity (models.py:1746-1753) lifts through compile_graph_sqlalchemy::<WoaPort> and emits via emit_python to a structurally 1:1 @DataClass: 3/3 columns typed, 3/3 nullability, 1/1 association (FK timesheet_id deduped to the timesheet BelongsTo), 0/0 action names (schema-only v0). Prints the D-PARITY-PROBE-WP-1-style N/N metric with an explicit drift list. Named SPEC-5 deviation (verified against ogar-vocab/src/ports.rs and RECON.md R8, not invented): WOA_ALIASES already pins "TimesheetActivity" to BILLABLE_WORK_ENTRY as a deliberate planner/ERP convergence concept, so compile_graph_sqlalchemy::<WoaPort> yields facet classid 0x0103_0003 (the convergence pin firing correctly), not the bootstrap 0x0000_0003 SPEC-5 assumed. A second, independent inaccuracy in the same passage: even a genuinely unmapped WoA model resolves to the literal bootstrap 0 (classid_for_node never composes the app prefix on a None lookup), not a composed 0x0000_0003. Both are pinned by dedicated tests in mint.rs rather than silently "fixed" to match the spec's expectation. Part D: the emitted @DataClass py-compiles and instantiates (tests/py/instantiate_check.py), proving the Python mirror of CompiledClass is real, usable Python, not just syntactically valid text. cargo test -p ogar-from-ruff: 59 + 3 passed. cargo test --workspace: all green, zero regressions. cargo clippy -p ogar-from-ruff --all-targets --all-features -- -D warnings: clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rface signed off gegen OGAR-AS-IR §3 Wire ruff's real behavior facts (ruff_spo_triplet::Function.reads/writes/ calls) onto ogar_vocab::ActionDef as first-class effect annotations, making behavior part of the compile-time substrate (Operator §3) without fabricating reactive @api.depends semantics from a plain method read (kausal stays None). IR-surface sign-off (WS-V, Opus) against docs/OGAR-AS-IR.md §3 six tests: - Test 2 (effect annotations first-class): PASSES HEAD-ON. reads/writes/calls are exactly the "what it reads / what it writes / what side effects" the test mandates; ActionDef previously violated it. - Tests 1/3/4/5/6: NEUTRAL. No hidden state, no target-dialect creep, no back-end/optimizer semantics touched; the facts ride the Core IR node (ActionDef), not the classid/address (doctrine: behavior is a property of what the id resolves to, never the address). Additive + non-breaking: ActionDef derives Default and is #[non_exhaustive]; its only construction path is ActionDef::new(..) + ..Default::default(), so the three new Vec<String> fields default to empty at every site. Workspace sweep confirms no exhaustive-match site breaks. Honest scoping: name-level only (value/body/params not captured by today's frontend); body_source/on_enter/params lowering remains SPEC-1(ii), a documented ruff_spo_triplet::Function extension follow-up. Tests: cargo test -p ogar-vocab (96) + -p ogar-from-ruff (58, incl. 3 new: lift_actions_carries_read_write_call_effect_facts, lift_actions_empty_facts_stay_empty_not_none, lift_actions_identity_predicate_object_unchanged) + cargo test --workspace (419 passed / 0 failed). clippy -D warnings clean on both patched crates. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ippy-1.95-Doc-Lints in Beispielen Die sqlalchemy.rs-Kopie von is_fk_shadowed_by_association bekommt die SPEC-0(b)-Semantik (explizites foreign_key zuerst, dann <name>_id-Konvention) — sonst waere die #156-Bug-Klasse im SQLAlchemy-Arm wieder eingefuehrt worden. Lockstep-Kommentar + Konsolidierungs-Follow-up dokumentiert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…E-WOA-1, E8-adjacent entries Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-parity Ledger-Konflikte append-only aufgelöst (beide Eintrags-Sets erhalten). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> # Conflicts: # .claude/board/EPIPHANIES.md # docs/DISCOVERY-MAP.md
…o → WoaPort (parked for woa-rs) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b2ff812. Configure here.
| name.to_string() | ||
| } else { | ||
| format!("\"{}\"", name.replace('"', "\"\"")) | ||
| } |
There was a problem hiding this comment.
Reserved table name unquoted
High Severity
quote_pg_ident incorrectly identifies names like User as safe bare identifiers. This causes emit_postgres_ddl to generate unquoted table names. Since PostgreSQL folds unquoted names to lowercase and user is a reserved keyword, applying the generated DDL can fail or mis-bind tables, impacting schemas like WoA.
Reviewed by Cursor Bugbot for commit b2ff812. Configure here.
| field: legacy_attr.name.clone(), | ||
| sink_in: sink_in_attr.options.required, | ||
| legacy: legacy_attr.options.required, | ||
| }); |
There was a problem hiding this comment.
Parity nullability tri-state mismatch
Medium Severity
The check_parity function incorrectly flags nullability drift when options.required is None in one class and Some(false) in another. These values are semantically equivalent for nullable columns and produce identical DDL, leading to false positives in the parity report.
Reviewed by Cursor Bugbot for commit b2ff812. Configure here.


What
The five documented "criticals" of the OGAR V3 transpiler substrate, each turned from an [H]-hypothesis into an executable proof, plus the WoA 1:1 reality-check. Rebased on #157 (recipe-codebook Phase 1). 22 commits, 42/42 test suites green.
Multi-agent build: Opus plan/review/IR-sign-off, Sonnet grind under fixed specs; every finding adversarially re-verified before merge.
The five criticals — now proven
ActionDefcarriesreads/writes/callsfacts from ruff #38 (IR-surface signed off vs OGAR-AS-IR §3; reads=inferred, writes=authoritative).D-BEHAVIOR-ACTION-EDGES.ClassView×FieldMaskprojection → askama (Rust) and jinja (Python) yield the identical field set at mask=45. Loud-fail guard replaces the silent >64-field drop.D-FIELDMASK-LOUD-FAIL.lift_ogit_entity: OGIT-TTL → controller-DTO with expected wire-names (DocumentInfoRecord fixture;vocab/ogar.ttlis owl:Class meta-vocab, deliberately unrecognised).D-MEMBRANE-TTL-DTO.NativeCommandExecutorpunched through end-to-end; falsifier #3 gap (kanban/tombstone needs ractor runtime) documented. cognition:StepDomainexhaustive-match breaks LOUD at compile-time when the ERP arm lands.D-EXEC-ONE-ACTION.WideFieldMask, backward-compatible, canonical form + repr-independent Eq/Hash (a P0 equality footgun found & fixed pre-merge).The reality check — WoA substrate vs WoA, 1:1
D-PARITY-PROBE-WOA-1: WoATimesheetActivity→ SQLAlchemy harvest → OGAR lift →emit_python→ structural diff vs original. classes 1/1, columns typed 3/3, nullability 3/3, associations 1/1, py_compile + instantiate green. classid0x0103_0003via theWOA_ALIASESconvergence pin toBILLABLE_WORK_ENTRY(SPEC's "unaliased bootstrap" assumption refuted and pinned by test; bootstrap is literal 0). Honest drift listed:emit_pythondoesn't yet renderoptions.required.Full harvest parked under
.claude/harvest/woa-rs/(139 models, 1961 attributes, 107/107 associations resolved, 6 aliased): the sink-in substrate forwoa-rs, withPARKED.mdrelocation steps (OSM #152 precedent). Released in WoA at.claude/harvest/woa-sinkin-substrate/(branchclaude/woa-repo-backup-update-qb1enp).SPEC-0 — the three #156 correctness findings, fixed (red-before-green)
Mainline
extract_app*now routes throughextract_app_with_schema; FK-dedup honours explicitforeign_key:; attribute-dup guard prevents invalid codegen.D-156-CORRECTNESS-FIXES.SPEC-7 — Python persistence groundwork (ruling b)
New
ogar-adapter-postgres-ddl: facet table (classid + 12 axis-indexed SMALLINT), DDL generated from the ClassView. Role split baked into the docs: PG = transactional system-of-record, lance-graph = zero-copy read hot-path, moka PG-side only (never before lance — it would break zero-copy).check_paritydrift-fuse skeleton (outbox/dual-write/CDC = named follow-ups).D-PY-PERSIST-PG-FACET.Depends on / sequencing
ruff_sqlalchemy_spo) → main; after it merges, OGAR ruff deps flipbranch=main(O-2 de-pin) — which also unblocks recipe-codebook consumability flagged in Recipe integration Phase 1: the recipe-concept codebook + lift resolver (+ the AR-shape reunion canon) #157 handover §6.OGAR-SOCsplit signal, not a widening case.Follow-ups (named in ledger, not silently dropped)
FieldMask consolidation (
project_total_schema_fields),emit_pythonrequired-rendering, dual-write outbox + CDC, Part-A SQLAlchemy frontend already on the ruff PR, falsifier #3 ractor runtime, F17/F1 measurement gates.🤖 Generated with Claude Code
https://claude.ai/code/session_01Cg8DSUz1U4AvKqXiy9Xx2f