Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
afa9675
chore(fds): bump the design system pin to da333e7 and regenerate the …
sandyghs Aug 21, 2026
337f757
feat(fds): adopt the library Combobox in the country, person and tena…
sandyghs Aug 22, 2026
1aa8f37
feat(fds): adopt the library Combobox in the scenario filters, the re…
sandyghs Aug 22, 2026
d77a051
feat(fds): adopt the library Combobox in the agent, document, tag and…
sandyghs Aug 22, 2026
69cc9cd
feat(fds): adopt the library Combobox in the three dashboard widget p…
sandyghs Aug 22, 2026
1d54426
feat(fds): adopt the library Combobox in the tags and channels filters
sandyghs Aug 22, 2026
d1d1ec0
feat(fds): adopt the library Combobox in the notifier and composed-tr…
sandyghs Aug 22, 2026
e2ee4db
feat(fds): adopt the library Combobox in the inject contract field
sandyghs Aug 22, 2026
f6c3664
feat(fds): adopt the library Combobox for the attack-path simulation …
sandyghs Aug 22, 2026
10ed09d
feat(fds): adopt the library Combobox in the two inject import uploaders
sandyghs Aug 22, 2026
bb21c96
docs(fds): log the Combobox wave and file the three library gaps it m…
sandyghs Aug 22, 2026
ae67eef
fix(fds): stop introducing untranslated i18n keys in the Combobox wave
sandyghs Aug 22, 2026
01bbee2
docs(fds): drop the bridge-freshness friction, already being fixed up…
sandyghs Aug 23, 2026
ce766b4
chore(fds): re-pin to 114854d — the field, container and chip-row res…
sandyghs Aug 23, 2026
a4fa936
chore(fds): re-pin to f8d3781 and raise the overlay layer to 1400
sandyghs Aug 24, 2026
9c838ad
feat(fds): adopt the library Combobox in the generic filter field
sandyghs Aug 24, 2026
6ad1d5b
feat(fds): adopt the library Combobox on the free-value family
sandyghs Aug 24, 2026
4258e98
feat(fds): adopt the library Combobox in the reporting field
sandyghs Aug 24, 2026
a342c83
fix(fds): drop the MUI imports the reporting field no longer uses
sandyghs Aug 24, 2026
3ade970
feat(front): adopt the Combobox on the last 13 sites, re-pinned on #155
sandyghs Aug 25, 2026
240bccf
fix(fds): name each create ornament for what it creates, reuse existi…
sandyghs Aug 25, 2026
76e60c6
test(e2e): match the arsenal submit button exactly
sandyghs Aug 25, 2026
4860899
test(e2e): read a field error from either the MUI or the library shape
sandyghs Aug 25, 2026
91e67f9
feat(front): move the name to the placeholder on the four chip-feedin…
sandyghs Aug 25, 2026
4a0608a
feat(front): convert the three form Select wrappers to the library
sandyghs Aug 25, 2026
f1b55e1
feat(front): convert the 22 regular MUI Select sites to the library
sandyghs Aug 25, 2026
cc744f0
feat(front): convert the widget-configuration and platform Select fields
sandyghs Aug 25, 2026
9abfe1b
feat(front): convert the filter operator selects to the library
sandyghs Aug 25, 2026
3afc2c0
feat(front): convert the asset, platform and execution-limit selects
sandyghs Aug 25, 2026
710a08d
feat(front): convert the three selects whose trigger read differently…
sandyghs Aug 25, 2026
dc40409
feat(front): convert the bulk-action and timezone selects
sandyghs Aug 25, 2026
cba5a06
feat(front): convert the chaining condition and inject-dependency sel…
sandyghs Aug 25, 2026
3f69f91
feat(front): convert the last four expectation selects, three of them…
sandyghs Aug 25, 2026
5f92a59
fix(front): visit findings — filter gap, statistics row, filter reset…
sandyghs Aug 25, 2026
16975ee
fix(front): keep the time-range Select's label above its trigger
sandyghs Aug 25, 2026
70a1dfd
test(e2e): a required field's accessible name no longer carries the a…
sandyghs Aug 25, 2026
89d5094
test(e2e): narrow the required arsenal fields by aria-required, not b…
sandyghs Aug 25, 2026
969ec79
test(e2e): narrow only the locator that actually collided
sandyghs Aug 25, 2026
eb05b30
test(e2e): keep the asterisk where the accessible name really carries it
sandyghs Aug 25, 2026
e3d0f7d
test(e2e): read a Select's helper text as a sibling, not from a wrapper
sandyghs Aug 25, 2026
22f3f42
test(e2e): match a Select's helper text without an id suffix
sandyghs Aug 25, 2026
6a59063
fix(front): review findings — one axis on the filter rows, field widt…
sandyghs Aug 26, 2026
bb8d73b
fix(front): render the design popover node in both modes — separation…
sandyghs Aug 26, 2026
629802a
fix(front): orphan MUI labels, chip row alignment, and move the creat…
sandyghs Aug 26, 2026
fd14030
fix(front): stack the list toolbar into three rows
sandyghs Aug 26, 2026
7e41e94
test(e2e): open the filter field by its trigger, not by its input
sandyghs Aug 26, 2026
0738859
test(e2e): anchor the clear-filters button instead of naming it
sandyghs Aug 27, 2026
f726590
test(e2e): dismiss the filter popover before touching the toolbar
sandyghs Aug 27, 2026
bf1e01b
fix(front): toolbar row height, sort label centring, chips row spacing
sandyghs Aug 27, 2026
8e26a7e
fix(front): bring the list toolbar top row down to 36px
sandyghs Aug 27, 2026
19a2f0e
feat(front): put the list toolbar on one line above 1600px
sandyghs Aug 27, 2026
e98205d
test(e2e): read the toolbar break point from the arrangement, not the…
sandyghs Aug 27, 2026
ed84ff3
docs(fds): log the Select wave and the toolbar break point
sandyghs Aug 27, 2026
deaed0d
docs(fds): file the Select/Tab gap as a pointer to the OpenCTI measur…
sandyghs Aug 27, 2026
c69ffd1
fix(front): honour fullWidth on the three Select form wrappers
sandyghs Aug 27, 2026
31ff7a5
fix(front): restore the declared full width on 26 converted Select sites
sandyghs Aug 27, 2026
85d41af
fix(front): stop paying the 48px option row where the row is not custom
sandyghs Aug 27, 2026
80d3969
Revert "fix(front): stop paying the 48px option row where the row is …
sandyghs Aug 27, 2026
8362d48
chore(fds): bump the pin to bd076e8 — the option row floors at the no…
sandyghs Aug 27, 2026
8c59da3
test(front): read Paper's own module, not the library barrel
sandyghs Aug 28, 2026
363c343
feat(front): adopt the library Radio, Checkbox and Switch on six sites
sandyghs Aug 28, 2026
6afe472
fix(front): wire the clear affordance on multi-select fields, name tw…
sandyghs Aug 28, 2026
1ceb114
feat(front): adopt the library ButtonGroup on the 11 icon-only segmen…
sandyghs Aug 28, 2026
cf74bca
test: query the segmented control by its radio role
sandyghs Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions fds-migration/IMPLEMENTATION-LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,155 @@ in filigran-design-system).
makes `bridge-freshness` meaningful; its branch ref (`sandyghs-miniature-enigma`
@ `8ab126d`) is untouched.
- Friction / process feedback: see the two points above.

### 2026-08-20 — Combobox wave: 23 sites adopt the library field
- Branch: fds/combobox-adoption
- Pin: f86e76e -> da333e7. Proven on the bytes the product serves, not on a local
rebuild: `transparency-50` gone from `dist/index.css` (was 8 occurrences),
`transparency-55` present 10 times, `--border-elevation-disabled` present,
`yarn.lock` resolution on da333e7, and the regenerated bridge records
`themeCssHash: 3c0ef256…`, which is the git hash of `theme.css` at that commit.
- The bridge was regenerated from a lib checkout DETACHED at da333e7, with its
on-disk `theme.css` hash checked against git first. Generating from a stale
sibling returns the previous values, which look perfectly plausible.
- Beyond the Combobox: the pin carries the disabled-token wave. Two tokens this
product wires into its MUI theme move value —
`--text-default-disabled` (dark #a0b4e3 -> #95969d, light #2b4f8d -> #62636a)
and `--bg-elevation-disabled` (dark #0c1527 -> #313235, light #c8d6ee ->
#cacbce). `palette.text.disabled` has 74 references in this front, so the shift
from a blue-tinted to a neutral gray ramp is product-wide. Disabled controls are
exempt from WCAG 1.4.3, so this is legibility, not conformance.
`--color-filigran-brand-primary-transparency-50` was renamed to `-55`; no
product code reads it, only the generated bridge, so the rename is inert here.
- Census, by TypeScript compiler API over 1537 files, negative controls passed in
both directions: 44 authored MUI `<Autocomplete>` sites in 39 files, plus 33
mount sites of 8 wrappers. The 15 files the earlier map missed all import
`Autocomplete as X` — a renamed import, which the previous extractor did not
resolve. Clean 2x2 split, no exception.
- Converted: 23 sites. Left on MUI: 21, each with its reason, the biggest bucket
being the missing change cause (8 sites, 15 screens — see LIBRARY-FEEDBACK 39).
- Visual validation, both modes, three screens (creation form field, filter,
multiple field with chips), measured at the DOM in this product's environment:
field background, radius, label and text colours all match
`Combobox.figma.json`; the single-row field is 37px against 36px declared, and
the chip field 63px. Both deltas are library defects, filed as 40 and 41.
- Friction / process feedback:
1. Three false results caught by controls rather than by luck. A `PUSH_EXIT=0`
that was `tail`'s status, not `git push`'s — read the state, never a
pipeline's exit code. A "the bump did not take" reading taken while yarn was
still linking, because the wrapper had backgrounded yarn inside an already
backgrounded command. And an "ArrowDown does nothing" verdict that was the
key name: `Down` is not `ArrowDown`, found by a negative control on a second
field.
2. Two bench defects that looked like product defects: a field rendering dark on
a light page (the bench bypassed `AppThemeProvider`, which sets the theme
class on `documentElement`) and system-font typography (the bench did not
import `@fontsource/*`). Both were mine. The third anomaly in the same
capture was real — see 41.
3. `mr-2` is NOT emitted in the served `dist/index.css`. A spacing utility taken
from the library would have rendered 0 with no error anywhere; product-side
spacing went through `theme.spacing()`.

### 2026-08-23 — Combobox wave: re-pin to 114854d, the three native-reset defects close
- Branch: fds/combobox-adoption
- Pin: da333e7 -> 114854d. Byte-proven on the installed package, and the first
grep was against the wrong file: the class strings live in `dist/chunk-*.mjs`,
not `dist/index.mjs`, which returned 0 for all three and looked like a bump that
had not landed. In the chunk: `border-0 m-0 p-0 box-border`, `list-none`,
`box-border`. And emitted in the SERVED stylesheet, which is the part that
decides anything: `.border-0{border-width:0}`, `.list-none{list-style-type:none}`,
`.box-border{box-sizing:border-box}`, `.m-0{margin:0}`, `.p-0{padding:0}`.
- No token moved: `theme.css` carries the SAME hash at both pins
(`3c0ef256…`), so #145's token-family work was a gate, not a value change, and
the regenerated bridge is byte-identical to the previous one. Verified by diff
rather than assumed.
- Re-measured, both modes, the same three screens: single-row field, filter and
chip field all **36px** — the declared value, down from 37/37/63. The input
reports `border-width: 0` and `padding: 0`; the chip row reports
`list-style-type: none`, `padding-inline-start: 0`, `margin-block: 0`. The grey
rectangle and the bullet are gone from the render.
- LIBRARY-FEEDBACK 40 and 41 withdrawn, kept as a stub carrying the numbers.
39 (the missing change cause, 8 sites / 15 screens) stays open.
- Friction / process feedback: `bridge-freshness` still SKIPS here. The library
fixed it in #145 (`scripts/lib/fds-conformity-bridge-freshness.test.ts`), but
this product runs its own generated copy of `check-fds-conformity.mjs`, which
has not been regenerated. The fix does not reach the product until
`pnpm generate:fds-migration --product openaev --write-to-product` runs —
deliberately out of scope for this branch, which would otherwise churn the
generated migration docs mid-review.

## 2026-08-25 — Combobox adoption closed at 41 of 44, pin `cd4b8ee` (library #155)

- Re-pinned on `cd4b8ee`. Proved on the SERVED dep chunk, not on the lockfile:
`data-combobox-adornment` ×2, `empty:hidden` ×1, `combobox-start-icon` ×1,
`onOpenChange` ×63 — and `leadingIcon` **×0**, the negative control for the
rename the library made before merging.
- 13 sites converted: the 7 on controlled `open`, the row-interaction site, the
leading-icon search, and the 4 create ornaments. Remaining: 3 `ToolBar`, settled.
- #155 answered three open questions in its own contract, so none needed a
product guess: `open={false}` with no `onOpenChange` mounts no panel at all and
leaves the keys their native meaning; `startIcon` lives on `ComboboxField`;
`adornment` is `empty:hidden`, so a permissions gate that renders nothing costs
neither width nor the shell's gap.
- `AutocompleteField`'s `renderOption` only ever tested its result for `null` — a
caller's node was discarded. It is now `hideOption`. Its `variant` prop went
with it (the library field has one style), across 5 typed callers.
- Chips-only inputs measured at the real pointer, not asserted: click → focus,
`aria-expanded` stays `false`, no `aria-controls`, **0 listbox and 0 Radix
popper**, `ArrowDown` inert, `Enter` commits a chip. The first pass showed the
input keeping its text after committing — MUI cleared it through its `reset`
cause, which the `cause === 'type'` filter drops. Fixed on all five and replayed.
- Three faults CI caught that local gates did not: three ornaments all named
"Create" (ambiguous for a screen reader, and Playwright's `getByRole(name)` is
a SUBSTRING match, so distinct names still collided — the locator became
`exact`); `No result` existed in no locale (`No results found` does); and a
required-field helper text invented here, removed rather than translated.
- Correction to the previous round's report: the two `arsenals` E2E jobs were
already red on `3314a216e`, not green as reported. They asserted
`.MuiFormHelperText-root.Mui-error` under a `MuiFormControl-root` ancestor
around a field converted in the earlier wave. `MuiFormHelpers.getFieldError`
now matches either shape. CI closed at **37/37**.
- V1 label pattern applied to the 4 chip-feeding fields: the name moves from
`ComboboxLabel` to the input's placeholder, freeing ~24px of height each. Two
measured consequences: `FilterAutocomplete`'s domains variant carries a 122-char
guidance sentence, of which **24 characters** fit its 146px input; and
`FilterChipPopoverInput`'s free-value input traded its "Press Enter to add a
value" hint for the filter's name, a placeholder holding only one of the two.
- LIBRARY-FEEDBACK 42 opened: `min-h-8` as the single option-row floor. 12 sites
render one glyph plus one line and pay 48px; no product compensation, arbitrated.

## 2026-08-27 — Select family converted, and the list toolbar given one break point

- Branch: fds/combobox-adoption
- The `Select` family was converted across the remaining product sites, over 11
commits grouped by what made each group awkward rather than by directory. Not
in the original scope: a page mixing the two families reads as two different
form languages, so the review asked for the whole field surface at once.
- Three library gaps filed from this wave: **#42** the option-row floor should be
`min-h-8`; **#43** `Select` renders no wrapper, so its label and trigger become
siblings of whatever contains them — the most serious; **#44**
`ComboboxLabel` has no `required`, so the two families expose different
accessible names.
- Visual review findings, each traced to a cause rather than compensated:
- 5 sites kept a MUI `InputLabel` after conversion. It is a floating label
(`position:absolute; transform:scale(.75)`), so it rendered at a different
size and offset from the library's. All five now use the library label.
- `TagsFilter` laid its chip row out with `float:left` and a 5px top margin,
offsetting the chips 3px from their neighbours. Now a centred flex row.
- The toolbar's top row measured 52px. Two causes, each fixed where it is set:
MUI's `TablePagination` wraps its content in a `Toolbar` with its own
`minHeight`, and its captions are `<p>` carrying the browser's 1em vertical
margins; separately the select-all `Checkbox` carries its own padding. Row
now 36px, click targets 36x36 and 32x32 — above the 24x24 minimum.
- The list toolbar (62 pages) now has one fixed break point at 1600px: stacked
below, one line at or above, chips on their own line either way. **Five
adaptive attempts were built and discarded first**, each failing the same way —
a measurement whose result depended on the layout it produced. The friction
worth carrying forward: a layout decision taken from a measurement of that same
layout has no fixed point. A media query has nothing to measure.
- Above the break point the container wraps rather than overflowing. Measured in
CI: the card view carries the sort select the list view does not, so at 1600px
it wraps to two rows while the list view sits on one. No overflow either way.
An E2E assertion that read the line count instead of the arrangement failed on
exactly this and was corrected, not the layout.
- Friction / process feedback: none upstream.
162 changes: 162 additions & 0 deletions fds-migration/LIBRARY-FEEDBACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -2053,3 +2053,165 @@ recorded here only so the two are not confused when the padding work is scoped.
**Not urgent, but it caps the wave.** Seventeen surfaces out of the 130 in the
OpenAEV container perimeter — 13%, and they are the only ones with no path
forward. Everything else either converts or is out of scope by design.

---

Raised during: the Combobox adoption wave, library pin
`da333e701d3073568159eabed00716c8e222a621`. Geometry and colour measured at the
DOM in this product's own environment — real `ThemeLight()`/`ThemeDark()`, real
`static/css/design-system-host.css`, `@fontsource/ibm-plex-sans` and
`@fontsource/geologica` loaded as `src/index.tsx` loads them, and the theme class
on `documentElement` as `AppThemeProvider` sets it. Three screens, both modes.

## 39. `Combobox` needs a CAUSE on every one of its callbacks — and one product site expresses that cause as an event's PRESENCE

**This is the wave's first blocker: 8 sites, 15 screens.** More than free value,
more than the size axis.

Six sites read MUI's change `reason`, across three different callbacks, and a
seventh guards on something the library also does not provide:

| callback | sites | what they read |
|---|---|---|
| `onInputChange` | `ReportingAutocompleteField.tsx:52`, `FilterAutocomplete.tsx:59`, `FilterChipPopoverInput.tsx:153`, `AutocompleteField.tsx:146` | `'input'` ×2, `'reset'` ×2 |
| `onClose` | `ScenarioField.tsx:137` | `'selectOption'` |
| `onChange` | `TagsFilter.jsx`, `ChannelsFilter.tsx` | `'clear'` — **converted**, see below |

**The two `onChange` sites did not need the library to change.** In single mode a
cleared field is exactly a null value; in multiple mode both handlers at the only
call site reduce to the same state update. Both mappings were verified by reading
the call sites, and both shipped. They are listed so the next reader does not
re-open them.

**The four `onInputChange` sites cannot be mapped, and they fail in opposite
directions.** The library calls `onInputChange` from `setInputValue`, which
`toggle()` and `clearAll()` also call, so a programmatic reset is
indistinguishable from a keystroke. The two reading `'input'` drive a server
search, so they would fire a query on every selection and every clear. The two
reading `'reset'` ignore resets precisely to protect the text the user typed,
which would now be overwritten.

**The fourth form, and the reason this entry exists as written.** `ToolBar.tsx`
(3 sites) never mentions `reason`. It writes:

```js
handleSearch(i, event, newValue) {
if (!event) return; // MUI passes null on a programmatic reset
}
```

That `if (!event) return` **is** `if (reason === 'input')`, expressed through the
presence of the event object rather than a cause string. A fix that only adds a
`reason` string to `onInputChange` would still leave these three sites
unconvertible, because what they need is the same distinction under another name.
A grep for `reason` does not find them — this one was found by opening the file.

**Ask.** Give every callback that can fire from more than one cause a stated
cause, with a named vocabulary, and cover the keystroke-vs-programmatic
distinction explicitly rather than only the close-vs-select one. MUI's own set
(`input`, `reset`, `clear`, `selectOption`, `removeOption`, `escape`, `blur`,
`toggleInput`) is what this product already codes against.

**Not worked around.** A local guard — "ignore an input change whose value equals
the selected option's label" — would be exactly the local workaround the
migration contract forbids. The 8 sites are left on MUI, listed, with the reason
stated at each.

## 40 & 41 — withdrawn, fixed upstream before this branch merged

Two defects raised on pin `da333e7` and closed on pin `114854d` by library #145,
which added `box-border` to the field shell, `m-0 list-none p-0` to the chip row
and `border-0 m-0 p-0 box-border` to the input, and locked all three with
`scripts/lib/form-control-ua-reset.test.ts`:

- the chip row's bare `<ul>` kept the browser's `list-style: disc`, 40px
`padding-inline-start` and 14.4px `margin-block`, costing a visible bullet and
**26px of height** on every multiple field;
- the bare `<input>` kept the browser's `border: 2px inset` and `1px` padding, so
the field sat **1px** over spec and painted a grey rectangle inside itself.

Re-measured at the new pin, in this product's environment, both modes: the
single-row field, the filter and the chip field all render **36px**, the declared
value; the input reports `border-width: 0` and `padding: 0`; the chip row reports
`list-style-type: none`, `padding-inline-start: 0` and `margin-block: 0`. Kept as
a stub rather than deleted so the numbers survive for whoever meets the same
no-preflight interaction on the next component.

## 42. The option row's floor read the wrong signal — fixed upstream

**Superseded framing.** This entry first said the product could not avoid the
48px option row without dropping its glyph. That was wrong, and the node says so.

Node 6899:15536 draws `Select Field Item` at 32px, `Multi Select Field Item` —
the row that carries a CHECKBOX — also at 32px, and the two-line `Option
Complex` at 48px. So the floor follows how many LINES a row renders; an ornament
is not a second line.

The component keyed the floor on the PRESENCE of `renderOption`, which answers a
different question: that prop is how a caller draws a row, not how tall it is.
Twenty-seven product sites — seventeen through `AutocompleteField`, ten field
wrappers drawing a flag, a platform icon, a domain glyph or a 25px image — were
therefore rendering at 48px where the node says 32px.

Fixed in filigran-design-system #176: `isOptionTwoLine?: (option: T) => boolean`
declares the two-line row instead of inferring it. Content growth was not used
as the signal — it measures 41px in a real browser, matching neither height the
node draws, which is why the floor was made explicit in the first place.

Measured on this branch after the pin bump: a plain field, a `multiple` field
with its checkbox, and an ornamented field all render `min-h-8`. No product site
draws a two-line row, so none needs to declare one.

## 43. `Select` renders no wrapper of its own, so its label and trigger separate

Measured at pin `cd4b8ee`, on the scenario statistics row.

`Combobox` wraps its parts: `<div className={cn("flex w-full flex-col", …)}>`.
`Select` does not — `SelectPrimitive.Root` emits no DOM node, so `SelectLabel`
and `SelectTrigger` become **siblings of whatever holds the Select**.

In a flex or grid parent that is not a stacked column, they are laid out as two
independent items. Measured on a `grid-template-columns: 330px 330px 330px` row:
the parameter field, the label "Plage horaire" and the trigger "3 derniers mois"
all reported `top: 342` — the label had been placed in its own grid cell, beside
the trigger instead of above it. Reported by the review as a misalignment
between the two filters, and it is exactly this.

Every product site must therefore add a wrapper element the component could have
provided. That is a silent trap: the composition looks right, typechecks, and
renders correctly in any parent that happens to be a block.

**The request.** Give `Select` the same wrapper `Combobox` already has, so the
two components compose the same way and neither depends on its parent's display.

## 44. `ComboboxLabel` has no `required`, so the two field families expose the marker differently

`SelectLabel` takes `required` and renders the asterisk as
`<span aria-hidden="true">*</span>` — deliberately out of the accessible name.
`ComboboxLabel` has no such prop, so every site fakes it with literal text
(`{label}{required ? ' *' : ''}`), which lands **inside** the accessible name.

Measured on the arsenal action form: the Select-based "Type" is named `Type`,
the Combobox-based "Expectations" is named `Expectations *`. Four E2E locators
broke on this during the sweep, in three different ways, before the asymmetry
was identified.

**The request.** Give `ComboboxLabel` the same `required` prop with the same
`aria-hidden` marker, so a required field is named the same way whichever family
it belongs to.

## 45. `Select` and `Tab` — reported from a measurement made elsewhere

**Not measured on this branch.** The defect was found by another session working
on OpenCTI and is documented in OpenCTI PR #17884; it is filed here only so the
OpenAEV side carries a pointer to it rather than rediscovering it. The
measurement, the reproduction and the analysis belong to that PR — read it there
before acting on this entry.

Recorded state on the OpenAEV side: accepted for a later pass, not worked around
in the Combobox/Select adoption wave. No product site here compensates for it.

**The request.** Whatever fix the library takes should be validated against
OpenCTI #17884's reproduction, not against a fresh OpenAEV one — there is no
OpenAEV repro to point at.
Loading
Loading