nav: finalize Klickweg structure parity — menu-rooted connectivity (Odoo #66 parity) + ERB↔Odoo synergy/drift finding#94
Merged
Conversation
…doo #66 parity) + ERB↔Odoo synergy/drift finding + ruff #67 rebase Cross-frontend parity. ruff #66 gave Odoo a two-shape navigates_to whose data-side <menuitem> records emit a SYNTHETIC MENU ROOT — menu → res_model edges that give nav_is_fully_connected its entry points, so "connected" means every screen is reachable FROM THE MENU. op-nexgen's top nav (nav::menu) is the identical structure but was not wired into the connectivity graph; NAV_ROOT was a screen (ProjectWorkItem). This brings op to parity: - MENU_UNIVERSE (synthetic `Menu` node + served screens), MENU_ROOT, MENU_NAV_EDGES (Menu → each tab-target, + the inter-screen NAV_EDGES lifted +1), menu_screens_mask, menu_target_concept (inverse of route_for for menu hrefs), menu_klickweg_is_connected(). - The menu-rooted check is STRONGER than the screen-only one: it catches a menu-orphan screen (exists + inter-linked but no top-nav click-path) that klickweg_is_connected() would pass. Same Core brick (nav_is_fully_connected), same "menu gives entry points" shape as Odoo's menuitem roots. - menu_nav_edges_match_derived pins MENU_NAV_EDGES against menu() + NAV_EDGES (no drift); menu_klickweg_is_fully_connected proves reachability. Boot affirms BOTH layers + resolves every menu tab to a served screen. The render-side screen graph (SCREEN_UNIVERSE / NAV_EDGES / render masks) is UNCHANGED — the menu universe is a separate connectivity graph so the synthetic node never pollutes a render-mask position. Finding: .claude/findings/2026-07-08-erb-vs-odoo-klickweg-synergy-drift.md maps the ERB (Ruby, consumed by op) vs Odoo (Python) arms — 6 synergies (one predicate, one ViewFieldSet type literally shared, one mask mint, two-shape nav, honest denominator, menu roots) and 6 principled divergences (receiver- vs record-scoping, plural-tolerant vs exact match, per-file vs cross-file join, framework nav idiom, selects_view plane, meta/arch split). op-relevant lesson: D3 cross-file join, needed when the real OpenProject corpus enters the harvest. Also rebases the ruff pins to main b5fde66 (#67 odoo_views relation-hop + tokenizer fixes — ruff_python_spo-only, behavior-inert for op, bumped for consistency). Tests: op-server nav:: 9/9 (2 new menu-rooted), full op-server + pipeline + ruff_openproject 79/79. New code clippy-clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9t3fRwXmPC6tCpMtnfTrM
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b0af6b0c-c595-44fd-ab7d-a206152ae8ec) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cross-frontend Klickweg parity
ruff #66 gave Odoo a two-shape
navigates_towhose data-side<menuitem>records emit a synthetic menu root —menu → res_modeledges that givenav_is_fully_connectedits entry points, so "connected" means every screen is reachable from the menu. op-nexgen's top nav (nav::menu) is the identical structure but wasn't wired into the connectivity graph (NAV_ROOTwas a screen,ProjectWorkItem). This brings op to parity.Menu-rooted connectivity (the render-side twin of Odoo's menuitem roots)
MENU_UNIVERSE(syntheticMenunode + served screens),MENU_ROOT,MENU_NAV_EDGES(Menu → each tab-target+ the inter-screenNAV_EDGESlifted +1),menu_screens_mask,menu_target_concept(inverse ofroute_forfor menu hrefs),menu_klickweg_is_connected().klickweg_is_connected()would pass. Same Core brick (nav_is_fully_connected), same "menu gives entry points" shape as Odoo.menu_nav_edges_match_derivedpinsMENU_NAV_EDGESagainstmenu()+NAV_EDGES(no drift);menu_klickweg_is_fully_connectedproves reachability; boot affirms both layers and resolves every menu tab to a served screen.SCREEN_UNIVERSE/NAV_EDGES/ render masks) is unchanged — the menu universe is a separate connectivity graph, so the synthetic node never pollutes a render-mask position.ERB ↔ Odoo synergy/drift finding
.claude/findings/2026-07-08-erb-vs-odoo-klickweg-synergy-drift.mdmaps the ERB (Ruby, the arms op consumes) vs Odoo (Python) harvests:Predicate::NavigatesTo; oneViewFieldSet/ViewTargettype (odoo_viewsliterallyuse crate::templates::…— the same types); onefrom_universe_presentmask mint (ERB/askama/Jinja/OdooXML = four renderers, one brick); two-shape nav; honest denominator; menu roots.selects_viewplane · Odoo's meta/arch split.NAV_EDGESfrom harvest).Also
Rebases the ruff pins to main
b5fde66(#67odoo_viewsrelation-hop + tokenizer fixes —ruff_python_spo-only, behavior-inert for op, bumped for consistency).Tests
op-server nav::9/9 (2 new menu-rooted); fullop-server+op-codegen-pipeline+ruff_openproject79/79. New code clippy-clean.🤖 Generated with Claude Code
Generated by Claude Code