Skip to content

feat(gastown): add usage-based container billing - #4673

Merged
jrf0110 merged 10 commits into
mainfrom
gt-billing
Jul 28, 2026
Merged

feat(gastown): add usage-based container billing#4673
jrf0110 merged 10 commits into
mainfrom
gt-billing

Conversation

@jrf0110

@jrf0110 jrf0110 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

image image image
  • add the Gastown usage-billing specification and integrate the merged @kilocode/container-usage client
  • bind Gastown to container-usage-meter#ContainerUsageMeter through a typed WorkerEntrypoint service binding
  • always report container usage to the meter (start, 5-min heartbeat, stop) whenever the CONTAINER_USAGE binding is present, independent of any feature flag, so real usage can be monitored before charging
  • gate enforcement (admission blocks, low-balance stops, billing-blocked draining) behind GASTOWN_BILLING_ENABLED; add an enforcing field to billing status so the UI blocks cold starts only under enforcement while still showing the run estimate
  • report durable, retry-safe start/heartbeat/final-stop segments using gastown-standard-2026-07, with SKU-rated cost estimates read from the catalog
  • add a durable user circuit breaker (automatic-start toggle) that saves work, stops the container, and prevents automatic restarts
  • recover stale pre-integration billing state, self-heal missing remote intervals, and force-close locally after repeated meter failures
  • fix a new-town bug where a transient boot-time runtime status force-closed the just-started interval
  • enable enforcement and announcement UI automatically in development while retaining production defaults
  • polish the terminal resize handle, bottom tab alignment, and cost-explanation tooltip
  • ensure dev:start gastown always launches the meter under the shared Wrangler dev registry (with regression tests)

Feature flags

  • GASTOWN_BILLING_ENABLED — enforcement only (does not gate metering).
  • GASTOWN_BILLING_ANNOUNCEMENT_ENABLED — upcoming-billing announcement UI.
  • Metering runs whenever the CONTAINER_USAGE binding exists.

Verification

  • Manual end-to-end customer charging not performed: production enforcement is off and the merged meter returns continue for every heartbeat (no wallet admission/debit yet). Metering runs for shadow monitoring.

Reviewer notes

  • Production SKU gastown-standard-2026-07 must exist in the catalog before enabling enforcement.
  • Automated checks passing: Gastown typecheck/lint and 317 unit tests, web typecheck + targeted lint, focused meter integration tests, launcher tests, and git diff --check.

Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread services/gastown/src/dos/TownContainer.do.ts Outdated
Comment thread services/gastown/src/trpc/router.ts Outdated
Comment thread apps/web/src/components/gastown/MayorChat.tsx Outdated
Comment thread apps/web/src/components/gastown/TerminalBar.tsx
Comment thread apps/web/src/components/gastown/TerminalBar.tsx
@kilo-code-bot

kilo-code-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The only in-scope commit since the last review is a pure refactor extracting nested ternaries into two named helper functions (idleBillingState, openIntervalBillingState) in container-usage-state.billing.ts, with identical logic and no new issues; all prior findings remain resolved as reported previously.

Files Reviewed (1 file changed since last review)
  • services/gastown/src/billing/container-usage-state.billing.ts - refactor only, logic verified equivalent to prior ternary chain, no new issues
Note
  • services/container-usage-meter/package.json appears in the commit range but is identical to main (net-zero vs. the PR base) and is correctly excluded from the PR diff.
Previous Review Summaries (5 snapshots, latest commit f2892c4)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit f2892c4)

Status: No Issues Found | Recommendation: Merge

Executive Summary

All 8 previously reported issues (billing error handling in Town.do.ts/TownContainer.do.ts, error classification in router.ts, and degraded-state terminal gating in MayorChat.tsx/TerminalBar.tsx) are fixed in this commit, and no new issues were found in the changed code.

Files Reviewed (5 files changed since last review)
  • apps/web/src/components/gastown/MayorChat.tsx - previous CRITICAL (degraded state disconnecting terminal) fixed
  • apps/web/src/components/gastown/TerminalBar.tsx - previous CRITICAL/WARNING (degraded state omitted from Mayor and agent terminal gating) fixed
  • services/gastown/src/dos/Town.do.ts - previous CRITICAL/WARNING/SUGGESTION (unguarded prepareContainerBilling, getBillingStatus, destroyWithBilling, getAlarmStatus) fixed
  • services/gastown/src/dos/TownContainer.do.ts - previous CRITICAL (uncaught INSUFFICIENT_CREDITS in recordUsageHeartbeat) fixed
  • services/gastown/src/trpc/router.ts - previous WARNING (fragile string-based error classification in mapContainerBillingError) fixed

Previous review (commit dcef296)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 3
WARNING 4
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
services/gastown/src/dos/Town.do.ts 990 prepareContainerBilling throws for towns with unresolved billing owner fields, breaking unrelated config/token updates -- now reachable in strictly more environments since metering runs whenever CONTAINER_USAGE is bound, independent of enforcement
services/gastown/src/dos/TownContainer.do.ts 241 Uncaught INSUFFICIENT_CREDITS from completeBillingStart skips low-balance shutdown handling; phase stays stuck on starting
apps/web/src/components/gastown/MayorChat.tsx 82 degraded billing state still disconnects the terminal when enforcement is on, contradicting the spec's "keep running" requirement (check renamed from enabled to enforcing, same gap remains)

WARNING

File Line Issue
services/gastown/src/dos/Town.do.ts 960 getBillingStatus can throw uncaught; tRPC endpoint doesn't map the error
services/gastown/src/dos/Town.do.ts 5989 Unguarded destroyWithBilling() can block storage teardown in destroy() on a billing-settlement failure
services/gastown/src/trpc/router.ts 103 Fragile error classification in mapContainerBillingError misclassifies unrelated failures as billing errors
apps/web/src/components/gastown/TerminalBar.tsx 1431 terminalEnabled (line 1434, also affecting agent-terminal gating at line 1571) and creditPaused/automaticStopInProgress (line 1431) omit degraded, disconnecting the Mayor terminal and showing misleading paused-overlay copy during a transient billing hiccup

SUGGESTION

File Line Issue
services/gastown/src/dos/Town.do.ts 5625 getAlarmStatus has an unguarded dependency on the container DO
Files Reviewed (14 files changed since last review)
  • .specs/gastown-usage-based-billing.md
  • ENVIRONMENT.md
  • apps/web/src/components/gastown/MayorChat.tsx - 1 issue
  • apps/web/src/components/gastown/TerminalBar.tsx - 1 issue
  • apps/web/src/lib/gastown/types/router.d.ts
  • dev/local/services.test.ts
  • services/gastown/src/billing/container-usage-state.billing.test.ts
  • services/gastown/src/billing/container-usage-state.billing.ts
  • services/gastown/src/billing/container-usage.billing.test.ts
  • services/gastown/src/billing/container-usage.billing.ts
  • services/gastown/src/dos/Town.do.ts - 1 issue re-verified
  • services/gastown/src/dos/TownContainer.do.ts - fixed the enforcement-off low-balance stop, added settlement-retry/force-close handling, and narrowed runtime-stopped detection to fix the new-town force-close bug
  • services/gastown/src/trpc/schemas.ts
  • services/gastown/test/integration/billing-disabled.test.ts

Fix these issues in Kilo Cloud

Previous review (commit 6d0ad74)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 3
WARNING 4
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
services/gastown/src/dos/Town.do.ts 989 prepareContainerBilling throws for towns with unresolved billing owner fields, breaking unrelated config/token updates
services/gastown/src/dos/TownContainer.do.ts 236 Uncaught billing error (BILLING_UNAVAILABLE) skips shutdown handling; phase stays stuck on starting
apps/web/src/components/gastown/MayorChat.tsx 82 degraded billing state disconnects the terminal, contradicting the spec's "keep running" requirement

WARNING

File Line Issue
services/gastown/src/dos/Town.do.ts 959 getBillingStatus can throw uncaught; tRPC endpoint doesn't map the error
services/gastown/src/dos/Town.do.ts 5968 Unguarded destroyWithBilling() can block storage teardown in destroy() on a billing-settlement failure
services/gastown/src/trpc/router.ts 103 Fragile error classification in mapContainerBillingError misclassifies unrelated failures as billing errors
apps/web/src/components/gastown/TerminalBar.tsx 1433 terminalEnabled omits degraded, disconnecting the Mayor terminal during a transient billing hiccup (also affects agent-terminal gating at line 1564, and the paused overlay at line 1431)

SUGGESTION

File Line Issue
services/gastown/src/dos/Town.do.ts 5605 getAlarmStatus has an unguarded dependency on the container DO
Files Reviewed (33 files)
  • .kilo/skills/specs/SKILL.md
  • .specs/gastown-usage-based-billing.md
  • ENVIRONMENT.md
  • apps/web/src/app/(app)/gastown/[townId]/TownOverviewPageClient.tsx
  • apps/web/src/app/(app)/gastown/[townId]/page.tsx
  • apps/web/src/app/(app)/organizations/[id]/gastown/[townId]/page.tsx
  • apps/web/src/components/gastown/MayorChat.tsx - 1 issue
  • apps/web/src/components/gastown/TerminalBar.tsx - 3 issues
  • apps/web/src/components/gastown/useXtermPty.ts
  • apps/web/src/lib/config.server.ts
  • apps/web/src/lib/gastown/types/router.d.ts
  • dev/local/services.ts
  • pnpm-lock.yaml
  • pnpm-workspace.yaml
  • services/container-usage-meter/package.json
  • services/gastown/package.json
  • services/gastown/src/billing/ContainerBilling.error.ts
  • services/gastown/src/billing/container-usage-state.billing.test.ts
  • services/gastown/src/billing/container-usage-state.billing.ts
  • services/gastown/src/billing/container-usage.billing.test.ts
  • services/gastown/src/billing/container-usage.billing.ts
  • services/gastown/src/billing/sku-rate.billing.test.ts
  • services/gastown/src/billing/sku-rate.billing.ts
  • services/gastown/src/dos/Town.do.ts - 4 issues
  • services/gastown/src/dos/TownContainer.do.ts - 1 issue
  • services/gastown/src/dos/town/scheduling.ts
  • services/gastown/src/trpc/router.ts - 1 issue
  • services/gastown/src/trpc/schemas.ts
  • services/gastown/test/integration/billing-disabled.test.ts
  • services/gastown/tsconfig.types.json
  • services/gastown/worker-configuration.d.ts
  • services/gastown/wrangler.jsonc
  • services/gastown/wrangler.test.jsonc

Fix these issues in Kilo Cloud

Previous review (commit 4569d98)

Status: 8 Issues Found | Recommendation: Address before merge

Executive Summary

The billing state machine still leaves a container running with a stuck starting phase when completeBillingStart fails, and the degraded billing state still incorrectly disconnects Mayor/agent terminals in violation of the spec.

Overview

Severity Count
CRITICAL 3
WARNING 4
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
services/gastown/src/dos/Town.do.ts 989 prepareContainerBilling throws for towns with unresolved billing owner fields, breaking unrelated config/token updates
services/gastown/src/dos/TownContainer.do.ts 233 Uncaught billing error (BILLING_UNAVAILABLE, previously also INSUFFICIENT_CREDITS) skips shutdown handling; phase stays stuck on starting
apps/web/src/components/gastown/MayorChat.tsx 82 degraded billing state disconnects the terminal, contradicting the spec's "keep running" requirement
apps/web/src/components/gastown/TerminalBar.tsx 1403 terminalEnabled omits degraded, disconnecting the Mayor terminal during a transient billing hiccup

WARNING

File Line Issue
services/gastown/src/dos/Town.do.ts 959 getBillingStatus can throw uncaught; tRPC endpoint doesn't map the error
services/gastown/src/dos/Town.do.ts 5968 Unguarded destroyWithBilling() can block storage teardown in destroy() on a billing-settlement failure
services/gastown/src/trpc/router.ts 103 Fragile error classification in mapContainerBillingError misclassifies unrelated failures as billing errors
apps/web/src/components/gastown/TerminalBar.tsx 1534 Agent terminal enabled gating inconsistent with the Mayor terminal panes, also omits degraded
apps/web/src/components/gastown/TerminalBar.tsx 1401 creditPaused/paused overlay omits degraded, showing misleading "never started" copy during a transient billing hiccup

SUGGESTION

File Line Issue
services/gastown/src/dos/Town.do.ts 5605 getAlarmStatus has an unguarded dependency on the container DO
Files Reviewed (28 files)
  • .kilo/skills/specs/SKILL.md
  • .specs/gastown-usage-based-billing.md
  • ENVIRONMENT.md
  • apps/web/src/app/(app)/gastown/[townId]/TownOverviewPageClient.tsx
  • apps/web/src/app/(app)/gastown/[townId]/page.tsx
  • apps/web/src/app/(app)/organizations/[id]/gastown/[townId]/page.tsx
  • apps/web/src/components/gastown/MayorChat.tsx - 1 issue
  • apps/web/src/components/gastown/TerminalBar.tsx - 3 issues
  • apps/web/src/components/gastown/useXtermPty.ts
  • apps/web/src/lib/config.server.ts
  • apps/web/src/lib/gastown/types/router.d.ts
  • dev/local/services.ts
  • pnpm-lock.yaml
  • services/gastown/package.json
  • services/gastown/src/billing/ContainerBilling.error.ts
  • services/gastown/src/billing/container-usage-state.billing.test.ts
  • services/gastown/src/billing/container-usage-state.billing.ts
  • services/gastown/src/billing/container-usage.billing.test.ts
  • services/gastown/src/billing/container-usage.billing.ts
  • services/gastown/src/billing/sku-rate.billing.test.ts
  • services/gastown/src/billing/sku-rate.billing.ts
  • services/gastown/src/dos/Town.do.ts - 4 issues
  • services/gastown/src/dos/TownContainer.do.ts - 1 issue
  • services/gastown/src/dos/town/scheduling.ts
  • services/gastown/src/trpc/router.ts - 1 issue
  • services/gastown/src/trpc/schemas.ts
  • services/gastown/test/integration/billing-disabled.test.ts
  • services/gastown/tsconfig.types.json
  • services/gastown/worker-configuration.d.ts
  • services/gastown/wrangler.jsonc
  • services/gastown/wrangler.test.jsonc

Fix these issues in Kilo Cloud

Previous review (commit 1e5ae88)

Status: 8 Issues Found | Recommendation: Address before merge

Executive Summary

The billing state machine has a critical gap where insufficient-credit detection during container start can leave a container running unbilled/unstopped, and the web UI's degraded billing state incorrectly disconnects terminals in violation of the spec.

Overview

Severity Count
CRITICAL 4
WARNING 3
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
services/gastown/src/dos/Town.do.ts 968 prepareContainerBilling throws for towns with unresolved billing owner fields, breaking unrelated config/token updates
services/gastown/src/dos/TownContainer.do.ts 209 Uncaught INSUFFICIENT_CREDITS skips low-balance shutdown; phase also stays stuck on starting
apps/web/src/components/gastown/MayorChat.tsx 76 degraded billing state disconnects the terminal, contradicting the spec's "keep running" requirement
apps/web/src/components/gastown/TerminalBar.tsx 1305 terminalEnabled omits degraded, disconnecting the Mayor terminal during a transient billing hiccup

WARNING

File Line Issue
services/gastown/src/dos/Town.do.ts 956 getBillingStatus can throw uncaught; tRPC endpoint doesn't map the error
services/gastown/src/trpc/router.ts 100 Fragile error classification in mapContainerBillingError misclassifies unrelated failures as billing errors
apps/web/src/components/gastown/TerminalBar.tsx 1413 Agent terminal enabled gating inconsistent with Mayor terminal panes, also omits degraded

SUGGESTION

File Line Issue
services/gastown/src/dos/Town.do.ts 5546 getAlarmStatus now has an unguarded dependency on the container DO
Files Reviewed (25 files)
  • .kilo/skills/specs/SKILL.md
  • .specs/gastown-usage-based-billing.md
  • ENVIRONMENT.md
  • apps/web/src/app/(app)/gastown/[townId]/TownOverviewPageClient.tsx
  • apps/web/src/app/(app)/gastown/[townId]/page.tsx
  • apps/web/src/app/(app)/organizations/[id]/gastown/[townId]/page.tsx
  • apps/web/src/components/gastown/MayorChat.tsx - 1 issue
  • apps/web/src/components/gastown/TerminalBar.tsx - 2 issues
  • apps/web/src/components/gastown/useXtermPty.ts
  • apps/web/src/lib/config.server.ts
  • apps/web/src/lib/gastown/types/router.d.ts
  • services/gastown/src/billing/ContainerBilling.error.ts
  • services/gastown/src/billing/container-usage-state.billing.test.ts
  • services/gastown/src/billing/container-usage-state.billing.ts
  • services/gastown/src/billing/container-usage.billing.test.ts
  • services/gastown/src/billing/container-usage.billing.ts
  • services/gastown/src/dos/Town.do.ts - 3 issues
  • services/gastown/src/dos/TownContainer.do.ts - 1 issue
  • services/gastown/src/dos/town/scheduling.ts
  • services/gastown/src/trpc/router.ts - 1 issue
  • services/gastown/src/trpc/schemas.ts
  • services/gastown/test/integration/billing-disabled.test.ts
  • services/gastown/tsconfig.types.json
  • services/gastown/worker-configuration.d.ts
  • services/gastown/wrangler.jsonc
  • services/gastown/wrangler.test.jsonc

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-5 · Input: 28 · Output: 4.2K · Cached: 778K

Review guidance: REVIEW.md from base branch main

Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread apps/web/src/components/gastown/TerminalBar.tsx Outdated
Comment thread services/gastown/src/dos/Town.do.ts Outdated
Comment thread apps/web/src/components/gastown/MayorChat.tsx
Comment thread apps/web/src/components/gastown/TerminalBar.tsx
Comment thread services/container-usage-meter/package.json Outdated
Comment thread services/gastown/src/billing/container-usage-state.billing.ts Outdated
@jrf0110
jrf0110 merged commit b7bfcad into main Jul 28, 2026
71 checks passed
@jrf0110
jrf0110 deleted the gt-billing branch July 28, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants