Conversation
| @@ -0,0 +1,2 @@ | |||
| ALTER TABLE "kiloclaw_instances" ADD COLUMN "tracked_image_tag" text;--> statement-breakpoint | |||
| CREATE INDEX "IDX_kiloclaw_instances_tracked_image_tag" ON "kiloclaw_instances" USING btree ("tracked_image_tag") WHERE "kiloclaw_instances"."destroyed_at" is null; No newline at end of file | |||
There was a problem hiding this comment.
WARNING: Build this index concurrently
kiloclaw_instances is already populated, and a plain CREATE INDEX takes a write-blocking lock until the index build finishes. Use a concurrent index build (or another safe migration path) so instance lifecycle writes are not blocked during deployment.
There was a problem hiding this comment.
Based on my tests, index creation took less than 1 second. Only 1 table is locked. Requests are queued. I feel like this is not a huge concern.
There was a problem hiding this comment.
also relatively speaking a pretty small table. we'll have less than 75k record in it.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (9 files)
Fix these issues in Kilo Cloud Reviewed by gpt-5.5-2026-04-23 · 1,663,022 tokens |
…e-tag Resolves conflict in services/kiloclaw/src/durable-objects/kiloclaw-instance/index.ts: both branches added imports near each other (this branch: syncTrackedImageTagToPostgresHelper from ./postgres; main: lifecycle-push imports from PR #2915). Took both. Test file auto-merged.
Summary
Adds a nullable
tracked_image_tagcolumn tokiloclaw_instances. The Durable Object alarm reconciler writes the column on each tick. This is the schema groundwork for an upcoming admin tool that filters instance populations by current running version, planned as Phase 1.5.2 inplans/kiloclaw-forced-upgrades.md.The Durable Object remains the source of truth for the running image tag. The Postgres column is a denormalized read cache so admin tooling can query instances by version using SQL. The alarm write happens via
ctx.waitUntilso a Postgres failure cannot block reconciliation. The UPDATE usesIS DISTINCT FROMin the WHERE clause, which makes Postgres skip the row entirely when the value already matches. That keeps vacuum pressure low on idle fleets.After deploy, the active fleet populates within roughly 30 minutes worst case (the longest alarm interval). New rows populate on first alarm.
This change also updates
services/kiloclaw/AGENTS.mdto acknowledge that the Worker writes Postgres in two narrow exception paths: destroy finalization (already in place) and this denormalized operational metadata column. The previous invariant text claimed Next.js was the sole writer, which had not been accurate since the destroy path landed.Verification
pnpm drizzle generateand verified it is additive only (nullable column plus a partial index).pnpm drizzle migrate.SELECT tracked_image_tag FROM kiloclaw_instancesreturned the expected value.pnpm run format:checkpasses.pnpm run lintandpnpm run typecheckshow no new errors in touched files. The errors that remain are in unrelated areas (services/gastown/container/*for lint,apps/mobileandservices/kiloclaw/src/northflankfor typecheck) and were already failing onmain.packages/db/src/schema.test.tspasses (6 of 6).Visual Changes
N/A
Reviewer Notes
Schema change is additive. After this lands, the active fleet self populates
tracked_image_tagover the next alarm cycle (5 minutes for running instances, up to 30 minutes for idle ones). The bulk version change UI consumes this column in a subsequent PR (Phase 1.5.2 inplans/kiloclaw-forced-upgrades.md).