Skip to content

v0.9.3 — tier-chain reordering that sticks, and a keyboard path for it

Choose a tag to compare

@izzoa izzoa released this 26 Jul 12:29

Highlights

  • Dragging models to reorder a tier chain now lands where you dropped it. The chain is
    the fallback policy — position 0 is the primary every auto/tier-routed request hits first
    — so a reorder that silently reverted left you believing you had configured one routing
    policy while the proxy ran another. Two independent defects caused it. Drag state was keyed
    by a list index that was re-read after the reorder had already been applied, so it tracked
    the drop target rather than the row you grabbed; for an adjacent swap that became a stable
    oscillator, flipping the order back and forth at the browser's drag-event rate with the
    pointer held perfectly still, and which order survived depended on where that oscillation
    happened to be when you released. Separately, a chain write's response or a routing refresh
    arriving mid-drag repainted the whole chain from server state and threw the reorder away —
    reachable by dragging within a round-trip of any other chain edit, or simply by leaving the
    Routing page and coming back while a refresh was still in flight.
  • Reordering no longer flickers. A reorder now commits only once the pointer crosses the
    target row's midpoint, so jitter on a row boundary stops re-triggering it, and the row hover
    highlight no longer chases rows as they move under a stationary pointer.
  • The drop is properly accepted. It was resolving as a cancelled drag, which made the
    browser animate the row snapping back to where it started — reading as "it didn't take" even
    when the order had persisted. dragstart also sets drag data now, which browsers require in
    order to begin an HTML5 drag at all.
  • New: reorder a chain from the keyboard. The ⋮⋮ handle is a real button — focus it and
    press Alt+ / Alt+ to move an entry, with focus
    following the row and the new position announced to screen readers. Previously Make
    primary
    was the only keyboard route and could only reach position 0, so there was no way to
    order one fallback against another without a mouse.
  • CALIBRATION_* and EVENTS_* set in .env now reach the container. The shipped
    docker-compose.yml is an explicit environment: allow-list and neither namespace was on
    it, so all thirteen knobs silently kept their defaults — with nothing in the logs to explain
    why. Unset behaviour is unchanged.

Upgrade notes

  • No migration, no schema change, no new environment variable. The reorder work is
    frontend-only and the persisted contract is unchanged (an ordered modelIds replace,
    ≤ 5 models, position 0 = primary).
  • If you were setting any CALIBRATION_* or EVENTS_* variable in .env and quietly getting
    defaults, those values take effect on your next docker compose up. Review them before
    restarting if you had tuned around the defaults. SEMANTIC_* is deliberately unaffected —
    those belong to docker-compose.semantic.yml and the -semantic image.
  • Hardening that ships alongside: the tier writer is now identity-generation tagged, so a chain
    write or tier deletion that completes after a sign-out can no longer write into the next
    session's state or surface the previous session's error.

Full package changelogs live in packages/*/CHANGELOG.md.