v2.1 #8

Merged
xavier merged 32 commits from dev into main 2026-08-27 17:25:18 +02:00
Owner
No description provided.
docs(specs): v2.1 SQL Runner "Add files" source picker — sql-query spec + glossary + index
All checks were successful
release / build + scan + publish (push) Successful in 1m11s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m51s
b52cb153c9
Encodes the frozen v2.1 scope (plans/v2.1.md) plus the Principal-approved rulings (2026-08-20): staged batch with explicit Add commit, discard on picker close, warn-state threshold in the running combined size. Origin-bucket confinement with cross-prefix accumulation, already-held indication, allow-then-gate cap semantics, and the two-scheme alias ruling (path-derived preferred, numeric-suffix fallback, uniform per session). Scope boundaries gain no-cross-bucket and no-folder-selection entries; six new success criteria.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
Two test-hygiene backlog items (logoutViaSessionStore retire, refocusAccessKey reset) dropped in the same sweep. v2.0.md deletion landed earlier at b52cb15; v2.0 tagged at d8a2127 which retains the file.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(specs): sql-query — alias derivation must stay engine-resolvable for pathological keys (ADR #49)
All checks were successful
release / build + scan + publish (push) Successful in 1m8s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m50s
e81dc30941
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 plan layer — 2 waves / 8 tasks, PM rulings (confirm-on-dirty-close YES pending spec amendment, autocompletion in-scope severable)
Some checks failed
release / build + scan + publish (push) Successful in 1m1s
CI / pnpm gate (typecheck, lint, build, test) (push) Has been cancelled
f312752901
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(specs): sql-query — picker dirty-close confirmation (PM ruling 2026-08-20, unblocks v2.1 T7)
All checks were successful
release / build + scan + publish (push) Successful in 1m8s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m2s
03efa96797
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 execution start — greenlight recorded, T7 unblocked (03efa96), T1 in-progress (wave 1)
All checks were successful
release / build + scan + publish (push) Successful in 1m4s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m52s
20dd24e68d
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
feat(web): aliasFromKey returns in-bucket key paths + pathological-key transforms (v2.1 T1, wave 1 — ADR #49)
Some checks failed
CI / pnpm gate (typecheck, lint, build, test) (push) Failing after 1m40s
release / build + scan + publish (push) Successful in 1m42s
932b20436b
Scheme 1 of ADR #49: every SQL source registers under its key path (uniform from entry, not collision-only), eliminating the same-basename registry-shadowing bug class by construction. Two verified-necessary transforms inline: ./-prefix for remote-scheme-looking keys (http/https/s3/file/opfs), backslash percent-encoded to %5C. Stale basename docblocks updated (types.ts wire contract, BucketPage entry seam, makeExportPath collision comment). Known-red: 2 alias pins in topbar.test.tsx are T2's inversion scope.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
test(web): wave-1 alias unit surface — path pins, transform inventory, same-basename collision regression (v2.1 T2, ADR #49)
Some checks failed
CI / pnpm gate (typecheck, lint, build, test) (push) Has been cancelled
release / build + scan + publish (push) Successful in 1m2s
213684a2da
Inverts the two known-red basename pins to path form; adds the ADR #49 §2 pure transform inventory (five scheme prefixes, uppercase non-escape, %5C encoding, composition, case preservation); the headline same-basename collision regression (two prefixes -> two distinct working registry entries, aliases derived through the real aliasFromKey seam so a revert fails directly); nested-fixture path-form default-query cases incl. quote-in-path doubling. Suite: 2735 tests green.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 T1 done (932b204) + T2 done (213684a) — wave-1 alias scheme green at unit level; T3 E2E in flight
All checks were successful
release / build + scan + publish (push) Successful in 1m18s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m52s
a5dbfe5316
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
test(web): wave-1 E2E — nested-key entry via both entry points, path-form default query executes green (v2.1 T3, ADR #49)
All checks were successful
release / build + scan + publish (push) Successful in 1m14s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m30s
2c91c73183
New serial block on the compose.e2e.yaml MinIO stack: seeds reports/2026/q1.csv, enters the Runner via action-bar and TopBar SQL from the nested prefix, pins SELECT * FROM 'reports/2026/q1.csv' (with a negative basename pin) and a green execute against the real duckdb-wasm engine (results table + row/col summary, scoped past the Inspector rail's tables). Same-basename-two-prefixes E2E deferred to T8 (unreachable pre-picker). 14 passed / 0 failed across three runs incl. CI=true.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 wave 1 closed — T3 re-verified green (14/14 e2e), battery 6/6 (2735 tests serialized); next T4
All checks were successful
release / build + scan + publish (push) Successful in 1m36s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m48s
5e015da3af
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
feat(web): add SQL Runner source picker (Add files) — modal browse/stage/commit per ADR #50
All checks were successful
release / build + scan + publish (push) Successful in 1m29s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m53s
a2c7587560
v2.1 T4 — the version's centerpiece: the source set can grow without
leaving the workbench (leaving would rewrite the default query and
re-fetch all sources on return).

- SourcePicker modal (DownloadDialog pattern: overlay + scrim +
  role=dialog + useDialogFocus trap/Escape/restore), hosted from the
  SourceChips row via a '+ Add files' trigger shown whenever the panel
  holds an origin bucket; SourceChips' MVP no-picker gate docblock
  rewritten to the open state.
- Browsing reuses the list-view data layer wholesale: local prefix +
  loadedPages state against the FIXED origin bucket (usePaginatedList
  mounting the useS3List ladder), client-side isQueryableExt filter,
  prefix rows navigate (visually distinct, NOT selectable — the
  selectable-folders backlog stays unprecluded), Load-more per the
  list-view semantics, in-dialog breadcrumbs, virtualized rows.
- Staging is picker-LOCAL (Map<key,{key,size}>), accumulates across
  prefixes, dies with the dialog — never the shared selection store.
- Held rows (same bucket+key as a held source) render indicated
  ('already added') and cannot be staged.
- Running combined-size indicator (held + pending, declared LIST
  sizes) with ok/warn/over tiers against SQL_QUERY_WARN_SIZE /
  SQL_QUERY_LIMIT_SIZE — shape-coded (no-glyph/⚠/✕), informational
  only, enforcement stays at load; no pre-flight gate.
- Commit = setSources([...held, ...picked]) (no origin argument) PLUS
  a direct loadSources(getCredentials()) from the commit handler —
  closes the post-L2-cancel gap (ADR #50 §5); picker never calls
  setSqlText; close-on-commit. Every close path funnels through the
  single closePicker(reason) seam (T7 slots its confirm-on-dirty-close
  guard there; T4 closes silently per the spec baseline).
- i18n (ADR #41): 24 sql.picker.* descriptors in sql/messages.ts,
  en-US extract + fr-FR translation in the same change; the catalog
  size tripwire (494→518) and the i7 placeholder allowlist (bucket/
  location/name/warn — trusted UI state) updated alongside.

Visual loop (compose.e2e stack + on-prem vision review, light+dark,
1440x900/780x493/375x667): verified browse/stage-across-prefixes/
held/load-more/empty/warn/over/commit/discard/editor-untouched, fixed
a short-viewport footer clip (list region now yields to a min-height
floor) and strengthened the warn/over banner tints (10%→20%).

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 T4 done — SourcePicker landed at a2c7587, review-approved (should-fix carried to T7)
All checks were successful
release / build + scan + publish (push) Successful in 1m16s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m56s
b32e440d4e
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
fix(web): picker confirm-on-dirty-close per spec + nav landmark (T4 review should-fix)
Some checks failed
CI / pnpm gate (typecheck, lint, build, test) (push) Failing after 1m36s
release / build + scan + publish (push) Successful in 1m47s
aa7ade3d26
v2.1 T7 — the SourcePicker close seam now guards dirty closes: a
discard-intent close with a non-empty staged batch arms an in-footer
role=alertdialog discard/stay confirmation (SqlToolbar warn-gate
idiom) instead of closing; confirm discards AND closes, Stay (or any
repeated close intent while armed — second-Escape-cancels) returns to
the picker with staging intact. Clean batch and post-commit closes
stay silent (sql-query.md §"The source picker"). The breadcrumb row
becomes a nav landmark (aria-label exposed; Breadcrumbs.tsx idiom),
and fr-FR stageAria verb becomes "Préparer {name}" to stop colliding
with the commit button "Ajouter" for FR screen-reader users.

Catalogs: +3 sql.picker.confirm* keys, en-US extract + fr-FR in the
same change; tripwire pin 518 → 521.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
fix(web): stable picker close handlers — latest-value refs, no useDialogFocus re-run per stage toggle (T7 review must-fix)
All checks were successful
release / build + scan + publish (push) Successful in 1m54s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m13s
763c618ecc
T7 review must-fix: closePicker closed over the staged Map (fresh identity
per toggle) and closeDiscard over closePicker + confirmVisible, so both
re-identified on every stage/unstage and arm/disarm. closeDiscard is
useDialogFocus's onClose — the churn re-ran the hook's effect per toggle
(cleanup focusing the opener behind the scrim, setup re-focusing the
container), yanking focus off the activated row and clobbering the confirm
row's Stay autoFocus, and broke the host's stable-close invariant
(SourceChips.tsx).

Fix: stagedSizeRef + confirmVisibleRef synced by ref-sync effects (the
allowed form — only set-state-in-effect is banned); closePicker reads the
ref guard with deps back to [onClose] (the T4 shape); closeDiscard reads
confirmVisibleRef with all-stable deps. stayInPicker was already stable.
Rendering keeps the confirmVisible state; guard semantics unchanged.

Verified against the compose.e2e.yaml stack (real MinIO + proxy + built
bundle) in-browser: focus stays on the row across stage/unstage; arming
lands and keeps focus on Stay; the useDialogFocus keydown listener counts
exactly 1 add / 1 remove for a full open→stage→arm→stay→discard session;
second-Escape-while-armed = Stay; empty-batch close silent; commit closes
directly (confirm never mounts); unstage-to-empty self-clears the confirm;
focus restores to the opener on close.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 T7 done — confirm-on-dirty-close at aa7ade3, must-fix 763c618, review-approved
All checks were successful
release / build + scan + publish (push) Successful in 1m7s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m1s
9594976cbb
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
test(web): picker + registry unit suites — guard matrix, focus regression, double-load, oversize-at-load (T5)
All checks were successful
release / build + scan + publish (push) Successful in 1m6s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m2s
f455228f6f
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
test(web): oversize continuation pinned single-loop (T5 review must-fix) + LIST-error states + nits
All checks were successful
release / build + scan + publish (push) Successful in 1m7s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m51s
f5182d945e
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 T5 done — unit suites at f455228, must-fix f5182d9, review-approved; backlog: pagination error-retry gap
All checks were successful
release / build + scan + publish (push) Successful in 1m4s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m51s
3574ce338a
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
feat(web): held-alias autocompletion in the SQL editor — quoted-literal apply, live store read (ADR #49 §3)
All checks were successful
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m17s
release / build + scan + publish (push) Successful in 2m45s
4a6f6352ad
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
fix(web): completion apply dispatch parity — scrollIntoView + input.complete userEvent (T6 review should-fixes)
Some checks failed
CI / pnpm gate (typecheck, lint, build, test) (push) Has been cancelled
release / build + scan + publish (push) Successful in 1m25s
9f3608ef3e
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 T6 done — autocompletion at 4a6f635 + 9f3608e, review-approved
All checks were successful
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m43s
release / build + scan + publish (push) Successful in 1m0s
67be5dd1fa
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
test(web): picker E2E — commit-survives, cross-prefix same-basename, held, discard+confirm, focus; autocompletion case (T8)
All checks were successful
release / build + scan + publish (push) Successful in 52s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m43s
8e1aa27bf7
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 wave 2 closed — T8 done at 8e1aa27, battery 8/8 green (2823 tests, independent e2e 19/19); execution complete, ship-ready
All checks were successful
release / build + scan + publish (push) Successful in 55s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m38s
8cc8f3b1b1
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
T9: editor/results splitter computed height = startHeight - dy with the editor pane ABOVE the handle, so the divider fled the cursor both ways (inverted since v1.1). Drag math is now startHeight + dy (divider tracks the cursor; drag down grows the editor) and the keyboard map moves the separator (ArrowUp/PageUp shrink -16/-64, ArrowDown/PageDown grow +16/+64, Home/End = bounds). 19-test direction-pinning suite (none existed before).

T10: the source-chips strip was auto-height unbounded (30 files ~400px of a 900px viewport). New persisted-ceiling store (44/192/480 px, default 192, key vedrfolnir.preferences.sqlChipsMaxHeight) + ChipsSplitter between chips and editor; wrapper gets inline maxHeight + overflow-y-auto (compact under the ceiling, internal scroll above).

Both handles now share a parameterized SplitterHandle core; InspectorSplitter untouched. New aria string sql.splitter.resizeChipsAria in en-US + fr-FR.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 wave 3 closed — T9/T10 review-approved, battery green (2887 tests, e2e 19/19); ship-ready
All checks were successful
release / build + scan + publish (push) Successful in 1m23s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m42s
8c9cd1aa63
Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
fix(web): SQL Runner chips splitter drag dead zone — anchor gestures on rendered height (v2.1 wave 4, T11)
All checks were successful
release / build + scan + publish (push) Successful in 2m38s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m46s
f232e1677a
The chips/editor divider wrote the persisted max-height ceiling, but the
wrapper renders at min(content, ceiling) — so with the strip under the
ceiling nearly the whole drag range moved nothing on screen. Pointer drags
and keyboard steps now compute from min(storedCeiling, renderedHeight) via
an optional readAnchor seam on SplitterHandle (absent prop = byte-identical
math; SqlSplitter/InspectorSplitter untouched and pinned). Store bounds,
persistence, aria, and the compact resting layout are unchanged.

Full dev → tester → reviewer cycle per docs/plans/v2.1.md T11: 2907/2907
workspace tests, battery 5/5, reviewer approved.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): v2.1 wave-4 closed — close-out battery 7/7 green; COMPONENTS.md refresh brief staged
All checks were successful
release / build + scan + publish (push) Successful in 50s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 2m33s
62dfd7a6fe
Independent battery at f232e16: build, serialized workspace tests 2907/2907,
typecheck, lint, duckdb-pin, locale-catalogs, and the sql-runner E2E re-run
19/19 with zero retries on a freshly built, force-recreated stack. Ledger
records wave 4 closed; the backlog's COMPONENTS.md item now carries the
verified gap-list brief for the architect's pre-ship refresh.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(architecture): SQL Runner living docs catch-up for v2.1 (picker, splitters, split pref stores)
All checks were successful
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m40s
release / build + scan + publish (push) Successful in 57s
CI / pnpm gate (typecheck, lint, build, test) (pull_request) Successful in 2m26s
02c2307990
COMPONENTS.md: the UI inventory now covers the source-picker family
(ADR #50 — SourcePicker/Row/SizeIndicator + the pure staging model), the
SplitterHandle shared core with the T11 readAnchor seam, ChipsSplitter, the
T10 ceiling-capped chips wrapper, sql-export.ts, and both SQL layout
preference stores; Dependencies gains @codemirror/autocomplete 6.20.3; new
Key note records the two splitter semantics (fixed height vs persisted
ceiling + anchor-on-rendered gestures, T9-T11); SourceChips one-liner
catches up to ADR #41/#49/#50. Header now cites #49/#50.

ARCHITECTURE.md: the SQL Runner row's 'per-query register/drop' was stale
twice over (superseded by ADR #33's panel-scoped registry) — corrected, and
the row gains the v2.1 clause (aliases/autocompletion #49, picker #50,
resizable panes T9-T11).

Closes the backlog brief 'COMPONENTS.md sql-runner inventory stale' (PM to
drop the item).

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(plans): close out v2.1 — delete the shipped execution file, drop the done COMPONENTS.md backlog item
All checks were successful
release / build + scan + publish (push) Successful in 56s
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m43s
CI / pnpm gate (typecheck, lint, build, test) (pull_request) Successful in 2m23s
6944721f64
Per the docs/plans convention the execution file is deleted when the
release ships (git at the v2.1 tag is the permanent record); the
COMPONENTS.md inventory refresh landed in 02c2307 and shipped in v2.1,
so its backlog item is dropped per its own completion note.

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
docs(agents): plan-file deletion convention — after the tag, never in it
All checks were successful
CI / pnpm gate (typecheck, lint, build, test) (push) Successful in 1m39s
CI / pnpm gate (typecheck, lint, build, test) (pull_request) Successful in 1m41s
release / build + scan + publish (push) Successful in 51s
4212b05e6d
Principal ruling (2026-08-27): the vX.Y.md execution file must still
exist at the tag vX.Y so 'git checkout vX.Y' shows what was planned;
the deletion is the immediate post-tag commit. Codified in AGENTS.md.
The v2.1 close-out already followed this shape (tag at 02c2307 with
the file; deletion in 6944721).

Co-Authored-By: Xavier's assistant <assistant@gijoe88.com>
xavier merged commit 4212b05e6d into main 2026-08-27 17:25:18 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
xavier/s3-vedrfolnir!8
No description provided.