- Show the spot price as a <1× multiplier of on-demand (e.g. 0.42×) with a
'spot vs on-dmd' label, colored by how much you're saving; node spot tags
show the effective $/hr and savings %.
- Node-pool dropdown shows realistic specs and prices (spot priced ~0.45×).
- Make the node and queue panels flex columns whose lists scroll
internally, so a large cluster no longer overflows its row and covers the
event log.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- Replace the generic node pools with realistic AWS EC2 families and their
us-east-1 on-demand prices: c5.xlarge/c5.2xlarge (general), c5d.2xlarge
(local-NVMe SSD), r5.2xlarge (memory), g4dn.xlarge (1× T4 GPU), plus c5
spot variants. Pod requests were already realistic and are unchanged.
- Spot price is now the live fraction of on-demand (mean-reverting ~0.45,
clamped <1 since AWS never bills spot above on-demand); spot nodes bill at
cost×spotPrice and a hotter market means more interruptions.
- GPU nodes are now single-GPU (g4dn.xlarge), so the autoscaler provisions
one GPU node per pending GPU pod instead of de-duping to one per burst.
- Name nodes with a random k8s-style suffix (node-xugjs) while keeping a
stable internal id.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- README covers DaemonSets, spot nodes/pricing/reclaims, and cluster
upgrades, plus the updated scoring and KPIs.
- Headless smoke test builds a richer scene (spot node + in-progress
upgrade) and asserts daemonset pods/chips render; new screenshot shows
it all.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- New KPI tiles for live spot price and cluster version (with count of
nodes left to upgrade).
- Node cards show their version (amber when out of date), a spot $/hr tag
at the live price, a spot 'Reclaiming' countdown, distinct dashed
DaemonSet chips, and an Upgrade button on outdated nodes.
- Daemonset overhead is drawn at the base of each resource meter.
- Badges/styles for Upgrading and Reclaiming states; a toast announces
control-plane upgrade events.
- Help modal documents the new mechanics.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- DaemonSets: infra pods the controller reconciles onto every matching
node (gpu plugin only on GPU nodes); counted as per-node overhead, kept
on drain like kubectl, and recreated when a node joins or finishes an
upgrade.
- Spot nodes: a fluctuating spot price (mean-reverting random walk with
occasional spikes) drives both billing and an unexpected-reclaim risk;
reclaimed nodes give a short drain window before evicting their pods.
- Cluster upgrades: nodes carry a version, periodic upgrade events bump
the target, and upgradeNode() drains + reboots a node onto the new
version. Outdated nodes leak score while pending; a full rollout pays a
bonus.
- Autopilot now recovers from spot reclaims and performs a safe one-at-a
-time rolling upgrade.
- Tests cover daemonset reconciliation/overhead, spot reclaim + price
bounds, upgrade drain/reboot, rollout bonus, and auto rolling upgrade.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- server.js: zero-dependency static file server (Node built-ins only) with
correct ES-module MIME types, path-traversal guard, and auto port fallback.
- package.json: type=module, start/serve/test/smoke scripts, no dependencies.
- README: how to run/play, the scheduling constraints, scoring formula,
scenarios, project layout, and testing.
- tools/browser-smoke.mjs: optional end-to-end check that drives the real UI in
headless Chrome over the DevTools Protocol (Node global fetch/WebSocket, no
npm deps); verifies zero console errors, click-to-schedule, and screenshots.
- docs/screenshot.png: gameplay screenshot for the README.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
Dark control-plane dashboard rendered with vanilla DOM (no framework):
- Node grid cards with status badges, label/taint chips, segmented CPU/Mem
bin-packing bars colored per pod, GPU counters, and cordon/drain/delete actions.
- Pending-pod queue with per-pod constraint pills, wait timers, and a one-click
auto-place (best-fit) button.
- Click-to-select a pod to highlight feasible nodes green and dim infeasible ones
with the blocking reason; click or drag-and-drop onto a node to bind it.
- KPI bar (score, utilization, latency, pending/running, nodes, cost, SLA),
scenario/speed/pause controls, auto-schedule + autoscaler toggles, event log,
toasts, and a how-to-play modal.
- main.js drives a sim loop (setTimeout, speed-scaled) and a dirty-flag rAF
render loop that never repaints mid-drag.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
When CI is pending, the reconciler now returns RequeueAfterSeconds: 60
to poll for CI completion every minute, instead of relying on check_run
events which are difficult to route through the workqueue.
- Remove check-run-workqueue from trigger.tf
- Remove processCheckRunEvent and related parsing code
- Add requeue when CIFixPending is true
- Update agent.md to remove check_run event documentation
The github-events trampoline sets event.SetSubject(repoFullName) which
becomes ce-subject attribute, but does NOT set a 'repo' extension.
- Change extension_key from 'repo' to 'subject' for check-run-workqueue
- Rename parseRepoURL to parseRepoKey to handle both URL and subject formats
- Add tests for subject format (owner/repo)
This allows check_run completion events to flow through the workqueue
and trigger CI fixer reconciliation.
When a push event triggers reconciliation, the GitHub workflow may not
have started yet, resulting in 0 checks. Previously this was treated
as 'all checks passing'. Now we treat it as pending and wait for checks
to start.
- Show 'Waiting for CI to complete' when pending instead of success
- Distinguish 'CI passing after fix' from 'CI is passing' (no fix needed)
- Show turns attempted for all states
- Clearer messaging overall
The github-events module doesn't set pullrequesturl for check_run events,
so they don't trigger the PR workqueue. This adds a separate workqueue that
listens for check_run completion events keyed by repo URL.
When a check_run event is received, the reconciler:
1. Lists open PRs with the ci-autofix label
2. Processes each one to re-evaluate CI status
Also keeps check run status as in_progress while waiting for CI.