← All docs changelog/2026-W22.md

Week 22 — May 26 – Jun 1, 2026

Summary

The deploy dashboard reached maturity with a full pipeline redesign, extensive performance optimization, and real-time pipeline stage tracking. The backend was overhauled for speed: GitLab API calls were parallelized and cached, Modal AppList switched from CLI subprocess to direct RPC, and /api/envs fetches all data in parallel. On the security front, two significant fixes landed: a SessionState cross-session leak in LiveKit was patched, and input validation was added across RPC, WebSocket, and Gemini streaming surfaces. Secrets were routed through Modal (Resend API key, JWT validation tightened, static site titles escaped). A codebase hygiene pass cleaned up dead imports, unused packages, and non-idiomatic boolean comparisons. The headless Claude runner (grizzlebear-claude-runner) shipped — a separate Modal app that runs /improve and /document skills on a weekly cron with safety guards (path allowlists, force-push blocks, gitleaks scanning). Bruno test infrastructure was restructured with per-request progress streaming and finer sub-folder fan-out.

44 code commits | 80+ unique files changed | ~+4,400 / -1,100 lines


Highlights

Deploy Dashboard Pipeline Redesign (May 28)

The dashboard UI was redesigned from flat cards to a connected pipeline visualization: env cards are linked by connectors showing the promotion flow (jh→dev→beta→main). Each card shows 4 recent commits with truncated subjects. In-flight connectors animate during promotions. A local mock-preview script (preview_dashboard.py) enables rapid UI iteration without a live backend.

Dashboard Performance (May 26)

Multiple rounds of backend optimization: (1) get_env_states switched from modal app list CLI subprocess to direct Modal AppList RPC; (2) GitLab API calls for branch tips and test results were parallelized via asyncio.gather; (3) a 60-second TTL cache was added to avoid hammering GitLab on rapid polls; (4) "no test" sentinels are cached to skip redundant lookups; (5) /api/envs was parallelized to fetch all data sources concurrently. On the frontend, skeleton cards render immediately while data loads, adaptive polling speeds up during in-flight actions, and action outcomes persist in toasts.

Deploy Dashboard UX Polish (May 26–27)

Action toasts now anchor above their target env card, show per-stage elapsed timers, and display live test progress (e.g., "3/12 folders passed"). Promote flows show distinct bootstrap → waiting → merging → deploying → testing phases. The deploy.sh script records deploy state so local deploys appear in the dashboard. The promote-to-dev flow was unified as an inline dispatcher matching dev→beta.

Security Fixes (May 28)

Two security patches: (1) SessionState in the LiveKit agent used a class-level dict, leaking state between sessions — fixed to per-instance; (2) input validation (type checks, length limits) was added to RPC handler arguments, WebSocket message payloads, and Gemini streaming inputs. Additionally: the Resend API key was moved from env vars to Modal Secrets, JWT validation now checks exp/iss claims, and static site page titles are HTML-escaped to prevent XSS.

Codebase Cleanup (May 28)

Removed dead imports across 12 files, dropped 2 unused packages from requirements.txt, and replaced == True/== False with idiomatic boolean checks. Closed corresponding IMPROVE.md findings.

Headless Claude Runner (May 29)

A new dev/automation/ package deploys a separate Modal app (grizzlebear-claude-runner) that runs the /improve and /document skills headless via the Claude Code CLI — isolated from the grizzlebear-api blast radius with its own image and secrets. hardening.py holds the safety guards: per-skill allowed-path enforcement (IMPROVE.md for improve, docs/ only for document), a pre-push hook blocking force/delete pushes and any push off dev, env scrubbing, and gitleaks scanning. Manual-only while in shake-out (cron commented in place). Commits land on origin/dev with reserved IMPROVE:/DOCUMENT: prefixes.

Bruno Test Fan-out (May 29)

The Bruno collections were split into sub-folders (Geocoding → address/health/image/session/tile; ML → chat/data-files/eval/gateway/generation/health; Users → _bootstrap/anonymous/invite/profile/security-probes/sharing) for finer parallel fan-out, and the runner now streams per-request progress. Supporting review-* Justfile recipes collapse multi-pipe audit commands into single allow-listable invocations for the scheduled code review.


Daily Breakdown

May 26 (13 code commits)

  • 74a5ec9 deploy-dashboard: drop confirm() popups (-19)
  • 6c900fa deploy-dashboard: instant click feedback + adaptive polling (+233/-113)
  • f8f4ee2 deploy-dashboard: faster first paint + persistent outcomes (+231/-34)
  • bafee62 deploy-dashboard: anchor toasts above target card (+111/-18)
  • 487b6b8 deploy-dashboard: parallelize /api/envs + debug timer (+80/-26)
  • a9f4819 ci/_git_in_modal: parallelize GitLab calls (+55/-46)
  • af4b7da ci/_git_in_modal: bump get_env_states to cpu=8 (+6/-2)
  • 8d577bf ci/_git_in_modal: AppList via RPC not CLI subprocess (+56/-40)
  • bbcebb5 ci/_git_in_modal: cache GitLab round-trips (+107/-12)
  • 2224358 ci/_git_in_modal: cache "no test" sentinel (+17/-2)
  • f82ba46 low_priority_app: min_containers=1 for dashboard warmth (+6/-2)
  • 100fbfe ci/webhook: self-heal on uncertain dev state (+7/-3)
  • 136ac76 deploy-dashboard: stale-artifact guard + live test progress (+180/-17)

May 27 (12 code commits)

  • a7c71e1 local deploys record deploy-state + stage toast (+44/-11)
  • 6667aa4 toast matches card width + per-stage elapsed + merge phase (+75/-21)
  • caa3405 split bootstrap phase + "waiting for CI" step (+55/-8)
  • 88a5b9e unify promote-to-dev as inline dispatcher (+144/-47)
  • 29a22c1 docs+just: no ad-hoc compound commands rule + just commits (+21/-0)
  • 9344550 serve dashboard shell no-store (+11/-2)
  • b1c3a20 always-on elapsed timer in pending toast (+33/-31)
  • 8be5249 clear destination-card chips during promotion (+29/-3)
  • 297c8ad deploy.sh: skip deploy-state in --ci mode (+5/-2)
  • 9f1ac96 ci: keep deploy + bruno workers warm (+7/-0)
  • 2c647fc ci/deploy_in_modal: slim deploy image (+16/-2)
  • 1345a94 ci: revert warm pins on deploy + bruno workers (-7)

May 28 (12 code commits)

  • 90bc03e deploy-dashboard: pipeline redesign + local mock-preview (+1,037/-284)
  • 5459ffd ci/_git_in_modal: route AppList through synchronicity loop (+43/-25)
  • 2db12a6 deploy-dashboard: 3 recent commits + DOWN label (+4/-3)
  • ae3b2f7 ci/_git_in_modal: return commits per branch from get_branch_tips (+23/-7)
  • bfb4f5b deploy-dashboard: solid in-flight connector + commits from tips (+41/-44)
  • a741bf3 deploy-dashboard: shift connector overlap (+8/-3)
  • 0dbf94f ci/_git_in_modal: return 4 commits per branch (+5/-4)
  • 971b6ca deploy-dashboard: 4 commits with truncated subjects (+14/-10)
  • 835108a security: route Resend secrets via Modal + fix JWT + escape titles (+97/-117)
  • ca76051 security: fix SessionState leak + input-validate RPC/WS/Gemini (+77/-70)
  • d13fe51 Justfile: verbose deploy option (+14/-2)
  • 6c66c41 cleanup: dead imports, unused packages, bool comparisons (+28/-117)

Headless Claude Runner (May 29)

A new dev/automation/ package: a separate Modal app that runs the /improve and /document skills headless via the Claude Code CLI. Hardened with per-skill path allowlists (IMPROVE.md-only for improve, docs/-only for document), a pre-push hook blocking force/delete pushes, env scrubbing, and gitleaks scanning. Secrets sourced from env=main to work across all developer environments. Weekly crons enabled: Mon 03:00 UTC (improve) + 04:00 UTC (document).

Bruno Test Infrastructure (May 29)

Per-request progress streaming (not just per-folder) and reorganization of the large API collections into sub-folders for finer parallel fan-out: Geocoding API (6 sub-folders), ML API (7 sub-folders), Users API (6 sub-folders). Justfile gained review-* audit recipes for the scheduled IMPROVE.md code review.

May 29 (7 code commits)

  • 15d23c4 automation: Modal-hosted headless Claude runner for /improve and /document (+597)
  • e28541b runner: source secrets from env=main (+7/-4)
  • 066dc0e runner: reuse TradeSpark + GitlabPushToken secrets, proxy GitLab (+46/-13)
  • 46666a8 runner: fix end-to-end bring-up (+45/-3)
  • 97185d7 runner: enable weekly crons (+13/-6)
  • f29c5b3 bruno tests: per-request progress + sub-folder fan-out (+267 net, 54 files reorganized)
  • 31b2632 Justfile: review-* audit recipes (+82)

Modified Files (key changes)

CI Pipeline

  • ci/_git_in_modal.py — AppList RPC, parallelized GitLab calls, TTL cache, branch commits, synchronicity loop
  • ci/webhook.py — action outcomes, self-heal, promote-to-dev dispatcher
  • ci/bruno_in_modal.py — live test progress, per-request streaming
  • ci/deploy_in_modal.py — slim image, warm pins (added then reverted)

Deploy Dashboard

  • dev/static_site/deploy_dashboard.py — parallel /api/envs, no-store headers, promote-to-dev
  • dev/static_site/templates/deploy-dashboard/index.html — pipeline redesign, connectors, toasts, commits
  • dev/static_site/preview_dashboard.pynew: local mock-preview server

Automation

  • dev/automation/claude_runner.pynew: headless Claude runner Modal app
  • dev/automation/hardening.pynew: safety guards (path allowlist, pre-push hook, gitleaks)

Security

  • dev/livekit_ts/agent/session_state.py — per-instance state (was class-level)
  • dev/livekit_ts/agent/rpc_handler.py — input validation
  • dev/websocket/websocket.py — input validation
  • dev/websocket/gemini.py — input validation
  • dev/core/notifier.py — Resend key from Modal Secret
  • dev/users/auth.py — stricter JWT validation
  • dev/static_site/endpoint.py — HTML-escape titles

Test Infrastructure

  • dev/test_app.sh — finer sub-folder fan-out
  • bruno/Grizzlebear API Collection/** — 54 .bru files reorganized into sub-folders
  • Justfile — review-* audit recipes

Cleanup

  • 12 files — dead import removal
  • dev/requirements.txt — drop unused packages

Automation

  • dev/automation/claude_runner.pynew: Modal app running /improve + /document headless
  • dev/automation/hardening.pynew: path allowlist, pre-push hook, env scrub, gitleaks
  • ci/bruno_in_modal.py — per-request progress streaming
  • dev/test_app.sh — finer Bruno fan-out
  • Justfile — review-* audit recipes