* feat(queue): audit-log workspace-fairness cap transitions
When the cloud per-workspace fairness mechanism adds a workspace to the
capped set or releases one, write `workspace_fairness.capped` /
`workspace_fairness.uncapped` audit-log entries to the affected workspace.
The cluster admin can review the full timeline from the `admins` workspace
audit view with `all_workspaces=true`; per-workspace owners see their own
events in their normal audit list.
Only the per-cycle refresh winner emits entries (matching where the heavy
aggregation runs), so a fleet of N workers does not produce N duplicates
per transition. The diff is computed against the value already in
`background_task_state` rather than the winner's in-memory cache, so a
freshly-restarted process winning the claim does not spuriously emit
"newly capped" entries for workspaces that were already capped before it
started.
Audit writes are best-effort: failures are logged via tracing and do not
abort the refresh cycle.
Fixes WIN-1984
* feat(queue): scope fairness audit to admins workspace + queue-metrics pane
- Write `workspace_fairness.capped` / `workspace_fairness.uncapped` to the
`admins` workspace (was: per-affected-workspace) with the affected
workspace_id moved to the `resource` field. Cluster admins now get the
full timeline in one place without `all_workspaces=true`.
- Add `GET /workers/workspace_fairness_events` returning the last 100
events. Cloud-gated (returns `[]` on non-cloud) and devops-only.
- Add a `WorkspaceFairnessEvents` Section to the Queue Metrics drawer,
rendered only when `isCloudHosted()` is true. Shows time / event
badge / workspace / parameters with a refresh button.
Fixes WIN-1984
* Remove $$props.field usage
* Rename slots to ensure no hyphen
* _props
* _trigger
* OnSelectedIteration type correct capitalization
* rename _content
* Remove afterUpdate
* Migrate everything to svelte 5
* array bind
* Fix popover
* type never
* nit fixes
* Fixed many trivial errors
* onClick
* Fix errors
* use let:
* nit typing
* fix: wrap state_referenced_locally vars with untrack()
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add untrack import
* Fix all syntax errors due to untrack migration
* Fix undefined errors
* Fix more undefined errors
* untrack(() => initialOpen)
* svelte-ignore
* Fix state_descriptors_fixed error in Chart.svelte
Use $state.snapshot() to pass plain copies of data/options to Chart.js
instead of $state proxies. Chart.js's listenArrayEvents tries to define
property descriptors on data arrays, which Svelte 5 proxies reject.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* nit typing
* Merge issue
* Fix "path is not set" error in resource picker / editor
* Fix InputTransformForm error when rerunning some flows
* fix npm run check
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>