Skip to content

feat(kiloclaw): add image tag based version pinning#483

Draft
St0rmz1 wants to merge 12 commits intomainfrom
feat/kiloclaw-image-tag-pinning
Draft

feat(kiloclaw): add image tag based version pinning#483
St0rmz1 wants to merge 12 commits intomainfrom
feat/kiloclaw-image-tag-pinning

Conversation

@St0rmz1
Copy link
Contributor

@St0rmz1 St0rmz1 commented Feb 23, 2026

Add admin-controlled per-user version pinning with image_tag as the unique deployable identity and image_digest for content integrity.

  • New DB tables: kiloclaw_available_versions (catalog), kiloclaw_version_pins (per user pins)
  • Admin versions router: CRUD for catalog entries, pin/unpin users, publish versions
  • Cron sync: worker KV → Postgres catalog with atomic upserts and digest conflict rejection
  • Provision flow: cloud reads pin from Postgres, passes tag+digest to worker
  • Worker: accepts pinnedImageTag, skips KV lookup for pinned users, tracks isPinned
  • Digest uniqueness enforced at every layer (Postgres, admin publish, sync, worker KV)
  • Admin UI: pin management on instance detail, version stats cards, sync button
  • Tests for all new functionality

St0rmz1 and others added 6 commits February 23, 2026 15:40
Add admin-controlled per-user version pinning with image_tag as the unique deployable identity and image_digest for content integrity.

- New DB tables: kiloclaw_available_versions (catalog), kiloclaw_version_pins (per user pins)
- Admin versions router: CRUD for catalog entries, pin/unpin users, publish versions
- Cron sync: worker KV → Postgres catalog with atomic upserts and digest conflict rejection
- Provision flow: cloud reads pin from Postgres, passes tag+digest to worker
- Worker: accepts pinnedImageTag, skips KV lookup for pinned users, tracks isPinned
- Digest uniqueness enforced at every layer (Postgres, admin publish, sync, worker KV)
- Admin UI: pin management on instance detail, version stats cards, sync button
- Tests for all new functionality
@St0rmz1 St0rmz1 marked this pull request as ready for review February 24, 2026 00:39
@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Feb 24, 2026

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/routers/kiloclaw-router.ts 148 Deprecated pins are silently ignored during provisioning (pin allows deprecated, provision only accepts active).
src/app/api/cron/sync-kiloclaw-versions/route.ts 57 Digest conflict check remains race-prone under concurrent sync runs, risking raw unique-constraint failures.
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
None N/A None
Files Reviewed (28 files)
  • kiloclaw/scripts/push-dev.sh - 0 issues
  • kiloclaw/src/durable-objects/kiloclaw-instance-pinning.test.ts - 0 issues
  • kiloclaw/src/durable-objects/kiloclaw-instance.ts - 0 issues
  • kiloclaw/src/index.ts - 0 issues
  • kiloclaw/src/lib/image-version-pinning.test.ts - 0 issues
  • kiloclaw/src/lib/image-version.ts - 0 issues
  • kiloclaw/src/routes/platform.ts - 0 new issues
  • kiloclaw/src/schemas/instance-config.ts - 0 issues
  • kiloclaw/src/types.ts - 0 issues
  • src/app/admin/components/KiloclawInstances/KiloclawInstanceDetail.tsx - 0 issues
  • src/app/admin/components/KiloclawInstances/KiloclawInstancesPage.tsx - 0 issues
  • src/app/api/cron/sync-kiloclaw-versions/route.test.ts - 0 issues
  • src/app/api/cron/sync-kiloclaw-versions/route.ts - 1 issue
  • src/db/migrations/0032_skinny_vin_gonzales.sql - skipped (migration)
  • src/db/migrations/meta/0032_snapshot.json - skipped (generated snapshot)
  • src/db/migrations/meta/_journal.json - skipped (migration journal)
  • src/db/schema.test.ts - 0 issues
  • src/db/schema.ts - 0 new issues
  • src/lib/kiloclaw/kiloclaw-internal-client.ts - 0 issues
  • src/lib/kiloclaw/types.ts - 0 issues
  • src/lib/user.test.ts - 0 issues
  • src/lib/user.ts - 0 issues
  • src/routers/admin-kiloclaw-versions-router.test.ts - 0 issues
  • src/routers/admin-kiloclaw-versions-router.ts - 0 new issues
  • src/routers/admin-router.ts - 0 issues
  • src/routers/kiloclaw-router-pinning.test.ts - 0 issues
  • src/routers/kiloclaw-router.ts - 1 issue
  • vercel.json - 0 issues

Fix these issues in Kilo Cloud

  - Move digest conflict check inside transaction with FOR UPDATE lock
    to prevent TOCTOU race in publishVersion
  - Add paginated KV list helper for catalogs beyond 1000 entries
  - Fix sync rate limit to skip only new inserts, not updates
  - Add kiloclaw_version_pins cleanup to softDeleteUser for GDPR
    compliance (with test)
…ag-pinning

merge: resolve conflicts with main

  Renumber version pinning migration from 0024 to 0028 to avoid
  collision with migrations landed on main (0024-0027). Regenerated
  snapshot with correct parent chain. Both SCHEMA_CHECK_ENUMS
  (KiloClawVersionStatus + SecurityAuditLogAction) included
…ag-pinning

merge: resolve migration conflicts with main

  Renumber 0028_skinny_vin_gonzales to 0029 to avoid collision
  with main's 0028_wakeful_mercury migration. Updated snapshot
  chain and schema state accordingly.
@St0rmz1 St0rmz1 requested a review from pandemicsyn February 24, 2026 21:25
const catalogEntry = await db.query.kiloclaw_available_versions.findFirst({
where: and(
eq(kiloclaw_available_versions.image_tag, pin.image_tag),
eq(kiloclaw_available_versions.status, 'active')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Deprecated pins are silently ignored during provisioning

pinUser currently allows pinning to versions with status = 'deprecated', but this query only honors pins when the catalog row is active. That means admins can successfully create a pin that will never be applied, and the user silently falls back to latest.

This behavior mismatch can cause hard-to-debug rollout issues. Consider either rejecting deprecated pins in pinUser or allowing deprecated status here and only rejecting disabled.

// Reject entries whose digest already belongs to a different tag.
// Same digest = same image. Two tags with the same digest is not allowed.
if (entry.imageDigest) {
const conflict = await db.query.kiloclaw_available_versions.findFirst({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Digest conflict check is still race-prone under concurrent sync runs

The conflict read is done before the insert/upsert, but not inside a transaction/lock scope. If two sync executions run concurrently (cron overlap or manual trigger + cron), both can pass this check and then race into the unique digest index, causing a raw DB constraint error and failing the sync run.

Consider moving this conflict check into a transaction with row locking (similar to publishVersion) or handling unique-constraint errors explicitly and continuing safely.

@St0rmz1 St0rmz1 marked this pull request as draft February 25, 2026 14:55
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.

1 participant