You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/08/29 06:08:18 UTC

(causeway) 15/22: docs(openspec): plan Vaadin Menu Bar application menus

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch htmx
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 1726ebfad81ed86e70a3619bb7a7962370776adc
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Aug 28 15:54:24 2026 +0200

    docs(openspec): plan Vaadin Menu Bar application menus
---
 .../.openspec.yaml                                 |   2 +
 .../design.md                                      | 155 ++++++++++++++++
 .../proposal.md                                    |  17 +-
 .../specs/domain-web-components/spec.md            |  63 +++++++
 .../generic-htmx-web-component-viewer/spec.md      | 122 +++++++++++++
 .../spec.md                                        |  59 ++++++
 .../vaadin-application-menubar-adapter/spec.md     | 202 +++++++++++++++++++++
 .../tasks.md                                       | 116 ++++++++++++
 .../planned-changes/web-component-viewer/README.md |   4 +-
 .../vaadin-presentation-roadmap.md                 |   8 +-
 10 files changed, 736 insertions(+), 12 deletions(-)

diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/.openspec.yaml b/openspec/changes/use-vaadin-menu-bar-for-application-menus/.openspec.yaml
new file mode 100644
index 00000000000..7f2cf9bc02c
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-08-28
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/design.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/design.md
new file mode 100644
index 00000000000..54dd69c1ee3
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/design.md
@@ -0,0 +1,155 @@
+## Context
+
+The archived menu-bar foundation already owns application-menu capability discovery, resource parsing, semantic primary, secondary, and tertiary tiers, generation-scoped refresh, independently prepared service-action state, action execution, result publication, responsive native disclosures, focus, diagnostics, and host policy.
+The archived Vaadin reference, editor, read-only field, action, and Grid tranches established the common `component-toolkit=vaadin|native` policy, independently packaged free-core closures, exact-hash CSP, family-scoped failure, lifecycle revisions, and complete native rollback.
+Menu Bar differs from member-local adapters because `<cw-menubars>` belongs to the stable authenticated shell and its closure can affect nearly every authenticated route.
+Vaadin Menu Bar accepts nested item objects, disabled state, item-selected events, overflow, and keyboard behavior, but those objects and events cannot become application contracts or bypass Causeway interaction and navigation policy.
+The implementation must preserve the existing public `cw-*` vocabulary and established native behavior while deciding whether the stable-shell payload and responsive behavior justify default internal adaptation.
+
+## Goals / Non-Goals
+
+**Goals:**
+
+- Use one qualified internal Vaadin Menu Bar for each non-empty semantic primary, secondary, or tertiary tier.
+- Preserve exact menu, section, action, service, visibility, usability, disabled-reason, icon-hint, description, preparation, refresh, invocation, result, and focus semantics.
+- Keep Causeway application-menu state and service-action interaction as the only authorities.
+- Preserve wide and narrow keyboard, pointer, overflow, dismissal, focus-restoration, and accessibility contracts.
+- Reuse the common toolkit policy while isolating Menu Bar packaging, CSP, family health, and fallback from every other Vaadin family.
+- Prove deterministic free-core packaging, acceptable stable-shell cost, no telemetry, no external requests, and complete explicit-native rollback.
+- Preserve login and authentication-challenge chrome without loading Menu Bar assets.
+
+**Non-Goals:**
+
+- Expose raw `vaadin-menu-bar`, item objects, item-selected events, methods, properties, theme internals, or Shadow DOM as supported application APIs.
+- Merge the three Causeway semantic tiers into one public or internal navigation hierarchy.
+- Move GraphQL execution, service-action preparation, validation, authorization, invocation, action-result handling, routing, or refresh ownership into Vaadin callbacks.
+- Add application routing, hyperlinks, client-owned menu definitions, speculative prefetch, or local authorization filtering.
+- Add Vaadin Flow, Binder, server-side Vaadin state, commercial components, telemetry, CDN assets, or external runtime resources.
+- Change public menu resources, GraphQL operations, canonical routes, authentication behavior, or application markup.
+- Remove the established native renderer or its responsive disclosures.
+
+## Decisions
+
+### Keep the existing Causeway menu state machine authoritative
+
+`MenuBarsContextController` continues to discover capabilities, load and parse the menu resource, prepare service-action state, cancel superseded work, publish diagnostics, refresh generations, and execute through the existing interaction controller.
+The Menu Bar adapter receives only an immutable Causeway projection of an already accepted bar generation.
+An item-selected callback resolves a bounded internal semantic identity and delegates to the same Causeway service-action activation path used by native buttons.
+The callback never constructs GraphQL, invokes navigation, interprets action results, or mutates authoritative menu state.
+
+The alternative of letting Vaadin items contain executable callbacks is rejected because it would create a second invocation path and make stale item objects authoritative.
+
+### Preserve one independently qualified adapter per semantic tier
+
+Each non-empty primary, secondary, or tertiary bar remains represented by its existing public element and receives its own internal Menu Bar control.
+The adapter does not merge tiers, reorder menus, or move actions between sections.
+An empty tier remains hidden exactly as it is today.
+A hierarchy that cannot be represented without semantic loss keeps that complete tier native rather than mixing native and Vaadin controls within one tier.
+A closure or definition failure is family-scoped and returns all connected tiers to native rendering because partial toolkit family health would be confusing and difficult to recover consistently.
+
+The alternative of one Menu Bar for all tiers is rejected because it would erase stable tier identity, styling, source order, independent state, and host placement.
+
+### Project immutable item descriptors with opaque semantic identities
+
+The host projects each accepted bar into frozen descriptors containing stable generation, tier, menu, section, action, service logical type, action ID, label, description, icon hint, disabled state, and bounded disabled reason.
+Top-level items correspond to Causeway menus in source order.
+Labeled sections become nested grouping items and unlabeled sections contribute their actions in order without manufacturing selectable commands.
+Only leaf action items are activatable.
+Adapter-private item objects carry opaque lookup keys into the current projection, and stale or unknown keys are ignored.
+Values, GraphQL variables, prepared argument snapshots, full errors, and interaction-controller internals are excluded from item objects and diagnostics.
+
+The alternative of identifying selected actions by visible label is rejected because labels are not stable or unique and may be localized.
+
+### Preserve Causeway-owned action activation and focus intent
+
+The existing bar element owns activation, closes transient menu state, requests action execution through the generated interaction controller, and publishes established semantic outcomes.
+Before activation, the host records a semantic focus intent containing tier and action identity rather than retaining a Vaadin Shadow DOM node.
+After preparation refresh, action completion, cancellation, adapter rerender, or responsive fallback, focus restoration resolves that intent against the current semantic projection or a safe tier-level target.
+Disabled items never invoke, and their existing bounded reason remains available through accessible description and native fallback.
+
+The alternative of restoring a recycled internal item element is rejected because Menu Bar may recreate or overflow internal controls.
+
+### Qualify responsive use without weakening the native contract
+
+A tier qualifies only when policy is Vaadin, family health is available, the element is connected and visible, the generation is current, the tier is non-empty, every hierarchy node is representable, and current width can preserve every authorized action through reviewed Menu Bar overflow behavior.
+The adapter uses a container observer and a revision token so width changes are applied outside observer delivery and stale asynchronous work cannot restore a superseded mode.
+A narrow tier uses Vaadin only after browser evidence proves nested overflow, internationalized overflow labeling, Escape behavior, focus return, order, and zero horizontal overflow.
+If that proof fails for a hierarchy or width, the complete tier uses the established native bar disclosure.
+Responsive transitions reuse accepted semantic state and issue no GraphQL request.
+
+The alternative of assuming Vaadin overflow is always equivalent is rejected because tier labels, nested sections, disabled reasons, and focus restoration can differ at narrow widths.
+
+### Add one independent Menu Bar family loader and lifecycle
+
+A private adapter module owns dynamic import, custom-element definition waiting, timeout, projection, listener installation, rendering, cleanup, and family health.
+Every upgrade captures host connection, menu generation, adapter revision, responsive revision, policy revision, and family revision.
+Disconnect, tier replacement, refresh, policy change, width disqualification, or family failure invalidates pending work before native rendering.
+Cleanup removes listeners, item arrays, observers, focus intents, and generated controls exactly once.
+One family failure emits one bounded value-free diagnostic, marks Menu Bar unavailable, rerenders connected tiers natively, and leaves references, fields, actions, Grid, GraphQL, routing, and authentication unchanged.
+A later explicit connected retry can recover the family without reloading the route.
+
+The alternative of embedding adapter behavior directly throughout `menubar-element.mjs` is rejected because it would obscure native authority and make lifecycle isolation difficult to test.
+
+### Reuse the common component policy without another public switch
+
+Default or explicit `component-toolkit=vaadin` enables qualified Menu Bar together with existing adapters.
+Explicit `component-toolkit=native` disables Menu Bar, contributes no Menu Bar CSP hashes, and requests no Menu Bar bytes.
+When `component-toolkit` is absent, the documented deprecated `editor-toolkit=vaadin|native` compatibility mapping continues to control the complete component policy and therefore Menu Bar.
+Older pilot properties remain limited to their original families and do not enable Menu Bar.
+No Menu-Bar-specific application property is introduced.
+
+The alternative of an independent Menu Bar toggle is rejected because the common policy intentionally provides one operational rollback while family qualification already supplies automatic fallback.
+
+### Load only for qualified authenticated stable-shell menus
+
+The HTMX shell publishes a same-origin Menu Bar closure URL and family policy only under the resolved Vaadin component policy.
+The closure is imported after an authenticated stable shell has connected a non-empty representable tier, rather than on login, authentication challenge, static shell startup, or routes with no effective menu.
+Because most authenticated applications have menus, its normal cost is treated as stable-shell cost and receives a stricter compressed budget and request-count review than route-local adapters.
+Module import remains deduplicated across tiers and routes.
+
+The alternative of unconditional shell import is rejected because it would penalize login, failure, empty-menu, unsupported, and explicit-native states.
+
+### Package and qualify an independent deterministic free-core closure
+
+A dedicated `foundation/vaadin-menubar` package pins Vaadin Menu Bar and only the production transitive closure required by its browser entry point.
+Ordinary Maven builds verify checked-in generated assets and legal metadata without running npm.
+Explicit regeneration installs pinned inputs, audits production dependencies, builds deterministic bytes, records checksums and exact style hashes, rejects telemetry and development-only modules from runtime paths, and refreshes licenses.
+The closure has independent raw and compressed budgets and does not absorb reference, field, action, or Grid bundles.
+CSP remains exact-hash with `style-src-attr 'none'`, no nonce weakening, and no `unsafe-inline`.
+
+The alternative of adding Menu Bar to an existing closure is rejected because stable-shell cost, failure, CSP, and rollback must remain independently reviewable.
+
+### Release-qualify behavior before default adaptation
+
+Foundation tests cover projection, qualification, hierarchy, activation, disabled state, lifecycle revisions, family failure, recovery, responsive switching, and native parity.
+Browser matrices cover primary, secondary, tertiary, nested and labeled sections, hidden and disabled actions, parameterized actions, action results, overflow, keyboard, pointer, Escape, focus restoration, refresh, cancellation, stale responses, authentication exclusions, themes, reduced motion, forced colors, zoom, CSP, external requests, and route replacement.
+Default and explicit-native Petclinic and Reference Application journeys remain mandatory.
+The family is accepted only if no unexpected axe, CSP, console, page, external-request, duplicate-control, stale-item, clipping, overlay, focus, order, or overflow failures remain.
+
+## Risks / Trade-offs
+
+- [Stable-shell payload is paid on most authenticated pages] → Keep a separate closure, enforce compressed and request budgets, lazy-load only after a qualified non-empty tier connects, and retain native rendering if cost is not justified.
+- [Vaadin overflow or nested keyboard behavior differs from established semantics] → Qualify representative hierarchies at wide and narrow widths and keep the complete tier native whenever equivalence is not proven.
+- [Section grouping can create selectable or misleading items] → Represent section labels only as non-action grouping nodes and permit activation only for opaque leaf action identities.
+- [Stale item objects can invoke obsolete actions] → Bind every item to generation and revision, resolve against the current immutable projection, and ignore stale or unknown keys.
+- [Disabled reasons can disappear inside toolkit internals] → Project bounded reasons to accessible descriptions and preserve the complete native fallback.
+- [Three internal controls can duplicate overflow or focus state] → Keep tier-local controls, semantic focus intents, and family-scoped lifecycle cleanup with cross-tier browser tests.
+- [Responsive observers can loop or race asynchronous import] → Apply width state outside observer callbacks and gate every completion by connection, generation, policy, responsive, adapter, and family revisions.
+- [One family failure could break the stable shell] → Fail closed to established native menus while leaving all data, interaction, route, and authentication state intact.
+- [Toolkit diagnostics could leak menu or action data] → Emit only family, phase, bounded classification, revision, and tier metadata.
+- [Pinned free-core dependencies can still include telemetry code] → Audit import reachability and runtime requests, reject activation, and verify zero external requests under production CSP.
+
+## Migration Plan
+
+1. Record current native hierarchy, action, focus, responsive, accessibility, request, and visual baselines.
+2. Build and qualify the independent Menu Bar closure without changing runtime selection.
+3. Add immutable projection, adapter, qualification, lifecycle, family health, and focused tests behind internal configuration.
+4. Extend common policy publication, same-origin packaging, exact-hash CSP, diagnostics, themes, samples, and authenticated stable-shell lazy delivery.
+5. Run complete default and native foundation, HTMX, Petclinic, Reference Application, accessibility, responsive, security, budget, vulnerability, legal, and RAT gates.
+6. Enable qualified default adaptation only after retained evidence demonstrates semantic parity and acceptable stable-shell cost.
+7. Roll back operationally with `causeway.viewer.webcomponents.htmx.component-toolkit=native` without GraphQL, route, persisted-data, authentication, menu-resource, or application-markup changes.
+
+## Open Questions
+
+No blocking design questions remain after promotion.
+Implementation evidence must still determine the accepted Menu Bar version, exact dependency closure, style hashes, raw and compressed budgets, and whether narrow Vaadin overflow qualifies every representative hierarchy or remains selectively native.
diff --git a/openspec/planned-changes/web-component-viewer/use-vaadin-menu-bar-for-application-menus/proposal.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/proposal.md
similarity index 67%
rename from openspec/planned-changes/web-component-viewer/use-vaadin-menu-bar-for-application-menus/proposal.md
rename to openspec/changes/use-vaadin-menu-bar-for-application-menus/proposal.md
index afd4d648044..2a31e8a2338 100644
--- a/openspec/planned-changes/web-component-viewer/use-vaadin-menu-bar-for-application-menus/proposal.md
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/proposal.md
@@ -5,16 +5,21 @@ Vaadin Menu Bar provides established nested-item, disabled-item, overflow, inter
 
 ## What Changes
 
-- Add a qualified internal `vaadin-menu-bar` adapter behind the existing `<cw-menubars>`, `<cw-menubar-primary>`, `<cw-menubar-secondary>`, and `<cw-menubar-tertiary>` semantic vocabulary.
-- Preserve primary, secondary, and tertiary bar identity, source order, labels, sections, action order, visibility, usability, and independently refreshed service-action state.
+- Add a qualified internal `vaadin-menu-bar` adapter behind the existing `<cw-menubars>`, `<cw-menubar-primary>`, `<cw-menubar-secondary>`, and `<cw-menubar-tertiary>` semantic vocabulary after the Grid tranche has established the common toolkit, packaging, lifecycle, CSP, and rollback patterns.
+- Preserve primary, secondary, and tertiary bar identity by using one independently qualified internal Menu Bar per non-empty semantic tier rather than merging the tiers.
+- Preserve source order, labels, descriptions, icon hints, sections, action order, visibility, usability, disabled reasons, and independently refreshed service-action state.
 - Map each non-empty semantic bar into an internal Vaadin item tree rather than collapsing the three public Causeway tiers into one application-facing menu model.
 - Map nested menu and section structure to reviewed Vaadin item children while preserving exact Causeway action identity and disabled reasons.
 - Translate Vaadin item activation into the existing Causeway action-request and interaction-controller path; Vaadin callbacks MUST NOT invoke GraphQL or navigation directly.
 - Qualify Menu Bar overflow, nested keyboard navigation, pointer behavior, visible focus, accessible names, disabled items, internationalized overflow labels, escape behavior, and focus restoration against the established wide and narrow contracts.
-- Replace custom narrow disclosures only when Vaadin overflow and nested menus preserve every visible authorized action without page overflow or order changes; otherwise retain the native responsive presentation at that width.
-- Preserve generation-scoped application metadata, menu-resource loading, service-action preparation, cancellation, refresh, stale-result protection, login exclusions, and route-independent stable-shell ownership.
-- Retain native menu rendering as explicit toolkit rollback and as automatic fallback for adapter-load failure, unsupported hierarchy, policy failure, or accessibility failure.
+- Replace custom narrow disclosures only when Vaadin overflow and nested menus preserve every visible authorized action without page overflow or order changes; otherwise retain the complete native responsive presentation for that tier at that width.
+- Preserve generation-scoped application metadata, menu-resource loading, service-action preparation, cancellation, refresh, stale-result protection, and route-independent stable-shell ownership.
+- Keep unauthenticated login, failure, and authentication-challenge chrome native and prevent those routes from requesting Menu Bar assets.
+- Use the existing common `component-toolkit=vaadin|native` policy and deprecated compatibility precedence without adding a Menu-Bar-specific public configuration property.
+- Retain native menu rendering as explicit toolkit rollback and as automatic fallback for empty tiers, unsupported hierarchy, policy failure, responsive disqualification, adapter-load failure, definition timeout, rendering failure, or accessibility failure.
+- Treat one Menu Bar closure failure as family-scoped so every connected tier returns natively while reference, field, action, Grid, GraphQL, routing, and authentication behavior remain unaffected.
 - Package Menu Bar and only its reviewed free-core transitive closure independently with pinned inputs, deterministic bytes, checksums, licenses, vulnerability review, exact CSP hashes, compressed budgets, accessibility, keyboard, responsive, theme, and lifecycle evidence.
+- Accept default Menu Bar use only if its stable-shell payload, behavior, and fallback evidence remain within reviewed budgets.
 
 ## Capabilities
 
@@ -30,7 +35,7 @@ Vaadin Menu Bar provides established nested-item, disabled-item, overflow, inter
 
 ## Impact
 
-Because `<cw-menubars>` lives in the stable application shell, default Vaadin Menu Bar selection loads its closure on essentially every authenticated viewer page rather than only after an object member connects.
+Because `<cw-menubars>` lives in the stable application shell, default Vaadin Menu Bar selection loads its closure on essentially every authenticated viewer page with a non-empty qualified tier rather than only after an object member connects.
 The change affects menu rendering, item-tree adaptation, action activation, focus management, packaged browser assets, CSP, themes, authentication chrome, samples, and browser evidence.
 Public menu resources, GraphQL service-action operations, `<cw-menubars>` markup, canonical routes, action results, and application-facing Causeway events remain stable.
 It introduces no Vaadin Flow, Binder, server-side Vaadin state, commercial component, CDN asset, telemetry, direct navigation policy, or raw application-facing Menu Bar API.
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/domain-web-components/spec.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/domain-web-components/spec.md
new file mode 100644
index 00000000000..1290dd2c69b
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/domain-web-components/spec.md
@@ -0,0 +1,63 @@
+## ADDED Requirements
+
+### Requirement: Toolkit-backed qualified application menus
+The semantic application-menu components SHALL permit an internal Menu Bar presentation only when the complete tier preserves established hierarchy, order, state, interaction, responsive, and accessibility contracts.
+The public element vocabulary, semantic events, menu state, action state, and host policy MUST remain Causeway-owned.
+
+#### Scenario: Qualified semantic tier renders
+- **WHEN** a connected non-empty primary, secondary, or tertiary tier is representable under the Vaadin component policy
+- **THEN** that public tier may host one internal Menu Bar without changing application markup or selectors
+- **AND** menus, sections, actions, labels, descriptions, icon hints, order, visibility, usability, and disabled reasons remain equivalent
+
+#### Scenario: Service action is selected
+- **WHEN** an enabled current action item is activated by keyboard or pointer
+- **THEN** the existing Causeway interaction-controller path executes its service logical type and action ID exactly once
+- **AND** established validation, cancellation, result, navigation, refresh, and semantic-event policy remains authoritative
+
+#### Scenario: Tier is empty or unqualified
+- **WHEN** a tier is empty, disconnected, hidden, unsupported, stale, responsively disqualified, failed, or governed by native policy
+- **THEN** it remains hidden or uses the complete established native presentation
+- **AND** no approximate or mixed toolkit hierarchy is presented
+
+#### Scenario: Three tiers qualify
+- **WHEN** primary, secondary, and tertiary bars are all non-empty and qualified
+- **THEN** each retains one independently identified internal control in original semantic order
+- **AND** the tiers are not merged into one application-facing or internal menu tree
+
+### Requirement: Toolkit-neutral menu adapter lifecycle
+Application-menu generation, preparation, refresh, activation, result, focus, and responsive state SHALL remain valid independently of native or toolkit presentation.
+Superseded presentation work MUST NOT mutate current menu state or invoke a stale action.
+
+#### Scenario: Menu generation changes
+- **WHEN** refresh, authorization, preparation, metadata, or resource loading produces a newer accepted generation
+- **THEN** current connected tiers project only that generation into native or toolkit presentation
+- **AND** stale items, events, focus targets, definitions, and render completions are ignored
+
+#### Scenario: Presentation mode changes
+- **WHEN** policy, width, hierarchy, family health, connection, or visibility changes presentation mode
+- **THEN** the tier rebuilds from current immutable Causeway state without another semantic request
+- **AND** generated controls, listeners, observers, items, and transient focus state are cleaned exactly once
+
+#### Scenario: Disabled action remains explained
+- **WHEN** current preparation marks a visible service action unusable with a bounded reason
+- **THEN** both native and qualified presentation expose equivalent disabled and described semantics
+- **AND** neither presentation can invoke it
+
+#### Scenario: Family failure occurs
+- **WHEN** Menu Bar loading, definition, projection, rendering, event translation, or CSP fails
+- **THEN** current menu tiers remain usable through native presentation
+- **AND** references, fields, actions, collections, GraphQL, routing, authentication, and menu state remain unaffected
+
+### Requirement: Semantic menu focus continuity
+Application menus SHALL track focus and dismissal by current tier and semantic menu, section, or action identity rather than toolkit DOM identity.
+Focus restoration MUST remain safe when overflow, refresh, responsive switching, action completion, or fallback recreates controls.
+
+#### Scenario: Expanded menu is dismissed
+- **WHEN** the user presses Escape in a native or toolkit nested or overflow menu
+- **THEN** the transient menu closes and focus returns to its current semantic origin
+- **AND** other tiers remain independently scoped
+
+#### Scenario: Focused action disappears
+- **WHEN** refresh removes, hides, disables, or relocates the focused action
+- **THEN** focus moves to a safe current tier or shell target
+- **AND** no stale, hidden, disconnected, or toolkit-internal node regains focus
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/generic-htmx-web-component-viewer/spec.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/generic-htmx-web-component-viewer/spec.md
new file mode 100644
index 00000000000..33f4719df45
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/generic-htmx-web-component-viewer/spec.md
@@ -0,0 +1,122 @@
+## MODIFIED Requirements
+
+### Requirement: Default route-lazy toolkit delivery
+The generic HTMX viewer SHALL enable every qualified packaged adapter under the resolved component policy without eagerly importing any reference, field-family, action-button, Grid, or Menu Bar closure.
+A member-local closure MUST load only after an eligible connected Causeway presentation or editor selects its internal adapter, and Menu Bar MUST load only after an authenticated stable shell connects a non-empty qualified tier.
+
+#### Scenario: Route contains one eligible read-only family
+- **WHEN** the first read-only property eligible for one default field family connects
+- **THEN** only that family's same-origin closure is requested and upgraded
+- **AND** route readiness, other families, references, actions, Grid, and Menu Bar do not wait for it
+
+#### Scenario: Route contains one eligible editor family
+- **WHEN** the first editor eligible for one default field family connects before a read-only property from that family
+- **THEN** only that family's same-origin closure is requested and upgraded
+- **AND** the later read-only adapter reuses the same closure
+
+#### Scenario: Route contains an ordinary action
+- **WHEN** the first visible qualified ordinary action connects on a route without an eligible field
+- **THEN** only the independently packaged action-button closure is requested
+- **AND** no field-family, Grid, or Menu Bar closure is downloaded as a transitive convenience
+
+#### Scenario: Route contains a qualified wide collection
+- **WHEN** the first active wide collection satisfies Grid window, ordering, total or paging, column, renderer, and lifecycle qualification
+- **THEN** only the independently packaged Grid closure is requested for collection presentation
+- **AND** route readiness, fields, references, actions, Menu Bar, and GraphQL loading do not wait for unrelated closures
+
+#### Scenario: Eligible collection is narrow
+- **WHEN** an otherwise eligible collection remains at or below the documented 48rem container boundary
+- **THEN** it uses native responsive presentation and does not request Grid solely for that collection
+- **AND** widening may request Grid later without changing route readiness
+
+#### Scenario: Authenticated shell contains qualified menus
+- **WHEN** the first non-empty representable application-menu tier connects in an authenticated stable shell
+- **THEN** one independently packaged same-origin Menu Bar closure is requested and shared across tiers and later routes
+- **AND** route readiness, GraphQL state, and unrelated adapter families do not wait for it
+
+#### Scenario: Authentication or empty-menu chrome renders
+- **WHEN** login, authentication challenge, failure, logged-out, unsupported-menu, or empty-menu chrome is current
+- **THEN** no Menu Bar closure is requested
+- **AND** authentication remains Spring-owned and native
+
+#### Scenario: Route contains no eligible presentation or editor
+- **WHEN** a landing, menu-free, custom, narrow-collection, or other unaffected route contains no eligible reference, field presentation, editor, ordinary action, wide Grid collection, or qualified application-menu tier
+- **THEN** it requests zero reference, basic, numeric, local-temporal, action-button, Grid, and Menu Bar Vaadin assets
+- **AND** default CSP hash permission does not cause a network request
+
+#### Scenario: One family fails
+- **WHEN** a default field, action, Grid, or Menu Bar closure fails to load or define its controls
+- **THEN** its existing Causeway failure boundary activates the matching native implementation
+- **AND** other family closures remain independently eligible and lazy
+
+### Requirement: Supported exact-hash toolkit CSP
+The HTMX response CSP SHALL include only the generated reviewed style-hash union for the resolved internal component toolkit policy.
+It MUST retain `style-src-attr 'none'`, same-origin script and connection sources, and no `unsafe-inline` source.
+
+#### Scenario: Default component policy renders CSP
+- **WHEN** the effective policy is the supported Vaadin default
+- **THEN** `style-src` and `style-src-elem` contain the deterministic deduplicated reference, field-family, action-button, Grid, and Menu Bar hash union
+- **AND** every hash corresponds to pinned generated policy metadata
+
+#### Scenario: Deprecated editor compatibility renders CSP
+- **WHEN** the component property is absent and explicit `editor-toolkit=vaadin` resolves the complete Vaadin compatibility policy
+- **THEN** CSP contains the same reviewed union, including Grid and Menu Bar, as the default component policy
+- **AND** shell diagnostics identify the deprecated source
+
+#### Scenario: Deprecated pilot subset renders CSP
+- **WHEN** compatibility mode enables only a subset of old editor adapters
+- **THEN** CSP contains exactly the reviewed union required by that old subset
+- **AND** read-only-presentation-only, action-button, Grid, and Menu Bar hashes are absent
+
+#### Scenario: Native component policy renders CSP
+- **WHEN** the effective component policy is native
+- **THEN** CSP contains no Vaadin style hash, including no Grid or Menu Bar hash
+- **AND** route, GraphQL, application stylesheet, canonical identity, and authentication policy remain unchanged
+
+### Requirement: Supported default and native release qualification
+The viewer SHALL treat default-Vaadin and explicit-native component modes as supported release configurations rather than sample-scoped modes.
+Petclinic, the vanilla sample, the pinned Reference Application, deterministic packaging, strict CSP, accessibility, browser isolation, bundle budgets, licenses, vulnerabilities, and ordinary Maven packaging MUST remain passing gates for qualified Menu Bar, Grid, and all previously accepted adapters.
+
+#### Scenario: Default release matrix runs
+- **WHEN** release qualification runs with no toolkit override
+- **THEN** eligible references, read-only fields, editors, ordinary actions, wide collections, and application-menu tiers use internal Vaadin adapters and preserve authoritative outcomes
+- **AND** unexpected CSP, accessibility, console, page, external-request, stale-state, stale-item, duplicate-control, focus, order, overlay, clipping, or overflow failures fail the gate
+
+#### Scenario: Native release matrix runs
+- **WHEN** the same journeys run with `component-toolkit=native`
+- **THEN** native controls, collections, and menus preserve the same GraphQL values, windows, routes, interactions, semantic events, action results, and classifications
+- **AND** all Vaadin closure requests and style hashes, including Grid and Menu Bar, are absent
+
+#### Scenario: Deprecated editor compatibility matrix runs
+- **WHEN** compatibility qualification runs with explicit `editor-toolkit=vaadin` and no component property
+- **THEN** authoritative outcomes and qualified Grid and Menu Bar presentation match default component mode
+- **AND** bounded diagnostics identify the replacement property
+
+#### Scenario: Authentication exclusions run
+- **WHEN** login, authentication failure, challenge, logout, and authenticated-shell journeys execute under default and native modes
+- **THEN** authentication chrome requests no Menu Bar assets and authenticated menu behavior preserves session and security policy
+- **AND** no adapter broadens Spring-owned authentication or authorization behavior
+
+### Requirement: Common internal component toolkit policy
+The HTMX viewer SHALL expose `causeway.viewer.webcomponents.htmx.component-toolkit` with the bounded values `vaadin` and `native` and SHALL default effectively to `vaadin`.
+The resolved component policy SHALL govern eligible references, editors, read-only field presentation, ordinary action buttons, qualified Grid collection presentation, qualified application Menu Bar presentation, and their CSP and asset delivery.
+
+#### Scenario: No toolkit property is configured
+- **WHEN** an application starts without the component, editor, or deprecated pilot toolkit properties
+- **THEN** the resolved component policy enables every qualified Vaadin reference, field, read-only presentation, ordinary action, Grid, and Menu Bar adapter
+- **AND** unsupported or excluded shapes, collections, menus, and controls retain native or explicit unsupported presentation
+
+#### Scenario: Native component policy is explicit
+- **WHEN** `component-toolkit=native` is configured
+- **THEN** the shell explicitly disables every Vaadin component adapter and emits no Vaadin CSP hash
+- **AND** routes request no reference, field-family, action-button, Grid, or Menu Bar closure
+
+#### Scenario: Component policy overrides compatibility inputs
+- **WHEN** `component-toolkit` and `editor-toolkit` or a deprecated pilot property are configured with conflicting values
+- **THEN** the explicit component policy determines all qualified adapters and CSP hashes
+- **AND** compatibility values cannot create a mixed or broadened policy
+
+#### Scenario: Toolkit value is invalid
+- **WHEN** configuration supplies a component-toolkit value other than `vaadin` or `native`
+- **THEN** configuration binding rejects it with a bounded error
+- **AND** the viewer does not silently select a broader policy
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/reference-application-viewer-regression-suite/spec.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/reference-application-viewer-regression-suite/spec.md
new file mode 100644
index 00000000000..df6274d3ad1
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/reference-application-viewer-regression-suite/spec.md
@@ -0,0 +1,59 @@
+## ADDED Requirements
+
+### Requirement: Vaadin Menu Bar application-navigation regression coverage
+The pinned Reference Application SHALL provide deterministic targets for primary, secondary, tertiary, nested, labeled-section, disabled, hidden, parameterized, overflow, refresh, and action-result Menu Bar behavior.
+The same targets MUST remain executable under default Vaadin and explicit native component policies.
+
+#### Scenario: Representative hierarchy renders
+- **WHEN** browser acceptance opens the authenticated Reference Application shell
+- **THEN** primary, secondary, and tertiary tiers preserve menu, section, action, label, description, icon, order, visibility, usability, and disabled-reason semantics
+- **AND** default mode may use qualified Menu Bar while native mode uses no Vaadin menu control or asset
+
+#### Scenario: Enabled service action executes
+- **WHEN** keyboard and pointer journeys activate representative parameterless and parameterized service actions
+- **THEN** established preparation, validation, invocation, cancellation, result, refresh, and navigation outcomes occur exactly once
+- **AND** raw Vaadin item or event contracts are not required by the test
+
+#### Scenario: Disabled and hidden actions are covered
+- **WHEN** authorization or preparation hides an action or marks it unusable with a reason
+- **THEN** hidden actions remain absent and disabled actions remain inoperable and described in both modes
+- **AND** overflow does not reveal unauthorized or duplicate actions
+
+#### Scenario: Nested and labeled sections are covered
+- **WHEN** representative menus contain nested groupings and labeled or unlabeled sections
+- **THEN** qualified and native presentations preserve source order, grouping, names, descriptions, and leaf activation
+- **AND** grouping nodes cannot invoke service actions
+
+### Requirement: Menu Bar lifecycle delivery and accessibility regression coverage
+The regression suite SHALL prove authenticated stable-shell delivery, family isolation, refresh, stale-result rejection, responsive behavior, focus continuity, failure recovery, security, accessibility, and complete native rollback.
+It MUST fail on unexpected requests, hashes, external resources, stale items, duplicate controls, or semantic divergence.
+
+#### Scenario: Stable-shell delivery is measured
+- **WHEN** login, authenticated menu, empty-menu, unrelated route, and repeated route journeys run
+- **THEN** Menu Bar requests are absent from authentication chrome, deduplicated after first qualified use, and independent of member-local closures
+- **AND** explicit native mode has zero Menu Bar requests and hashes
+
+#### Scenario: Refresh supersedes preparation and projection
+- **WHEN** menu metadata, resource, or service-action state refresh overlaps adapter import, item projection, or action preparation
+- **THEN** only current generation items, disabled reasons, actions, focus, and results remain active
+- **AND** stale item selection cannot invoke or navigate
+
+#### Scenario: Route or shell changes during upgrade
+- **WHEN** logout, shell replacement, route replacement, disconnect, policy change, or width change occurs during Menu Bar work
+- **THEN** stale controls, listeners, items, focus, and events cannot reappear
+- **AND** current native or qualified shell state remains authoritative
+
+#### Scenario: Menu Bar family failure is injected
+- **WHEN** failure occurs before connection, during import, during definition, after connection, during projection, or during event translation
+- **THEN** every current tier remains usable natively and a connected retry can recover from current state
+- **AND** reference, field, action, Grid, GraphQL, route, and authentication families remain unaffected
+
+#### Scenario: Responsive keyboard matrix runs
+- **WHEN** wide, narrow, overflowed, zoomed, light, dark, reduced-motion, and forced-colors journeys operate menus with Tab, arrows, Enter, Space, Escape, and pointer input
+- **THEN** every visible authorized action remains reachable in order with visible focus, correct names, descriptions, disabled state, dismissal, focus return, and zero page overflow
+- **AND** unexpected axe, CSP, console, page, external-request, duplicate-control, stale-item, clipping, overlay, focus, or order failures fail the suite
+
+#### Scenario: Capability inventory remains reviewed
+- **WHEN** clean and incremental inventory and retained-target generation run after Menu Bar coverage is added
+- **THEN** output remains byte-identical unless a reviewed additive capability change intentionally updates the baseline
+- **AND** zero viewer defects and every qualified or excluded target remain discoverable
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/vaadin-application-menubar-adapter/spec.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/vaadin-application-menubar-adapter/spec.md
new file mode 100644
index 00000000000..33fe8336616
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/specs/vaadin-application-menubar-adapter/spec.md
@@ -0,0 +1,202 @@
+## ADDED Requirements
+
+### Requirement: Internal Menu Bar adapter boundary
+Qualified application-menu presentation SHALL remain behind `<cw-menubars>`, `<cw-menubar-primary>`, `<cw-menubar-secondary>`, and `<cw-menubar-tertiary>` public contracts.
+Raw Vaadin elements, item objects, events, methods, properties, theme internals, and Shadow DOM MUST remain unsupported application integration points.
+
+#### Scenario: Application shell declares semantic menu bars
+- **WHEN** the stable shell contains the established Causeway menu-bar elements
+- **THEN** each qualified tier may select an internal Menu Bar without changing that markup
+- **AND** application code does not receive or construct Vaadin items
+
+#### Scenario: Menu Bar emits an internal event
+- **WHEN** Menu Bar selects, opens, closes, overflows, focuses, or recreates an item
+- **THEN** the adapter translates only the reviewed signal into Causeway-owned behavior
+- **AND** raw toolkit events do not become public semantic events
+
+### Requirement: Independently preserved semantic tiers
+The adapter SHALL preserve primary, secondary, and tertiary tier identity through one independently qualified internal Menu Bar per non-empty tier.
+It MUST preserve source order and MUST NOT merge tiers or move content between them.
+
+#### Scenario: Three tiers are non-empty
+- **WHEN** accepted menu state contains primary, secondary, and tertiary menus
+- **THEN** each public tier hosts its own internal control in semantic order
+- **AND** CSS, diagnostics, refresh, and focus continue to identify the original tier
+
+#### Scenario: One tier is empty
+- **WHEN** an accepted generation contains no visible menu in one tier
+- **THEN** that public tier remains hidden and creates no internal control
+- **AND** the other tiers remain independently eligible
+
+### Requirement: Immutable Causeway item projection
+The host SHALL project accepted menu state into bounded immutable descriptors before creating adapter-private items.
+Descriptors MUST preserve menu, section, action, service, label, description, icon, visibility, usability, disabled-reason, tier, generation, and source-order semantics without containing executable callbacks or domain values.
+
+#### Scenario: Menu contains labeled and unlabeled sections
+- **WHEN** a representable menu contains actions grouped by labeled and unlabeled sections
+- **THEN** the item hierarchy preserves every grouping and action in source order
+- **AND** only leaf service actions are activatable
+
+#### Scenario: Labels are duplicated or localized
+- **WHEN** multiple actions share a label or labels change between generations
+- **THEN** selection resolves through opaque generation-scoped semantic identity rather than visible text
+- **AND** the current service logical type and action ID remain authoritative
+
+#### Scenario: Projection data is inspected
+- **WHEN** adapter-private item objects or diagnostics are reviewed
+- **THEN** they contain no GraphQL variables, prepared argument snapshots, protected values, serialized domain values, full errors, or executable interaction callbacks
+- **AND** metadata remains bounded to presentation identity and state
+
+### Requirement: Causeway-owned service-action activation
+Menu Bar item selection SHALL delegate exactly once to the established Causeway service-action interaction path.
+Vaadin callbacks MUST NOT construct GraphQL, navigate, interpret results, or bypass authorization, validation, preparation, cancellation, and host action-result policy.
+
+#### Scenario: Enabled leaf action is selected
+- **WHEN** the current generation resolves an enabled selected leaf identity
+- **THEN** the host invokes the same service context and action ID used by native presentation exactly once
+- **AND** existing interaction and result semantic events remain authoritative
+
+#### Scenario: Disabled item is selected internally
+- **WHEN** a selected item is disabled, stale, unknown, a menu, or a section grouping
+- **THEN** no service action is invoked
+- **AND** no navigation or GraphQL work is created
+
+#### Scenario: Action returns an object or void result
+- **WHEN** the established interaction controller publishes an action result
+- **THEN** existing host policy determines navigation, rendering, refresh, dismissal, or no-op behavior
+- **AND** Menu Bar does not infer a route from the result
+
+### Requirement: Disabled reasons and accessible semantics
+The adapter SHALL preserve labels, descriptions, hierarchy, disabled state, and bounded disabled reasons as accessible relationships.
+It MUST retain visible focus and distinguish expandable groupings from activatable actions.
+
+#### Scenario: Action is disabled with a reason
+- **WHEN** preparation marks a visible action unusable with a bounded reason
+- **THEN** the corresponding item is disabled and its accessible description exposes that reason
+- **AND** the item cannot invoke by keyboard or pointer
+
+#### Scenario: Assistive technology traverses a tier
+- **WHEN** a qualified tier is inspected or operated
+- **THEN** tier, menu, grouping, and action names and expanded or disabled states are available in semantic order
+- **AND** decorative icon hints are not announced as duplicate labels
+
+### Requirement: Responsive overflow qualification
+The host SHALL select Vaadin or complete native tier presentation from current policy, family health, generation, hierarchy, visibility, connection, and container-width qualification.
+Narrow Vaadin presentation MUST be used only when every visible authorized action retains order, keyboard access, accessible labeling, Escape behavior, focus return, and zero page overflow.
+
+#### Scenario: Wide representable tier qualifies
+- **WHEN** a connected non-empty representable tier is wide under the Vaadin policy
+- **THEN** it may use the internal Menu Bar and reviewed overflow behavior
+- **AND** all current actions remain reachable in source order
+
+#### Scenario: Narrow hierarchy is qualified
+- **WHEN** browser evidence accepts the hierarchy under current narrow width
+- **THEN** Menu Bar overflow preserves every authorized action, internationalized overflow labeling, dismissal, and focus
+- **AND** resizing issues no GraphQL request
+
+#### Scenario: Responsive equivalence is not proven
+- **WHEN** current width or hierarchy cannot preserve the accepted narrow contract
+- **THEN** the complete tier uses the established native responsive disclosure
+- **AND** no mixed native and Vaadin controls remain inside the tier
+
+### Requirement: Generation and revision scoped lifecycle
+Every asynchronous import, definition wait, projection, render, event, responsive transition, and focus restoration SHALL be bound to current connection, menu generation, policy, adapter, responsive, and family revisions.
+Cleanup MUST release generated controls, items, listeners, observers, and focus intent exactly once.
+
+#### Scenario: Refresh supersedes adapter work
+- **WHEN** menu refresh replaces a generation while import, definition, projection, or rendering remains pending
+- **THEN** stale work cannot install controls or activate items
+- **AND** only current accepted menu state is rendered
+
+#### Scenario: Tier disconnects or becomes native
+- **WHEN** a tier disconnects, empties, is replaced, changes policy, becomes unsupported, or becomes responsively disqualified
+- **THEN** adapter resources are released and native or hidden state is current
+- **AND** delayed work cannot restore the superseded control
+
+#### Scenario: Selected stale item arrives
+- **WHEN** an item-selected event references an earlier generation or revision
+- **THEN** it is ignored without invocation, navigation, focus corruption, or unbounded diagnostic data
+
+### Requirement: Semantic focus and dismissal continuity
+Focus and transient dismissal SHALL remain Causeway-owned across internal item recreation, overflow, refresh, responsive transitions, action completion, and native fallback.
+Focus identity MUST use tier and semantic action or grouping identity rather than toolkit DOM identity.
+
+#### Scenario: User dismisses with Escape
+- **WHEN** the user closes an expanded nested or overflow menu with Escape
+- **THEN** focus returns to the semantic item or safe tier target that opened it
+- **AND** sibling tiers retain their own transient state
+
+#### Scenario: Focused action disappears on refresh
+- **WHEN** authorization or state refresh removes the focused action
+- **THEN** focus resolves to a safe current tier target or shell location
+- **AND** it does not restore a stale or hidden toolkit node
+
+### Requirement: Family-scoped fallback and recovery
+Explicit native policy and automatic disqualification SHALL preserve the complete established native menu implementation.
+One Menu Bar family failure SHALL return every connected tier natively without disabling any other toolkit family or viewer subsystem.
+
+#### Scenario: Policy is native
+- **WHEN** `component-toolkit=native` is effective
+- **THEN** every menu tier uses native controls and requests no Menu Bar closure
+- **AND** GraphQL, menu resources, action semantics, routes, authentication, and markup remain unchanged
+
+#### Scenario: Closure or definition fails
+- **WHEN** Menu Bar import, definition, projection, rendering, CSP, or listener setup fails
+- **THEN** all connected tiers rerender from current authoritative state using native controls
+- **AND** references, fields, actions, Grid, GraphQL, routing, and authentication remain independently operational
+
+#### Scenario: Connected retry succeeds
+- **WHEN** the failed family is explicitly retried after the closure becomes available
+- **THEN** current qualified tiers may upgrade from current state
+- **AND** stale controls, items, listeners, or failure metadata are not reused
+
+### Requirement: Authenticated stable-shell lazy delivery
+The Menu Bar closure SHALL load only after an authenticated stable shell connects a non-empty qualified tier.
+Login, authentication challenge, failure, empty-menu, unsupported, and explicit-native states MUST request zero Menu Bar bytes.
+
+#### Scenario: Authenticated shell has a qualified tier
+- **WHEN** the first qualified tier connects under effective Vaadin policy
+- **THEN** one same-origin Menu Bar closure request is shared by all tiers and subsequent routes
+- **AND** route data and unrelated adapter readiness do not wait for it
+
+#### Scenario: Authentication chrome is rendered
+- **WHEN** login, authentication failure, access challenge, or logged-out chrome is shown
+- **THEN** no Menu Bar closure or internal control is requested
+- **AND** authentication behavior remains native and Spring-owned
+
+### Requirement: Deterministic secure Menu Bar packaging
+The implementation SHALL package a pinned independently reproducible free-core Menu Bar closure with accepted checksums, legal metadata, production vulnerability evidence, exact CSP style hashes, and raw and compressed budgets.
+Runtime closure paths MUST exclude telemetry activation, development-only code, commercial components, CDN assets, and external requests.
+
+#### Scenario: Ordinary Maven build runs
+- **WHEN** the Web Components reactor builds without an explicit regeneration profile
+- **THEN** checked-in Menu Bar bytes, policy metadata, hashes, licenses, and budgets are verified without npm
+- **AND** packaged resources are byte-identical to accepted assets
+
+#### Scenario: Explicit regeneration runs
+- **WHEN** the Menu Bar regeneration profile is invoked with supported Node and pinned inputs
+- **THEN** it audits, builds, verifies, and refreshes deterministic assets and legal metadata
+- **AND** unexpected dependency, checksum, hash, budget, telemetry, or vulnerability changes fail the gate
+
+#### Scenario: Production CSP runs
+- **WHEN** representative menu states execute under production CSP
+- **THEN** only reviewed exact candidate-originated style hashes are permitted with `style-src-attr 'none'`
+- **AND** there are no unexpected CSP violations or external requests
+
+### Requirement: Menu Bar accessibility and browser qualification
+Default and native application-menu journeys SHALL remain release-qualified across hierarchy, interaction, responsive, theme, security, authentication, failure, and lifecycle matrices.
+
+#### Scenario: Browser matrix runs
+- **WHEN** primary, secondary, tertiary, nested, labeled, disabled, hidden, parameterized, overflowed, refreshed, and failed menus run by keyboard and pointer in wide and narrow containers
+- **THEN** order, names, descriptions, expanded state, disabled reasons, focus, Escape, invocation, action results, native parity, and zero overflow satisfy the accepted contract
+- **AND** unexpected axe, CSP, console, page, external-request, duplicate-control, stale-item, clipping, overlay, focus, or order failures fail the suite
+
+#### Scenario: Themes and user preferences run
+- **WHEN** light, dark, reduced-motion, forced-colors, and zoom matrices exercise qualified and native menus
+- **THEN** content, visible focus, contrast, overflow, and action reachability remain accepted
+- **AND** no preference changes authoritative application-menu state
+
+#### Scenario: Failure diagnostics are inspected
+- **WHEN** import, definition, projection, render, interaction, route, refresh, or CSP failure is recorded
+- **THEN** diagnostics contain only family, phase, bounded classification, tier, and revision metadata
+- **AND** action values, GraphQL variables, prepared snapshots, protected values, and full errors remain absent
diff --git a/openspec/changes/use-vaadin-menu-bar-for-application-menus/tasks.md b/openspec/changes/use-vaadin-menu-bar-for-application-menus/tasks.md
new file mode 100644
index 00000000000..df920907e64
--- /dev/null
+++ b/openspec/changes/use-vaadin-menu-bar-for-application-menus/tasks.md
@@ -0,0 +1,116 @@
+## 1. Baseline and qualification contract
+
+- [ ] 1.1 Record native primary, secondary, and tertiary hierarchy, labels, sections, action order, disabled reasons, keyboard, focus, dismissal, refresh, and responsive baselines.
+- [ ] 1.2 Record authenticated, login, empty-menu, unsupported-menu, repeated-route, and explicit-native asset-request baselines.
+- [ ] 1.3 Inventory existing Menu Bar foundation, HTMX, Petclinic, Reference Application, CSP, accessibility, theme, and lifecycle tests before adaptation.
+- [ ] 1.4 Define immutable tier, menu, section, action, and opaque identity descriptors without domain values, executable callbacks, GraphQL variables, or full errors.
+- [ ] 1.5 Define deterministic qualification outcomes for Vaadin tier, native tier, hidden empty tier, and family failure.
+- [ ] 1.6 Define family, policy, menu-generation, adapter, responsive, and connection revisions used to reject stale work.
+- [ ] 1.7 Record accepted hierarchy and responsive exclusions and the complete-tier fallback rule.
+
+## 2. Deterministic Menu Bar closure
+
+- [ ] 2.1 Pin `@vaadin/menu-bar` and the exact reviewed free-core production dependency closure.
+- [ ] 2.2 Add an explicit browser entry point that imports only Menu Bar production modules and rejects telemetry activation.
+- [ ] 2.3 Add deterministic build inputs, lockfile, generated bundle, checksum, and raw plus compressed budget metadata.
+- [ ] 2.4 Generate complete third-party package and license metadata for the production closure.
+- [ ] 2.5 Add verification for pinned versions, dependency reachability, checksum, budgets, style hashes, licenses, telemetry, and prohibited runtime imports.
+- [ ] 2.6 Add production npm vulnerability audit and browser closure audit with zero external requests, CSP violations, axe violations, console errors, page errors, and overflow.
+- [ ] 2.7 Add generated Menu Bar assets and legal metadata to foundation Maven resources and RAT exclusions.
+- [ ] 2.8 Add ordinary Maven verification and an explicit regeneration profile without invoking npm in normal builds.
+- [ ] 2.9 Verify clean and incremental packaged Menu Bar bytes are identical to the accepted checksum.
+
+## 3. Projection and qualification foundation
+
+- [ ] 3.1 Add immutable Causeway Menu Bar projection for tiers, menus, labeled and unlabeled sections, and leaf actions.
+- [ ] 3.2 Preserve stable tier, menu, section, service logical type, action ID, label, description, icon hint, source-order, hidden, disabled, and reason semantics.
+- [ ] 3.3 Assign opaque generation-scoped lookup keys that do not rely on labels and reject duplicates or malformed identities safely.
+- [ ] 3.4 Ensure only current enabled leaf descriptors are activatable and grouping descriptors remain non-actions.
+- [ ] 3.5 Add qualification for policy, family health, connection, visibility, non-empty state, current generation, representable hierarchy, and responsive width.
+- [ ] 3.6 Reject unsupported, malformed, stale, empty, disconnected, hidden, failed, and native-policy tiers without constructing Vaadin items.
+- [ ] 3.7 Add projection and qualification tests for all tier, section, action-state, identity, exclusion, and immutability cases.
+
+## 4. Menu Bar family adapter
+
+- [ ] 4.1 Add one private Menu Bar family loader with dynamic import, definition waiting, bounded timeout, retry, and value-free diagnostics.
+- [ ] 4.2 Add a private adapter control that creates `vaadin-menu-bar`, applies immutable items, sets accessible tier identity, and exposes no raw API publicly.
+- [ ] 4.3 Translate top-level menus, nested labeled sections, unlabeled actions, disabled state, descriptions, and icon hints without changing order.
+- [ ] 4.4 Translate item-selected only through current opaque leaf identity and the existing Causeway activation callback.
+- [ ] 4.5 Ignore stale, unknown, disabled, grouping, duplicate, and malformed selected items without GraphQL, navigation, or focus side effects.
+- [ ] 4.6 Release item arrays, listeners, generated controls, timers, observers, and focus state exactly once.
+- [ ] 4.7 Fail the Menu Bar family without affecting reference, field, action, Grid, GraphQL, route, or authentication families.
+- [ ] 4.8 Recover connected qualified tiers from current Causeway state after an explicit family retry.
+- [ ] 4.9 Add adapter tests for success, timeout, definition failure, render failure, event failure, family fallback, isolation, cleanup, and recovery.
+
+## 5. Causeway activation focus and responsive behavior
+
+- [ ] 5.1 Refactor native service-action activation into one Causeway-owned method reusable by native buttons and Menu Bar selection.
+- [ ] 5.2 Preserve interaction-controller preparation, invocation, cancellation, validation, result, refresh, and host navigation policy exactly once.
+- [ ] 5.3 Preserve bounded disabled reasons through item disabled state and accessible description.
+- [ ] 5.4 Track focus intent by tier and semantic menu, section, or action identity rather than toolkit nodes.
+- [ ] 5.5 Restore focus safely after Escape, item activation, refresh, action completion, responsive switching, native fallback, and item removal.
+- [ ] 5.6 Add container-responsive observation with out-of-callback state application and no GraphQL request on width transitions.
+- [ ] 5.7 Use Vaadin overflow at narrow widths only for accepted representative hierarchies and otherwise retain complete native tier disclosures.
+- [ ] 5.8 Preserve internationalized overflow labels, nested keyboard behavior, pointer behavior, visible focus, Escape dismissal, and sibling-tier isolation.
+- [ ] 5.9 Add focused tests for keyboard, pointer, disabled state, focus, dismissal, overflow, responsive transitions, and zero semantic rereads.
+
+## 6. Menu host lifecycle and native fallback
+
+- [ ] 6.1 Integrate qualification into ready tier rendering without changing loading, unsupported, terminal-error, empty, hidden, or partial-diagnostic states.
+- [ ] 6.2 Preserve the current native renderer as explicit and automatic fallback without compatibility aliases or mixed controls.
+- [ ] 6.3 Gate every asynchronous completion and selection by connection, menu generation, policy, adapter, responsive, and family revisions.
+- [ ] 6.4 Prevent delayed imports, definitions, renders, events, and focus work from restoring disconnected, superseded, hidden, empty, or native tiers.
+- [ ] 6.5 Rerender every connected tier natively after one family failure from current authoritative state.
+- [ ] 6.6 Preserve existing menu-state and diagnostic semantic events without leaking Vaadin items, action values, callbacks, or full errors.
+- [ ] 6.7 Preserve composite and independently used bar elements, private and injected contexts, and generated interaction-controller ownership.
+- [ ] 6.8 Add host tests for every state, refresh, disconnect, replacement, policy change, responsive change, failure phase, retry, and stale callback.
+
+## 7. HTMX stable-shell policy CSP and delivery
+
+- [ ] 7.1 Publish same-origin Menu Bar closure URL, resolved common component policy, and bounded family diagnostics through the HTMX shell.
+- [ ] 7.2 Extend default and deprecated editor-policy compatibility to Menu Bar while keeping deprecated pilot properties limited to their original subsets.
+- [ ] 7.3 Ensure explicit native policy contributes no Menu Bar style hash, request eligibility, or generated control.
+- [ ] 7.4 Extend exact-hash CSP metadata with the deterministic deduplicated Menu Bar candidate-originated style hash set.
+- [ ] 7.5 Preserve `style-src-attr 'none'`, no `unsafe-inline`, same-origin script and connection policy, and existing authentication policy.
+- [ ] 7.6 Lazy-load Menu Bar only after an authenticated stable shell connects a non-empty qualified tier and deduplicate across tiers and routes.
+- [ ] 7.7 Prove login, challenge, authentication failure, logout, empty-menu, unsupported, and native states request zero Menu Bar bytes.
+- [ ] 7.8 Add HTMX property, renderer, controller, CSP, policy precedence, shell publication, authentication exclusion, and packaging tests.
+
+## 8. Themes documentation and samples
+
+- [ ] 8.1 Map established menu colors, spacing, typography, borders, radii, focus, disabled, error, and tier distinctions through Causeway CSS variables and parts.
+- [ ] 8.2 Preserve light, dark, reduced-motion, forced-colors, zoom, narrow, and wide rendering without inline style attributes.
+- [ ] 8.3 Extend the vanilla sample with deterministic qualified, native, empty, disabled, hidden, nested, labeled-section, overflow, failure, and responsive menu states.
+- [ ] 8.4 Extend Petclinic with representative primary, secondary, tertiary, disabled, nested, action-result, wide, narrow, default, and native journeys without raw Vaadin markup.
+- [ ] 8.5 Document qualification, stable-shell cost, hierarchy projection, action ownership, delivery, CSP, budgets, diagnostics, fallback, rollback, and unsupported raw APIs.
+- [ ] 8.6 Document exclusions for Flow, Binder, server-side state, commercial components, telemetry, CDN resources, direct GraphQL, direct navigation, and application item APIs.
+
+## 9. Foundation security accessibility and isolation evidence
+
+- [ ] 9.1 Add source audits preventing application-facing raw Menu Bar markup, items, events, callbacks, methods, properties, Shadow DOM, direct GraphQL, or direct navigation APIs.
+- [ ] 9.2 Verify item objects, diagnostics, semantic events, console output, and failure details contain no domain values, protected values, GraphQL variables, prepared snapshots, full errors, or executable callbacks.
+- [ ] 9.3 Verify closure raw, compressed, request-count, style-hash, package-count, startup, and activation budgets with retained evidence.
+- [ ] 9.4 Verify zero telemetry activation, production vulnerabilities, external runtime requests, CSP violations, axe violations, console errors, page errors, overlays, clipping, and page overflow.
+- [ ] 9.5 Verify accessible tier, menu, section, action, expanded, disabled, reason, overflow, focus, and dismissal semantics under keyboard and pointer input.
+- [ ] 9.6 Verify family failure and retry remain isolated from every other adapter, GraphQL, routes, authentication, and native menu state.
+
+## 10. Petclinic and Reference Application regression qualification
+
+- [ ] 10.1 Add deterministic Reference Application targets for all three tiers, nested and labeled sections, hidden and disabled actions, parameterized actions, object and void results, refresh, and overflow.
+- [ ] 10.2 Add default and native comparisons for hierarchy, source order, labels, descriptions, icon hints, action identity, disabled reasons, invocation, results, and focus.
+- [ ] 10.3 Add overlapping metadata, resource, preparation, refresh, import, definition, projection, and route-replacement lifecycle journeys.
+- [ ] 10.4 Inject family failures before connection, during import and definition, after connection, during rendering, and during event translation, then prove connected recovery.
+- [ ] 10.5 Verify responsive transitions and repeated routes issue no semantic reread and request the Menu Bar closure at most once.
+- [ ] 10.6 Verify login, authentication failure, challenge, logout, empty-menu, unsupported, explicit-native, and pilot-subset profiles request no Menu Bar closure.
+- [ ] 10.7 Run keyboard, pointer, Escape, focus, zoom, theme, reduced-motion, forced-colors, CSP, accessibility, clipping, order, and overflow matrices.
+- [ ] 10.8 Review capability inventory changes and prove clean and incremental retained resources are byte-identical.
+
+## 11. Final qualification and evidence
+
+- [ ] 11.1 Run complete foundation Node and Web Components Maven suites.
+- [ ] 11.2 Run HTMX configuration, shell, CSP, route, authentication, and packaging suites.
+- [ ] 11.3 Run deterministic reference, field, action, Grid, and Menu Bar checksum, license, budget, telemetry, and npm audit gates.
+- [ ] 11.4 Run complete vanilla sample and Petclinic integration and default plus native Playwright suites.
+- [ ] 11.5 Run Reference Application clean package, integration, inventory, and default plus native Playwright suites.
+- [ ] 11.6 Run applicable RAT, production-isolation, JavaScript syntax, strict OpenSpec validation, and `git diff --check` gates.
+- [ ] 11.7 Record final supported modes, narrow qualification, fallback, rollback, accepted stable-shell budgets, retained evidence, and exclusions.
diff --git a/openspec/planned-changes/web-component-viewer/README.md b/openspec/planned-changes/web-component-viewer/README.md
index 36eecef37e0..27b2c8889ed 100644
--- a/openspec/planned-changes/web-component-viewer/README.md
+++ b/openspec/planned-changes/web-component-viewer/README.md
@@ -10,9 +10,9 @@ The union-projection correction is archived.
 The opaque-route correction is archived.
 The archived `add-paged-graphql-reference-autocomplete` change adds honest bounded server response windows, and the archived `expand-vaadin-semantic-editor-families` change qualifies the broader editor families before the default-policy flip in `vaadin-default-roadmap.md`.
 The archived `make-vaadin-default-for-webcomponent-viewer` change completes the policy-focused Vaadin-editor-default sequence while retaining explicit native rollback.
-The archived `extend-vaadin-to-domain-member-presentation` change, promoted active `use-vaadin-grid-for-collection-presentation` change, and proposal-only `use-vaadin-menu-bar-for-application-menus` draft extend that internal toolkit to read-only fields and buttons, collections, and application navigation in independently reviewable tranches.
+The archived `extend-vaadin-to-domain-member-presentation` and `use-vaadin-grid-for-collection-presentation` changes and promoted active `use-vaadin-menu-bar-for-application-menus` change extend that internal toolkit to read-only fields and buttons, collections, and application navigation in independently reviewable tranches.
 Their order, shared boundaries, and promotion gates are recorded in `vaadin-presentation-roadmap.md`.
-Do not promote the remaining Menu Bar follow-on until the active Grid tranche is archived and its evidence is reviewed.
+The Grid evidence has been reviewed and the Menu Bar follow-on is now the single active tranche.
 The older Vue, Svelte, metadata, diagnostics, performance-analysis, catalogue, and designer drafts remain queued for separate review.
 Proposal-only security drafts separate local SecMan authentication for the HTMX viewer, subsequent OAuth/OIDC support, eventual promotion of the proven bridge into shared Causeway security, future CSRF-safe Wicket and HTMX coexistence, and stable SecMan delegated-user identity mapping.
 
diff --git a/openspec/planned-changes/web-component-viewer/vaadin-presentation-roadmap.md b/openspec/planned-changes/web-component-viewer/vaadin-presentation-roadmap.md
index 669cb01ff1f..171df255207 100644
--- a/openspec/planned-changes/web-component-viewer/vaadin-presentation-roadmap.md
+++ b/openspec/planned-changes/web-component-viewer/vaadin-presentation-roadmap.md
@@ -1,6 +1,6 @@
 # Vaadin presentation follow-on roadmap
 
-The current accepted architecture makes Vaadin free-core the default internal toolkit for qualified references, editors, read-only fields, and ordinary action buttons while keeping collections and application menus Causeway-native.
+The current accepted architecture makes Vaadin free-core the default internal toolkit for qualified references, editors, read-only fields, ordinary action buttons, and qualified collections while keeping application menus Causeway-native.
 The follow-on direction is to evaluate Vaadin as the default internal presentation toolkit without changing the public `cw-*` semantic boundary.
 
 The work is split because fields and buttons are local controls, Grid is a virtualized data surface, and Menu Bar is stable-shell application navigation.
@@ -19,8 +19,8 @@ eligible fields and action buttons
 | Order | Proposal | Purpose | Promotion gate |
 |---:|---|---|---|
 | 1 | `extend-vaadin-to-domain-member-presentation` *(archived)* | Use qualified read-only Vaadin fields and action buttons behind property and action components. | View/edit parity, action semantics, accessibility, theming, route loading, CSP, packaging, and native rollback pass the foundation, Petclinic, and Reference Application suites. |
-| 2 | `use-vaadin-grid-for-collection-presentation` *(active)* | Use an internal Grid for qualified collection presentations. | Existing bounded-window, row-context, nullable-total, semantic-cell, responsive, cancellation, and native-fallback contracts are proven without claiming database pushdown. |
-| 3 | `use-vaadin-menu-bar-for-application-menus` | Use internal Menu Bar item trees behind the three semantic application-menu tiers. | Hierarchy, order, disabled state, service-action invocation, overflow, keyboard, refresh, authentication exclusions, stable-shell loading, and native fallback pass broad acceptance coverage. |
+| 2 | `use-vaadin-grid-for-collection-presentation` *(archived)* | Use an internal Grid for qualified collection presentations. | Existing bounded-window, row-context, nullable-total, semantic-cell, responsive, cancellation, and native-fallback contracts are proven without claiming database pushdown. |
+| 3 | `use-vaadin-menu-bar-for-application-menus` *(active)* | Use internal Menu Bar item trees behind the three semantic application-menu tiers. | Hierarchy, order, disabled state, service-action invocation, overflow, keyboard, refresh, authentication exclusions, stable-shell loading, and native fallback pass broad acceptance coverage. |
 
 The order is a review sequence rather than a hard runtime dependency.
 Grid and Menu Bar MUST use separate packaged closures and MAY be rejected independently if their payload, accessibility, semantic, or fallback costs outweigh the styling benefit.
@@ -41,4 +41,4 @@ Grid and Menu Bar MUST use separate packaged closures and MAY be rejected indepe
 
 The archived field-and-action tranche resolved the common policy as `component-toolkit=vaadin|native` with bounded deprecated compatibility inputs.
 The promoted Grid change resolves unavailable totals through bounded Grid with Causeway-owned paging and retains native collection presentation at or below the existing 48rem container boundary.
-The Menu Bar proposal must verify that one internal Menu Bar per semantic tier preserves the existing responsive and keyboard contracts before custom disclosures are removed.
+The promoted Menu Bar change verifies that one internal Menu Bar per semantic tier preserves the existing responsive and keyboard contracts before custom disclosures are removed.