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/30 13:50:17 UTC
(causeway) 02/05: docs(openspec): propose action presentation enhancements
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 423059cee13746c222469c18ddf49cc0772eabfe
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Aug 30 10:12:36 2026 +0200
docs(openspec): propose action presentation enhancements
---
.../enhance-action-presentation/.openspec.yaml | 2 +
.../changes/enhance-action-presentation/design.md | 109 +++++++++++++++++++++
.../enhance-action-presentation/proposal.md | 33 +++++++
.../specs/domain-web-components/spec.md | 71 ++++++++++++++
.../generic-htmx-web-component-viewer/spec.md | 38 +++++++
.../specs/graphql-web-component-context/spec.md | 25 +++++
.../specs/rich-graphql-member-metadata/spec.md | 25 +++++
.../vaadin-application-menubar-adapter/spec.md | 39 ++++++++
.../changes/enhance-action-presentation/tasks.md | 34 +++++++
9 files changed, 376 insertions(+)
diff --git a/openspec/changes/enhance-action-presentation/.openspec.yaml b/openspec/changes/enhance-action-presentation/.openspec.yaml
new file mode 100644
index 00000000000..88ea4823207
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-08-30
diff --git a/openspec/changes/enhance-action-presentation/design.md b/openspec/changes/enhance-action-presentation/design.md
new file mode 100644
index 00000000000..2ba48cafdc4
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/design.md
@@ -0,0 +1,109 @@
+## Context
+
+The ordinary action component already discovers hidden, disabled, and canonical description state, but its visible label falls back directly from `label` to a humanized member ID and its description is only hidden explanatory text.
+Parameterized prompts independently humanize the action ID, so authored or canonical names and descriptions are lost at the dialog boundary.
+Application menus already parse effective-menu names, descriptions, and Font Awesome hints, but disabled reasons replace rather than compose with descriptions and icon hints currently create only empty placeholders.
+Rich member metadata has a shared additive metadata object, but it does not expose action Font Awesome facets or their position.
+
+The change crosses GraphQL schema generation, browser metadata discovery, ordinary and Vaadin action controls, effective-menu parsing, prompt state, shared assets, and sample coverage.
+Action presentation must remain escaped, bounded, authorization-safe, toolkit-neutral, and backward-compatible with older rich GraphQL schemas.
+
+## Goals / Non-Goals
+
+**Goals:**
+
+- Let HTML authors override an action name with `named` while retaining `label` compatibility.
+- Preserve canonical action names and descriptions through buttons, menus, and parameterized prompts.
+- Compose description and disabled reason as separate tooltip sections.
+- Render static `@ActionLayout(cssClassFa, cssClassFaPosition)` metadata with pinned same-origin Font Awesome assets.
+- Keep native and Vaadin-backed action and menu presentations semantically equivalent.
+- Demonstrate representative behavior in Petclinic without changing every action.
+
+**Non-Goals:**
+
+- Do not expose imperative icon methods, arbitrary HTML, action CSS classes, or other metamodel internals through rich metadata.
+- Do not add application-authored icon overrides to `<cw-action>`.
+- Do not change action execution, authorization, validation, result navigation, or refresh semantics.
+- Do not redesign prompts or add configurable description presentation modes for actions.
+- Do not load fonts, styles, or icons from a CDN.
+
+## Decisions
+
+### Action naming uses established authored precedence
+
+`<cw-action>` will observe and reflect `named` in addition to compatible `label`.
+The effective name precedence will be `named`, then `label`, then canonical `metadata.friendlyName`, then a humanized action ID.
+This matches collection naming vocabulary while preserving existing pages that use `label`.
+
+An alternative was to replace `label` outright, but that would break compatible application markup without improving semantics.
+
+### Rich metadata exposes only static action icon data
+
+The shared rich member metadata type will add nullable `cssClassFa` and `cssClassFaPosition` fields.
+Only action wrappers with a static Font Awesome facet will populate them; other wrappers, absent facets, and imperative icon facets will return null.
+The class value will use Causeway's canonical quick notation and the position will use the canonical `LEFT` or `RIGHT` token.
+
+This keeps the schema additive and avoids exposing executable icon behavior or broad layout metadata.
+
+### Browser discovery remains tolerant of older schemas
+
+Object and service action discovery will request the new metadata fields only when introspection advertises them.
+Normalized action presentation will carry bounded name, description, icon classes, and position into ordinary component state and interaction capabilities.
+Parameterized prompt state will copy that presentation once preparation succeeds, and subsequent recomputation will preserve it.
+Older schemas will continue to render names and prompts using established fallbacks without issuing invalid selections.
+
+### Tooltips use one bounded composed presentation
+
+Action descriptions and disabled reasons will be independently bounded and escaped, then composed with a blank-line section separator.
+Ordinary action controls and native and Vaadin menu items will expose the composed tooltip while retaining hidden `aria-describedby` sections for assistive technology.
+A disabled reason will never replace an available description.
+Disabled ordinary controls will retain a focusable explanatory wrapper so keyboard users can reach the tooltip without making the action invokable.
+
+Using only a native `title` attribute was rejected because it is not reliably keyboard-accessible and cannot provide consistent section styling.
+
+### Parameterized prompts use the prepared action presentation
+
+When an action has parameters, the dialog heading will use the same effective action name as the invoking control or menu item.
+A non-duplicate canonical description will render immediately below the heading using the quiet description styling already established for properties and collections.
+The description will participate in the dialog's accessible description alongside any current error.
+Parameterless actions will continue directly to invocation without opening a dialog.
+
+### Font Awesome rendering is same-origin and token-bounded
+
+The HTMX shell will load the pinned Font Awesome WebJar stylesheet from the same origin before application styles.
+Browser rendering will accept only bounded whitespace-separated CSS class tokens matching the Font Awesome token vocabulary and will add the required base class.
+Icons will be decorative, `aria-hidden`, and placed before or after the label according to the canonical position.
+Invalid, missing, or unsupported icon metadata will render no icon and will not affect action availability.
+
+An internal icon-name map was rejected because it would be incomplete and would duplicate the pinned Font Awesome distribution.
+A CDN stylesheet was rejected because it would violate offline, CSP, and external-request constraints.
+
+### Effective application menus retain layout position
+
+Effective-menu parsing and immutable projections will preserve `cssClassFaPosition` alongside the existing action icon hint.
+Native menu rendering and Vaadin Menu Bar materialization will use the same bounded icon helper and composed tooltip helper.
+Menu labels and sections remain unchanged, and raw Vaadin menu item state remains private.
+
+## Risks / Trade-offs
+
+- [Font Awesome WebJar increases shell CSS and font assets] → Pin the existing repository version, serve it lazily through same-origin WebJar paths, and cover packaging, CSP, and external-request behavior.
+- [Arbitrary facet strings could become unsafe classes] → Bound length, tokenize rather than interpolate markup, accept only conservative Font Awesome class tokens, and escape all attributes.
+- [Disabled controls are normally removed from keyboard order] → Put explanation focus on a non-invoking wrapper while leaving the disabled control itself disabled.
+- [Shared metadata fields appear on non-action wrappers] → Return null outside applicable static action facets and document the narrow action-only semantics.
+- [Prompt metadata could become stale during recomputation] → Freeze presentation from the current prepared capabilities and retire it with the existing prompt generation.
+- [Native and Vaadin menu tooltip behavior can diverge] → Project one composed descriptor and test both default and explicit-native browser modes.
+
+## Migration Plan
+
+1. Add additive GraphQL metadata and tolerant browser discovery.
+2. Add shared bounded tooltip and icon projection helpers.
+3. Update ordinary action controls and parameterized prompts.
+4. Update effective-menu parsing, projection, and native and Vaadin rendering.
+5. Add the pinned same-origin stylesheet and Petclinic demonstrations.
+6. Validate GraphQL approvals, foundation tests, HTMX rendering, Petclinic integration and Playwright modes, RAT, CSP, and strict OpenSpec consistency.
+
+Rollback removes the additive metadata fields, shell stylesheet, and browser presentation use without changing persisted data or action execution contracts.
+
+## Open Questions
+
+None.
diff --git a/openspec/changes/enhance-action-presentation/proposal.md b/openspec/changes/enhance-action-presentation/proposal.md
new file mode 100644
index 00000000000..92a5e751929
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/proposal.md
@@ -0,0 +1,33 @@
+## Why
+
+`<cw-action>` currently cannot override its visible name with the same HTML-authored vocabulary used by properties and collections, and action descriptions, disabled reasons, and Font Awesome layout facets are not presented consistently across object buttons, prompts, and application-menu items.
+This leaves application-authored pages less expressive and discards useful canonical action presentation metadata already present in the Causeway metamodel.
+
+## What Changes
+
+- Add a `named` attribute and reflected property to `<cw-action>`, with precedence over the compatible legacy `label` override and canonical metadata.
+- Present canonical action descriptions as bounded accessible tooltips on ordinary object-action buttons and application-menu action items.
+- Compose disabled reasons into the same tooltip as a separate section when a description is also present.
+- Show the effective action name and its canonical description in parameterized action dialogs.
+- Add narrow rich GraphQL action metadata for static Font Awesome classes and left/right position.
+- Render declared Font Awesome action icons in ordinary action buttons and native and Vaadin-backed application menus without exposing arbitrary markup or broad metamodel internals.
+- Extend selected Petclinic actions with representative HTML-authored names, descriptions, disabled reasons, icons, positions, and parameterized-dialog coverage while leaving other actions unchanged.
+
+## Capabilities
+
+### New Capabilities
+
+None.
+
+### Modified Capabilities
+
+- `domain-web-components`: Define action naming precedence, tooltip composition, dialog heading and description presentation, and bounded Font Awesome icon rendering.
+- `rich-graphql-member-metadata`: Expose nullable static Font Awesome class and position metadata for action wrappers.
+- `graphql-web-component-context`: Select and preserve canonical action name, description, and icon metadata through ordinary rendering and parameterized interaction preparation.
+- `vaadin-application-menubar-adapter`: Preserve composed action tooltips and positioned Font Awesome icons across native and Vaadin-backed application menus.
+- `generic-htmx-web-component-viewer`: Deliver the same-origin Font Awesome stylesheet and demonstrate selected action presentation in Petclinic.
+
+## Impact
+
+The change affects rich GraphQL member metadata, object and service action discovery, `<cw-action>`, action widgets, interaction dialogs, effective-menu parsing and projection, Vaadin Menu Bar materialization, shared styling, the HTMX shell asset set, and Petclinic fixtures and acceptance tests.
+It adds a pinned Font Awesome WebJar runtime asset to the generic HTMX viewer and remains additive for existing GraphQL clients and HTML pages.
diff --git a/openspec/changes/enhance-action-presentation/specs/domain-web-components/spec.md b/openspec/changes/enhance-action-presentation/specs/domain-web-components/spec.md
new file mode 100644
index 00000000000..549e8844898
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/specs/domain-web-components/spec.md
@@ -0,0 +1,71 @@
+## ADDED Requirements
+
+### Requirement: Authored and canonical action naming
+`<cw-action>` SHALL accept an optional `named` attribute and reflected property for its visible action name.
+The effective action name MUST use `named`, then compatible `label`, then canonical metadata, then the humanized action identifier.
+
+#### Scenario: HTML name is supplied
+- **WHEN** an action element declares `named="Place a new order"`
+- **THEN** its ordinary control and any parameterized prompt use `Place a new order`
+- **AND** the semantic action identifier remains unchanged
+
+#### Scenario: Compatible label is supplied
+- **WHEN** `named` is absent and an existing action element declares `label`
+- **THEN** the compatible label remains the visible name
+- **AND** canonical metadata and humanized fallback do not override it
+
+#### Scenario: No authored name is supplied
+- **WHEN** neither `named` nor `label` supplies a name
+- **THEN** canonical action metadata supplies the visible name when available
+- **AND** a humanized action identifier remains the bounded fallback for older schemas
+
+### Requirement: Action tooltip composition
+An ordinary action control SHALL present a bounded canonical description as an accessible tooltip.
+When the action is disabled, its bounded disabled reason MUST appear in the tooltip as a separate section without replacing an available description.
+
+#### Scenario: Enabled described action renders
+- **WHEN** a visible enabled action has a canonical description
+- **THEN** pointer and keyboard users can obtain that description from the action control tooltip
+- **AND** the description remains escaped and associated through accessible descriptive semantics
+
+#### Scenario: Disabled action has description and reason
+- **WHEN** a visible action has both a canonical description and a disabled reason
+- **THEN** its non-invoking control presents the description and disabled reason as separate tooltip sections
+- **AND** activation remains unavailable
+
+#### Scenario: Disabled action has only a reason
+- **WHEN** a visible action has no description and has a disabled reason
+- **THEN** the tooltip contains the disabled reason without an empty section
+- **AND** the reason remains available to assistive technology
+
+### Requirement: Parameterized action prompt presentation
+A parameterized action prompt SHALL present the effective action name as its heading and a non-duplicate canonical action description as quiet explanatory text immediately below.
+
+#### Scenario: Described parameterized action opens
+- **WHEN** action preparation returns one or more parameters and current action presentation includes a description
+- **THEN** the dialog heading uses the effective action name
+- **AND** the escaped description appears below the heading and participates in the dialog description
+
+#### Scenario: Parameterless action executes
+- **WHEN** action preparation returns no parameters
+- **THEN** established direct invocation remains in effect
+- **AND** no presentation-only prompt is introduced
+
+### Requirement: Font Awesome action icon presentation
+Ordinary action controls SHALL render applicable static Font Awesome metadata as a decorative icon before or after the action name according to its canonical position.
+Icon metadata MUST be bounded and tokenized and MUST NOT inject markup or alter action semantics.
+
+#### Scenario: Left-positioned icon is supplied
+- **WHEN** action metadata supplies accepted Font Awesome classes with `LEFT` position
+- **THEN** a decorative icon precedes the action name
+- **AND** the accessible name remains the textual action name
+
+#### Scenario: Right-positioned icon is supplied
+- **WHEN** action metadata supplies accepted Font Awesome classes with `RIGHT` position
+- **THEN** a decorative icon follows the action name
+- **AND** native and Vaadin action controls retain equivalent order
+
+#### Scenario: Icon metadata is absent or invalid
+- **WHEN** action metadata has no accepted static Font Awesome classes or position
+- **THEN** no icon is rendered
+- **AND** the action name, usability, invocation, and focus behavior remain unchanged
diff --git a/openspec/changes/enhance-action-presentation/specs/generic-htmx-web-component-viewer/spec.md b/openspec/changes/enhance-action-presentation/specs/generic-htmx-web-component-viewer/spec.md
new file mode 100644
index 00000000000..74c1e53aefe
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/specs/generic-htmx-web-component-viewer/spec.md
@@ -0,0 +1,38 @@
+## ADDED Requirements
+
+### Requirement: Same-origin Font Awesome action assets
+The generic HTMX shell SHALL provide the pinned Font Awesome stylesheet and fonts from same-origin packaged WebJar resources for action and menu icon presentation.
+Asset delivery MUST remain compatible with production CSP, offline operation, application styling, and browser external-request isolation.
+
+#### Scenario: HTMX shell renders
+- **WHEN** the generic shell is requested
+- **THEN** it links the pinned same-origin Font Awesome stylesheet before application styles
+- **AND** no CDN or external font request is introduced
+
+#### Scenario: Font Awesome asset is requested
+- **WHEN** a declared action icon causes the browser to resolve a font resource
+- **THEN** the asset is served from the packaged application origin
+- **AND** the response participates in established cache and security policy
+
+### Requirement: Selective Petclinic action presentation demonstration
+Petclinic HTML pages and domain actions SHALL demonstrate selected authored names, canonical descriptions, disabled tooltip sections, parameterized prompt descriptions, and left and right Font Awesome icon positions without changing unselected actions.
+
+#### Scenario: Selected object action renders
+- **WHEN** a representative Petclinic page composes a selected `<cw-action>`
+- **THEN** its authored `named` value takes precedence for visible control and prompt text
+- **AND** canonical tooltip and icon metadata remain domain-driven
+
+#### Scenario: Selected service action renders
+- **WHEN** a representative Petclinic service action appears in the application menu
+- **THEN** its canonical description and positioned Font Awesome icon appear in native and Vaadin-backed menu presentations
+- **AND** parameterized invocation uses the same effective action presentation
+
+#### Scenario: Selected action is disabled
+- **WHEN** Petclinic state disables a representative described action
+- **THEN** its tooltip separates canonical description from the disabled reason
+- **AND** browser acceptance verifies that the action cannot be invoked
+
+#### Scenario: Unselected action renders
+- **WHEN** a Petclinic action has no new authored name, description, or icon metadata
+- **THEN** its established label, tooltip absence, and invocation behavior remain unchanged
+- **AND** no default icon is fabricated
diff --git a/openspec/changes/enhance-action-presentation/specs/graphql-web-component-context/spec.md b/openspec/changes/enhance-action-presentation/specs/graphql-web-component-context/spec.md
new file mode 100644
index 00000000000..707c1109c78
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/specs/graphql-web-component-context/spec.md
@@ -0,0 +1,25 @@
+## ADDED Requirements
+
+### Requirement: Action presentation metadata continuity
+The GraphQL Web Component context SHALL discover available canonical action name, description, static Font Awesome classes, and icon position and preserve them through ordinary component state and action preparation.
+Discovery MUST remain compatible with rich schemas that omit the additive icon fields.
+
+#### Scenario: Current schema advertises action presentation metadata
+- **WHEN** action discovery introspects the additive metadata fields
+- **THEN** the current action state contains bounded canonical name, description, icon classes, and position
+- **AND** unrelated metadata and hidden members are not selected
+
+#### Scenario: Older schema omits icon fields
+- **WHEN** action discovery introspects a compatible schema without additive Font Awesome metadata
+- **THEN** the generated operation omits the unsupported fields
+- **AND** naming, description, action preparation, and invocation remain available
+
+#### Scenario: Parameterized action is prepared
+- **WHEN** current action preparation succeeds with one or more parameters
+- **THEN** the prepared capabilities retain the current canonical action presentation
+- **AND** subsequent parameter recomputation preserves it until the prompt generation is retired
+
+#### Scenario: Action generation is superseded
+- **WHEN** route, object, service, authorization, refresh, or action generation changes
+- **THEN** stale action presentation cannot replace current control or prompt metadata
+- **AND** no stale icon, tooltip, name, or description is rendered
diff --git a/openspec/changes/enhance-action-presentation/specs/rich-graphql-member-metadata/spec.md b/openspec/changes/enhance-action-presentation/specs/rich-graphql-member-metadata/spec.md
new file mode 100644
index 00000000000..d21d503e8ce
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/specs/rich-graphql-member-metadata/spec.md
@@ -0,0 +1,25 @@
+## ADDED Requirements
+
+### Requirement: Static action Font Awesome metadata
+The shared rich member metadata object SHALL expose nullable `cssClassFa` and `cssClassFaPosition` fields for applicable static action Font Awesome facets.
+It MUST NOT execute imperative icon logic or expose arbitrary action layout internals.
+
+#### Scenario: Static action icon facet exists
+- **WHEN** an action has an accepted static Font Awesome facet
+- **THEN** `cssClassFa` returns its canonical bounded quick notation
+- **AND** `cssClassFaPosition` returns the canonical `LEFT` or `RIGHT` token
+
+#### Scenario: Static action icon facet is absent
+- **WHEN** an action has no static Font Awesome facet
+- **THEN** both icon metadata fields return null
+- **AND** no default icon or position is fabricated
+
+#### Scenario: Metadata belongs to another wrapper
+- **WHEN** property, collection, or action-parameter metadata is requested
+- **THEN** action icon metadata fields return null
+- **AND** existing names, descriptions, and editor constraints remain unchanged
+
+#### Scenario: Icon behavior is imperative
+- **WHEN** icon behavior would require invoking domain code
+- **THEN** static icon metadata returns null
+- **AND** metadata resolution remains side-effect-free
diff --git a/openspec/changes/enhance-action-presentation/specs/vaadin-application-menubar-adapter/spec.md b/openspec/changes/enhance-action-presentation/specs/vaadin-application-menubar-adapter/spec.md
new file mode 100644
index 00000000000..2b497c82716
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/specs/vaadin-application-menubar-adapter/spec.md
@@ -0,0 +1,39 @@
+## ADDED Requirements
+
+### Requirement: Equivalent service-action tooltip composition
+Native and Vaadin-backed application-menu action items SHALL present the same bounded canonical description and disabled reason tooltip sections.
+A disabled reason MUST NOT replace an available description.
+
+#### Scenario: Enabled described menu action renders
+- **WHEN** a current visible service action has a canonical description and is enabled
+- **THEN** its native or Vaadin-backed menu item exposes the description tooltip
+- **AND** activation continues through the existing Causeway service-action path
+
+#### Scenario: Disabled described menu action renders
+- **WHEN** a current visible service action has both a canonical description and a disabled reason
+- **THEN** its menu item exposes both as separate tooltip sections
+- **AND** the item remains non-invoking and accessibly explained
+
+#### Scenario: Menu presentation changes
+- **WHEN** responsive, policy, recovery, or generation state replaces native or Vaadin-backed presentation
+- **THEN** the current immutable composed tooltip is applied exactly once
+- **AND** stale descriptions or disabled reasons cannot reappear
+
+### Requirement: Positioned Font Awesome service-action icons
+Native and Vaadin-backed application-menu action items SHALL preserve accepted static Font Awesome classes and canonical left or right position from the effective menu model.
+Icons MUST remain decorative and MUST NOT change semantic action identity or label text.
+
+#### Scenario: Menu action has a left icon
+- **WHEN** the effective menu action supplies accepted icon classes and `LEFT` position
+- **THEN** native and Vaadin-backed items render the decorative icon before the text
+- **AND** toolkit projection retains only bounded immutable icon metadata
+
+#### Scenario: Menu action has a right icon
+- **WHEN** the effective menu action supplies accepted icon classes and `RIGHT` position
+- **THEN** native and Vaadin-backed items render the decorative icon after the text
+- **AND** keyboard order and activation remain unchanged
+
+#### Scenario: Menu icon hint is malformed
+- **WHEN** effective menu icon metadata contains unsupported or oversized tokens
+- **THEN** the item renders without an icon
+- **AND** bounded diagnostics disclose no action values or implementation details
diff --git a/openspec/changes/enhance-action-presentation/tasks.md b/openspec/changes/enhance-action-presentation/tasks.md
new file mode 100644
index 00000000000..3ebe0110385
--- /dev/null
+++ b/openspec/changes/enhance-action-presentation/tasks.md
@@ -0,0 +1,34 @@
+## 1. Rich Action Metadata
+
+- [ ] 1.1 Add nullable static Font Awesome class and position fields to rich member metadata with action-only side-effect-free extraction.
+- [ ] 1.2 Extend GraphQL model and integration tests and approvals for present, absent, and non-action icon metadata.
+
+## 2. Action Discovery and Shared Presentation
+
+- [ ] 2.1 Extend action discovery and preparation to select available canonical name, description, icon classes, and icon position compatibly with older schemas.
+- [ ] 2.2 Add bounded reusable action tooltip and Font Awesome token and position projection helpers with focused unit tests.
+
+## 3. Ordinary Action Controls and Prompts
+
+- [ ] 3.1 Add observed reflected `named` support and effective naming precedence to `<cw-action>` while preserving `label` compatibility.
+- [ ] 3.2 Render composed description and disabled-reason tooltips and positioned decorative icons in native and Vaadin ordinary action controls.
+- [ ] 3.3 Preserve effective action presentation through preparation and render parameterized dialog headings and quiet accessible descriptions.
+- [ ] 3.4 Extend component, interaction, widget, accessibility, focus, failure, and compatibility tests for action presentation.
+
+## 4. Application Menu Actions
+
+- [ ] 4.1 Preserve bounded Font Awesome position and canonical action description through effective-menu parsing, action state, and immutable projection.
+- [ ] 4.2 Render equivalent composed tooltips and positioned icons in native and Vaadin-backed menu items.
+- [ ] 4.3 Extend menu parsing, projection, widget, keyboard, disabled, generation, and native-fallback tests.
+
+## 5. HTMX Assets and Petclinic Demonstration
+
+- [ ] 5.1 Add the pinned Font Awesome WebJar stylesheet to the generic HTMX shell with rendering, packaging, CSP, and same-origin tests.
+- [ ] 5.2 Add representative Petclinic action names, descriptions, disabled reasons, parameters, and left and right icons while retaining unselected controls.
+- [ ] 5.3 Extend Petclinic integration and default and native Playwright journeys for buttons, menus, tooltips, prompts, icons, focus, and invocation.
+- [ ] 5.4 Update action and HTMX usage documentation with naming precedence and presentation examples.
+
+## 6. Validation
+
+- [ ] 6.1 Run focused foundation, GraphQL model and integration, HTMX, Petclinic, default and native Playwright, RAT, CSP, and packaging checks.
+- [ ] 6.2 Run strict OpenSpec validation and `git diff --check`, then review the final diff for bounded metadata and backward compatibility.