Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .specs/kiloclaw-datamodel.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,6 @@ not yet enforced in the current codebase:
across all services that mutate subscription records. Some
subscription-creation paths may already write change-log entries;
complete cross-service coverage remains the intended invariant.
4. Fresh Provision Admission SHOULD be implemented in the Registry-backed
Worker admission flow before the existing web advisory lock is removed.
(Currently, web requests use transitional PostgreSQL advisory-lock
coordination that is being replaced because it is unsafe through
transaction-pooled production connections.)

## Changelog

Expand Down
15 changes: 15 additions & 0 deletions apps/web/src/lib/kiloclaw/kiloclaw-internal-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,21 @@ export class KiloClawInternalClient {
);
}

async repairProvisionReservation(
userId: string,
instanceId: string,
orgId?: string
): Promise<{ ok: true }> {
return this.request(
'/api/platform/provision/repair-reservation',
{
method: 'POST',
body: JSON.stringify({ userId, instanceId, orgId }),
},
{ userId }
);
}

async start(
userId: string,
instanceId?: string,
Expand Down
28 changes: 28 additions & 0 deletions apps/web/src/lib/kiloclaw/provision-error-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { TRPCError } from '@trpc/server';
import { UpstreamApiError } from '@/lib/trpc/init';
import { KiloClawApiError } from './kiloclaw-internal-client';

type ProvisionErrorPayload = { message?: string; code?: string };

type ProvisionErrorPayloadReader = (err: KiloClawApiError) => ProvisionErrorPayload;

export function handleProvisionError(err: unknown, getPayload: ProvisionErrorPayloadReader): never {
if (err instanceof KiloClawApiError && (err.statusCode === 409 || err.statusCode === 503)) {
Comment thread
pandemicsyn marked this conversation as resolved.
Outdated
const { message, code } = getPayload(err);
if (
code === 'provision_in_progress' ||
code === 'provision_completion_pending' ||
code === 'instance_already_active' ||
code === 'instance_destroyed'
) {
throw new TRPCError({
code: 'CONFLICT',
message:
message ??
'An instance is already being created. Wait for setup to finish, then try again.',
cause: new UpstreamApiError(code),
});
}
}
throw err;
}
200 changes: 0 additions & 200 deletions apps/web/src/lib/kiloclaw/provision-lock.test.ts

This file was deleted.

90 changes: 0 additions & 90 deletions apps/web/src/lib/kiloclaw/provision-lock.ts

This file was deleted.

11 changes: 11 additions & 0 deletions apps/web/src/lib/kiloclaw/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,17 @@ export type RegistryResult = {
createdAt: string;
destroyedAt: string | null;
}>;
reservations: Array<{
instanceId: string;
doKey: string;
assignedUserId: string;
status: 'in_progress' | 'completed' | 'failed_requires_reconciliation' | 'released';
startedAt: string;
updatedAt: string;
completedAt: string | null;
failureCode: string | null;
resolutionReason: string | null;
}>;
migrated: boolean;
};

Expand Down
Loading
Loading