Commit 49aa8cc
authored
feat(gastown): replace binary is_admin gate with PostHog feature flags (#904)
* feat(gastown): replace binary is_admin gate with PostHog feature flags (#901)
Replace the binary is_admin check from #537 with PostHog feature flags
for progressive rollout. Flag management (allowlists, percentage rollout,
kill-switch) is handled entirely through the PostHog dashboard — no
custom DB tables or admin UI needed.
Gate points updated:
- 9 Next.js pages use isFeatureFlagEnabled('gastown-access', user.id)
- Sidebar uses useFeatureFlagEnabled('gastown-access')
- Token endpoint evaluates the flag and embeds gastownAccess in the JWT
- Worker checks gastownAccess JWT claim (isAdmin fallback for compat)
Sub-feature flag names defined: gastown-convoys, gastown-pr-merge,
gastown-multi-rig (to be created in PostHog when needed).
Closes #901
* fix: address PR review comments
- Switch from isFeatureFlagEnabled to isReleaseToggleEnabled for strict
boolean auth checks (prevents multivariate variants from granting access)
- Remove dev-mode bypass — gate in dev too via PostHog
- Abstract requireGastownAccess into gastownProcedure composable tRPC
middleware in init.ts, replacing manual requireGastownAccess(ctx) calls
- Remove sub-feature flags (convoys, pr_merge, multi_rig) — only
gastown-access remains
* fix: use strict boolean check for client-side gastown flag
Use useFeatureFlagVariantKey === true instead of useFeatureFlagEnabled
to align the sidebar with the server-side isReleaseToggleEnabled check.
This prevents multivariate string variants from showing the nav item
when server-side access would be denied.
* fix: use isFeatureFlagEnabled with dev override for gastown-access
Switch all gate points from isReleaseToggleEnabled back to
isFeatureFlagEnabled. Add a DEV_ENABLED_FLAGS set to
posthog-feature-flags.ts that returns true for gastown-access in
non-production environments so local dev works without PostHog
configuration. Sidebar reverts to useFeatureFlagEnabled.
* refactor: move dev override into isGastownEnabled, revert posthog-feature-flags.ts
Move the dev-mode override out of the shared posthog-feature-flags.ts
module and into isGastownEnabled in src/lib/gastown/feature-flags.ts.
All pages and the token endpoint now call isGastownEnabled(user.id)
which returns true in non-production and delegates to
isFeatureFlagEnabled in production. The sidebar uses
useFeatureFlagEnabled || isDevelopment for the same effect client-side.
* feat(gastown): witness/deacon patrol, mayor codebase browsing, and UI improvements (#442) (#924)
Alarm-driven patrol system (witness & deacon):
- Tiered GUPP violation handling (30min warn, 1h escalate+triage, 2h force-stop)
- Orphaned work detection, stale hook recovery, agent GC, crash loop detection
- Per-bead timeout enforcement with agent container termination
- On-demand LLM triage agent for ambiguous situations
- Triage action validation, access control, and snapshot-based resolution
- Stranded convoy feeding with immediate dispatch eligibility
Mayor codebase browsing:
- Browse worktrees at /workspace/rigs/<rigId>/browse/ for read-only access
- POST /repos/setup container endpoint for proactive repo cloning
- System prompt written to AGENTS.md so mayor and sub-agents share context
- Git credential race fix: refreshGitCredentials runs before configureRig
- GIT_TERMINAL_PROMPT=0 to prevent credential prompt hangs
Agent dispatch improvements:
- startPoint parameter for convoy agents to branch from feature branch
- platformIntegrationId and KILOCODE_TOKEN plumbed through repo setup
- Existing users arm watchdog on DO init
- RESTART_WITH_BACKOFF uses dispatch cooldown delay
Rig deletion fix:
- tRPC deleteRig now calls TownDO.removeRig (was missing)
- addRig handles stale name conflicts via catch-and-retry
Real-time alarm status UI:
- Hibernatable WebSocket for live alarm status push
- Status tab in terminal bar with agent/bead/patrol cards
Other UI:
- Convoy title and branch use flex-based truncation instead of fixed max-width
- Status pane card padding normalized to p-2
- Legacy agent roles accepted in Zod schemas for backward compat
- PostHog feature flag integration for gastown access gating
* fix(gastown): only stop agent on triage resolve if still hooked to snapshot bead
CLOSE_BEAD and REASSIGN_BEAD now check that the agent's current hook
matches the snapshot bead from the triage request before calling
stopAgentInContainer. If the agent has moved on to different work,
stopping it would abort unrelated sessions.
* style: fix prettier formatting in gastown type declarations
* fix: resolve lint errors (no-base-to-string, unused vars)
* fix(gastown): triage agent should call gt_done not gt_bead_close
gt_bead_close only marks the bead closed without unhooking the agent
or resetting it to idle, leaking agent records. gt_done triggers the
agentDone path which has the patrol-created triage fast-path that
properly closes the batch, unhooks, and returns the agent to idle.
* fix(gastown): refinery singleton, container eviction recovery, review queue safety
- Treat refinery as per-rig singleton in getOrCreateAgent to prevent
UNIQUE constraint on identity when a refinery already exists
- Re-queue review entry (reset to open) when refinery is busy instead
of leaving it stuck in in_progress
- Return 'not_found' (not 'unknown') from checkAgentContainerStatus on
404, so witnessPatrol immediately resets and redispatches agents after
container eviction instead of waiting for the 2-hour GUPP timeout
* fix(gastown): triage prompt, timestamp format, per-rig creds, browse refresh
- Remove remaining gt_bead_close reference in triage prompt (line 72)
that contradicted the gt_done instruction on line 49
- Use strftime with ISO format in orphanedHooks SQL query to match
the toISOString() format stored in last_activity_at
- Resolve git credentials per-rig in mayor browse setup instead of
sharing one credential set across all rigs
- Browse worktree refresh uses fetch+reset instead of checkout to
avoid wrong-branch errors (worktree is on synthetic browse branch)
* fix(gastown): escalations now create triage requests for automated follow-up
Previously, gt_escalate created an escalation bead and optionally
notified the mayor, but nothing automated acted on it. Escalation
beads sat open with no assignee indefinitely.
Now routeEscalation creates a triage request alongside the escalation
bead, feeding the escalation into the patrol→triage→resolve loop.
The triage agent can then RESTART, REASSIGN, CLOSE, or ESCALATE_TO_MAYOR
with the full context of the original escalation.
When a triage request linked to an escalation is resolved, the
escalation bead is also closed automatically.
Also adds 'escalation' to the TriageType union and enriches the
ESCALATE_TO_MAYOR mayor message with agent and bead context.
* feat(gastown): store convoy_id and source_bead_id in escalation metadata
When an agent escalates from within a convoy, the escalation bead and
its triage request now carry convoy_id and source_bead_id in their
metadata. This associates escalations with their convoy for display
purposes and lays groundwork for Phase 4 convoy-aware triage handling.
* fix(gastown): escalation metadata path, polling fallback, refinery rollback, regen types
- Fix escalation_bead_id lookup in resolveTriage to read from
metadata.context (matching createTriageRequest's structure)
- Add polling fallback to AlarmStatusPane via tRPC getAlarmStatus
query when WebSocket fails, with 5s refetch interval
- Reset refinery to idle when container start fails in processReviewQueue
- Regenerate gastown type declarations to include getAlarmStatus1 parent 179a553 commit 49aa8cc
50 files changed
Lines changed: 3069 additions & 279 deletions
File tree
- cloudflare-gastown
- container
- plugin
- src
- src
- db/tables
- dos
- town
- handlers
- middleware
- prompts
- trpc
- ui
- packages/worker-utils/src
- src
- app
- (app)
- components
- gastown
- [townId]
- agents
- beads
- mail
- merges
- observability
- rigs/[rigId]
- settings
- api/gastown/token
- components/gastown
- lib
- gastown
- types
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
174 | 174 | | |
175 | 175 | | |
176 | 176 | | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
177 | 192 | | |
178 | 193 | | |
179 | 194 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
187 | 214 | | |
188 | 215 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
210 | 210 | | |
211 | 211 | | |
212 | 212 | | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
217 | 218 | | |
218 | 219 | | |
219 | 220 | | |
220 | 221 | | |
221 | | - | |
| 222 | + | |
222 | 223 | | |
223 | 224 | | |
224 | 225 | | |
| |||
360 | 361 | | |
361 | 362 | | |
362 | 363 | | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
363 | 416 | | |
364 | 417 | | |
365 | 418 | | |
| |||
368 | 421 | | |
369 | 422 | | |
370 | 423 | | |
371 | | - | |
| 424 | + | |
| 425 | + | |
372 | 426 | | |
373 | 427 | | |
374 | 428 | | |
375 | 429 | | |
376 | 430 | | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
377 | 467 | | |
378 | 468 | | |
379 | 469 | | |
380 | 470 | | |
381 | | - | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
382 | 478 | | |
383 | 479 | | |
384 | 480 | | |
| |||
390 | 486 | | |
391 | 487 | | |
392 | 488 | | |
| 489 | + | |
| 490 | + | |
393 | 491 | | |
394 | 492 | | |
395 | 493 | | |
| |||
401 | 499 | | |
402 | 500 | | |
403 | 501 | | |
404 | | - | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
405 | 511 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| |||
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
231 | 278 | | |
232 | 279 | | |
233 | 280 | | |
| |||
0 commit comments