Build the agent-native compute CRM platform
CI / verify (push) Successful in 3m6s

This commit is contained in:
2026-08-13 01:39:01 -07:00
parent bfd2f8d95a
commit 853bde2265
160 changed files with 61812 additions and 483 deletions
+672
View File
@@ -0,0 +1,672 @@
import {
ALLOCATION_STATUSES,
CONSUMING_ALLOCATION_STATUSES,
RESERVING_ALLOCATION_STATUSES,
} from '@pig/core';
import type {
AllocationStatus,
GuaranteeType,
GpuSocket,
InterconnectType,
SecurityTier,
} from '@pig/core';
import type {
Allocation,
CapacityCommitment,
Database,
DemandDeal,
NewCapacityCommitment,
} from '@pig/db';
import { allocations, capacityCommitments, demandDeals } from '@pig/db';
import { eq } from 'drizzle-orm';
import type { Principal } from '../lib/auth';
import { MutationError } from '../lib/mutation';
import { quantityAt, type CommitmentShape } from './capacity';
export type CapacityWriteTransaction = Parameters<Parameters<Database['transaction']>[0]>[0];
export interface CommitmentCapacity {
id: string;
gpuCount: number;
startsAt: Date;
endsAt: Date;
totalGpuHours: number;
shape: CommitmentShape | null;
oversubscriptionPct: number;
terminatedAt: Date | null;
}
export interface ReservationCapacity {
id?: string;
gpuHours: number;
startsAt: Date;
endsAt: Date;
status: AllocationStatus;
holdExpiresAt: Date | null;
}
export interface CapacityViolation {
code: 'outside_commitment_window' | 'total_capacity_exceeded' | 'shape_capacity_exceeded';
message: string;
at?: Date;
reserved?: number;
available?: number;
}
const EPSILON = 1e-7;
function isLiveReservation(reservation: ReservationCapacity, now: Date): boolean {
if (!(RESERVING_ALLOCATION_STATUSES as readonly string[]).includes(reservation.status)) {
return false;
}
return !(
reservation.status === 'planned' &&
reservation.holdExpiresAt !== null &&
reservation.holdExpiresAt <= now
);
}
function reservationRate(reservation: ReservationCapacity): number {
const durationHours =
(reservation.endsAt.getTime() - reservation.startsAt.getTime()) / 3_600_000;
return durationHours > 0 ? reservation.gpuHours / durationHours : Number.POSITIVE_INFINITY;
}
/**
* Checks both the contracted hour budget and every instantaneous shape interval.
* The row lock used by the caller turns this pure check into a concurrency-safe
* invariant rather than an optimistic preflight that two requests can both pass.
*/
export function findCapacityViolation(
commitment: CommitmentCapacity,
existing: readonly ReservationCapacity[],
candidate: ReservationCapacity | null,
now: Date,
): CapacityViolation | null {
const reservations = [...existing, ...(candidate ? [candidate] : [])].filter((reservation) =>
isLiveReservation(reservation, now),
);
for (const reservation of reservations) {
if (
reservation.startsAt < commitment.startsAt ||
reservation.endsAt > commitment.endsAt ||
reservation.endsAt <= reservation.startsAt
) {
return {
code: 'outside_commitment_window',
message: 'The allocation window must sit inside the commitment window.',
};
}
}
const multiplier = 1 + commitment.oversubscriptionPct / 100;
const allowedGpuHours = commitment.totalGpuHours * multiplier;
const reservedGpuHours = reservations.reduce((sum, reservation) => sum + reservation.gpuHours, 0);
if (reservedGpuHours - allowedGpuHours > EPSILON) {
return {
code: 'total_capacity_exceeded',
message: 'The allocation would exceed the commitment GPU-hour budget.',
reserved: reservedGpuHours,
available: allowedGpuHours,
};
}
const boundaries = new Set<number>([
commitment.startsAt.getTime(),
commitment.endsAt.getTime(),
...(commitment.shape?.intervals.map((boundary) => Date.parse(boundary)) ?? []),
]);
for (const reservation of reservations) {
boundaries.add(reservation.startsAt.getTime());
boundaries.add(reservation.endsAt.getTime());
}
const ordered = [...boundaries]
.filter(
(boundary) =>
Number.isFinite(boundary) &&
boundary >= commitment.startsAt.getTime() &&
boundary <= commitment.endsAt.getTime(),
)
.sort((a, b) => a - b);
for (let index = 0; index < ordered.length - 1; index++) {
const intervalStart = ordered[index]!;
const intervalEnd = ordered[index + 1]!;
if (intervalEnd <= intervalStart) continue;
const overlapping = reservations.filter(
(reservation) =>
reservation.startsAt.getTime() < intervalEnd &&
reservation.endsAt.getTime() > intervalStart,
);
if (overlapping.length === 0) continue;
const at = new Date(intervalStart + (intervalEnd - intervalStart) / 2);
const reserved = overlapping.reduce(
(sum, reservation) => sum + reservationRate(reservation),
0,
);
const available = quantityAt(commitment.shape, commitment.gpuCount, at) * multiplier;
if (reserved - available > EPSILON) {
return {
code: 'shape_capacity_exceeded',
message: 'The allocation would exceed available GPUs during part of its window.',
at,
reserved,
available,
};
}
}
return null;
}
export function commitmentCapacityError(commitment: CommitmentCapacity): string | null {
const durationHours =
(commitment.endsAt.getTime() - commitment.startsAt.getTime()) / 3_600_000;
if (durationHours <= 0) return 'Commitment end must be after its start.';
if (commitment.oversubscriptionPct < 0) return 'Oversubscription cannot be negative.';
const shape = commitment.shape;
if (!shape) {
if (commitment.totalGpuHours - durationHours * commitment.gpuCount > EPSILON) {
return 'Total GPU-hours cannot exceed the flat commitment envelope.';
}
return null;
}
if (shape.intervals.length < 2 || shape.quantities.length !== shape.intervals.length - 1) {
return 'Shape quantities must have exactly one entry per interval.';
}
const boundaries = shape.intervals.map((boundary) => Date.parse(boundary));
if (boundaries.some((boundary) => !Number.isFinite(boundary))) {
return 'Shape intervals must be valid ISO-8601 timestamps.';
}
if (
boundaries[0] !== commitment.startsAt.getTime() ||
boundaries[boundaries.length - 1] !== commitment.endsAt.getTime()
) {
return 'Shape intervals must cover the full commitment window.';
}
for (let index = 0; index < boundaries.length - 1; index++) {
if (boundaries[index + 1]! <= boundaries[index]!) {
return 'Shape intervals must be strictly ascending.';
}
}
if (
shape.quantities.some(
(quantity) => !Number.isInteger(quantity) || quantity < 0 || quantity > commitment.gpuCount,
)
) {
return 'Shape quantities must be whole GPUs within the commitment envelope.';
}
const shapedGpuHours = shape.quantities.reduce(
(sum, quantity, index) =>
sum + ((boundaries[index + 1]! - boundaries[index]!) / 3_600_000) * quantity,
0,
);
if (commitment.totalGpuHours - shapedGpuHours > EPSILON) {
return 'Total GPU-hours cannot exceed the capacity described by the shape.';
}
return null;
}
export interface CommitmentWriteInput {
accountId: string;
siteId?: string | null;
supplyDealId?: string | null;
name: string;
gpuType: string;
socket?: GpuSocket | null;
gpuCount: number;
interconnectType?: InterconnectType;
securityTier?: SecurityTier;
startsAt: string;
endsAt: string;
totalGpuHours: number;
costPerGpuHourCents: number;
currency?: string;
shape?: CommitmentShape | null;
colocateWith?: string[];
isContiguous?: boolean;
minimumSpendCents?: number | null;
isAutoRenew?: boolean;
noticeDays?: number | null;
takeOrPayFloorPct?: number | null;
prepaidPct?: number | null;
prepaidAmountCents?: number | null;
usefulLifeYears?: number | null;
salvageValuePct?: number | null;
depreciationStartAt?: string | null;
costOfCapitalBps?: number | null;
financingInstrument?: string | null;
oversubscriptionPct?: number;
notes?: string | null;
terminatedAt?: string | null;
}
export interface AllocationWriteInput {
capacityCommitmentId: string;
demandDealId: string;
gpuHours: number;
pricePerGpuHourCents: number;
currency?: string;
startsAt: string;
endsAt: string;
status: (typeof CONSUMING_ALLOCATION_STATUSES)[number];
guaranteeType?: GuaranteeType;
priority?: number;
complianceDecisionId?: string | null;
notes?: string | null;
}
export interface HoldWriteInput
extends Omit<AllocationWriteInput, 'status' | 'pricePerGpuHourCents'> {
pricePerGpuHourCents?: number;
holdExpiresAt: string;
holdOpportunityCostCents?: number | null;
}
export interface ReleaseWriteInput {
reason?: string;
}
export interface CommitmentWriteResult {
commitment: CapacityCommitment;
}
export interface AllocationWriteResult {
allocation: Allocation;
commitment: Pick<CapacityCommitment, 'id' | 'name'>;
deal: Pick<DemandDeal, 'id' | 'accountId'>;
}
export interface ReleaseWriteResult {
allocation: Allocation;
accountId?: string;
previousStatus: AllocationStatus;
}
function toCapacity(commitment: CapacityCommitment): CommitmentCapacity {
return {
id: commitment.id,
gpuCount: commitment.gpuCount,
startsAt: commitment.startsAt,
endsAt: commitment.endsAt,
totalGpuHours: Number(commitment.totalGpuHours),
shape: commitment.shape,
oversubscriptionPct: Number(commitment.oversubscriptionPct),
terminatedAt: commitment.terminatedAt,
};
}
function toReservation(allocation: Allocation): ReservationCapacity {
return {
id: allocation.id,
gpuHours: Number(allocation.gpuHours),
startsAt: allocation.startsAt,
endsAt: allocation.endsAt,
status: allocation.status,
holdExpiresAt: allocation.holdExpiresAt,
};
}
function assertCommitmentValid(commitment: CommitmentCapacity): void {
const error = commitmentCapacityError(commitment);
if (error) throw new MutationError('invalid_commitment', error, 400);
}
function assertCapacityAvailable(
commitment: CommitmentCapacity,
existing: readonly Allocation[],
candidate: ReservationCapacity | null,
now: Date,
): void {
const violation = findCapacityViolation(
commitment,
existing.map(toReservation),
candidate,
now,
);
if (!violation) return;
throw new MutationError(violation.code, violation.message, 409);
}
export class CapacityWriteService {
constructor(private readonly tx: CapacityWriteTransaction) {}
private async lockCommitment(id: string): Promise<CapacityCommitment> {
const [commitment] = await this.tx
.select()
.from(capacityCommitments)
.where(eq(capacityCommitments.id, id))
.limit(1)
.for('update');
if (!commitment) throw MutationError.notFound('Capacity commitment');
return commitment;
}
private async reservations(commitmentId: string): Promise<Allocation[]> {
return this.tx
.select()
.from(allocations)
.where(eq(allocations.capacityCommitmentId, commitmentId));
}
private async demandDeal(id: string): Promise<Pick<DemandDeal, 'id' | 'accountId'>> {
const [deal] = await this.tx
.select({ id: demandDeals.id, accountId: demandDeals.accountId })
.from(demandDeals)
.where(eq(demandDeals.id, id))
.limit(1);
if (!deal) throw MutationError.notFound('Demand deal');
return deal;
}
async createCommitment(input: CommitmentWriteInput, now: Date): Promise<CommitmentWriteResult> {
const capacity: CommitmentCapacity = {
id: 'new',
gpuCount: input.gpuCount,
startsAt: new Date(input.startsAt),
endsAt: new Date(input.endsAt),
totalGpuHours: input.totalGpuHours,
shape: input.shape ?? null,
oversubscriptionPct: input.oversubscriptionPct ?? 0,
terminatedAt: null,
};
assertCommitmentValid(capacity);
const [commitment] = await this.tx
.insert(capacityCommitments)
.values({
accountId: input.accountId,
siteId: input.siteId,
supplyDealId: input.supplyDealId,
name: input.name,
gpuType: input.gpuType,
socket: input.socket,
gpuCount: input.gpuCount,
interconnectType: input.interconnectType,
securityTier: input.securityTier,
startsAt: capacity.startsAt,
endsAt: capacity.endsAt,
totalGpuHours: String(input.totalGpuHours),
costPerGpuHourCents: input.costPerGpuHourCents,
currency: input.currency,
shape: input.shape,
colocateWith: input.colocateWith,
isContiguous: input.isContiguous,
minimumSpendCents: input.minimumSpendCents,
isAutoRenew: input.isAutoRenew,
noticeDays: input.noticeDays,
takeOrPayFloorPct:
input.takeOrPayFloorPct === undefined || input.takeOrPayFloorPct === null
? input.takeOrPayFloorPct
: String(input.takeOrPayFloorPct),
prepaidPct:
input.prepaidPct === undefined || input.prepaidPct === null
? input.prepaidPct
: String(input.prepaidPct),
prepaidAmountCents: input.prepaidAmountCents,
usefulLifeYears:
input.usefulLifeYears === undefined || input.usefulLifeYears === null
? input.usefulLifeYears
: String(input.usefulLifeYears),
salvageValuePct:
input.salvageValuePct === undefined || input.salvageValuePct === null
? input.salvageValuePct
: String(input.salvageValuePct),
depreciationStartAt:
input.depreciationStartAt === undefined
? undefined
: input.depreciationStartAt === null
? null
: new Date(input.depreciationStartAt),
costOfCapitalBps: input.costOfCapitalBps,
financingInstrument: input.financingInstrument,
oversubscriptionPct: String(input.oversubscriptionPct ?? 0),
notes: input.notes,
createdAt: now,
updatedAt: now,
})
.returning();
if (!commitment) throw new MutationError('write_failed', 'Commitment was not created.', 409);
return { commitment };
}
async updateCommitment(
id: string,
input: Partial<CommitmentWriteInput>,
now: Date,
): Promise<CommitmentWriteResult> {
const current = await this.lockCommitment(id);
const existing = await this.reservations(id);
const prospective: CommitmentCapacity = {
id,
gpuCount: input.gpuCount ?? current.gpuCount,
startsAt: input.startsAt ? new Date(input.startsAt) : current.startsAt,
endsAt: input.endsAt ? new Date(input.endsAt) : current.endsAt,
totalGpuHours: input.totalGpuHours ?? Number(current.totalGpuHours),
shape: input.shape === undefined ? current.shape : input.shape,
oversubscriptionPct:
input.oversubscriptionPct ?? Number(current.oversubscriptionPct),
terminatedAt:
input.terminatedAt === undefined
? current.terminatedAt
: input.terminatedAt
? new Date(input.terminatedAt)
: null,
};
assertCommitmentValid(prospective);
assertCapacityAvailable(prospective, existing, null, now);
if (
prospective.terminatedAt &&
existing.some((allocation) => isLiveReservation(toReservation(allocation), now))
) {
throw new MutationError(
'commitment_in_use',
'Release live allocations before terminating the commitment.',
409,
);
}
const changes: Partial<NewCapacityCommitment> = { updatedAt: now };
const assign = <Key extends keyof CommitmentWriteInput>(
key: Key,
value: NewCapacityCommitment[keyof NewCapacityCommitment],
) => {
if (input[key] !== undefined) {
(changes as Record<string, unknown>)[key] = value;
}
};
assign('accountId', input.accountId);
assign('siteId', input.siteId);
assign('supplyDealId', input.supplyDealId);
assign('name', input.name);
assign('gpuType', input.gpuType);
assign('socket', input.socket);
assign('gpuCount', input.gpuCount);
assign('interconnectType', input.interconnectType);
assign('securityTier', input.securityTier);
assign('startsAt', prospective.startsAt);
assign('endsAt', prospective.endsAt);
assign('totalGpuHours', String(prospective.totalGpuHours));
assign('costPerGpuHourCents', input.costPerGpuHourCents);
assign('currency', input.currency);
assign('shape', input.shape);
assign('colocateWith', input.colocateWith);
assign('isContiguous', input.isContiguous);
assign('minimumSpendCents', input.minimumSpendCents);
assign('isAutoRenew', input.isAutoRenew);
assign('noticeDays', input.noticeDays);
assign(
'takeOrPayFloorPct',
input.takeOrPayFloorPct === null ? null : String(input.takeOrPayFloorPct),
);
assign('prepaidPct', input.prepaidPct === null ? null : String(input.prepaidPct));
assign('prepaidAmountCents', input.prepaidAmountCents);
assign('usefulLifeYears', input.usefulLifeYears === null ? null : String(input.usefulLifeYears));
assign('salvageValuePct', input.salvageValuePct === null ? null : String(input.salvageValuePct));
assign(
'depreciationStartAt',
input.depreciationStartAt ? new Date(input.depreciationStartAt) : null,
);
assign('costOfCapitalBps', input.costOfCapitalBps);
assign('financingInstrument', input.financingInstrument);
assign('oversubscriptionPct', String(prospective.oversubscriptionPct));
assign('notes', input.notes);
assign('terminatedAt', prospective.terminatedAt);
const [commitment] = await this.tx
.update(capacityCommitments)
.set(changes)
.where(eq(capacityCommitments.id, id))
.returning();
if (!commitment) throw MutationError.notFound('Capacity commitment');
return { commitment };
}
async createAllocation(
input: AllocationWriteInput,
principal: Principal,
now: Date,
): Promise<AllocationWriteResult> {
const commitment = await this.lockCommitment(input.capacityCommitmentId);
if (commitment.terminatedAt) {
throw new MutationError('commitment_terminated', 'The commitment is terminated.', 409);
}
const deal = await this.demandDeal(input.demandDealId);
const existing = await this.reservations(commitment.id);
const candidate: ReservationCapacity = {
gpuHours: input.gpuHours,
startsAt: new Date(input.startsAt),
endsAt: new Date(input.endsAt),
status: input.status,
holdExpiresAt: null,
};
assertCapacityAvailable(toCapacity(commitment), existing, candidate, now);
const [allocation] = await this.tx
.insert(allocations)
.values({
capacityCommitmentId: commitment.id,
demandDealId: deal.id,
gpuHours: String(input.gpuHours),
pricePerGpuHourCents: input.pricePerGpuHourCents,
currency: input.currency,
startsAt: candidate.startsAt,
endsAt: candidate.endsAt,
status: input.status,
guaranteeType: input.guaranteeType,
priority: input.priority,
complianceDecisionId: input.complianceDecisionId,
createdByUserId: principal.userId,
notes: input.notes,
createdAt: now,
updatedAt: now,
})
.returning();
if (!allocation) throw new MutationError('write_failed', 'Allocation was not created.', 409);
return { allocation, commitment, deal };
}
async createHold(
input: HoldWriteInput,
principal: Principal,
now: Date,
): Promise<AllocationWriteResult> {
const holdExpiresAt = new Date(input.holdExpiresAt);
if (holdExpiresAt <= now) {
throw new MutationError('hold_already_expired', 'A new hold must expire in the future.', 400);
}
const commitment = await this.lockCommitment(input.capacityCommitmentId);
if (commitment.terminatedAt) {
throw new MutationError('commitment_terminated', 'The commitment is terminated.', 409);
}
const deal = await this.demandDeal(input.demandDealId);
const existing = await this.reservations(commitment.id);
const candidate: ReservationCapacity = {
gpuHours: input.gpuHours,
startsAt: new Date(input.startsAt),
endsAt: new Date(input.endsAt),
status: 'planned',
holdExpiresAt,
};
assertCapacityAvailable(toCapacity(commitment), existing, candidate, now);
const [allocation] = await this.tx
.insert(allocations)
.values({
capacityCommitmentId: commitment.id,
demandDealId: deal.id,
gpuHours: String(input.gpuHours),
pricePerGpuHourCents: input.pricePerGpuHourCents ?? 0,
currency: input.currency,
startsAt: candidate.startsAt,
endsAt: candidate.endsAt,
status: 'planned',
holdExpiresAt,
holdOpportunityCostCents: input.holdOpportunityCostCents,
guaranteeType: input.guaranteeType,
priority: input.priority,
complianceDecisionId: input.complianceDecisionId,
createdByUserId: principal.userId,
notes: input.notes,
createdAt: now,
updatedAt: now,
})
.returning();
if (!allocation) throw new MutationError('write_failed', 'Hold was not created.', 409);
return { allocation, commitment, deal };
}
async releaseAllocation(
id: string,
_input: ReleaseWriteInput,
now: Date,
): Promise<ReleaseWriteResult> {
const [reference] = await this.tx
.select({ capacityCommitmentId: allocations.capacityCommitmentId })
.from(allocations)
.where(eq(allocations.id, id))
.limit(1);
if (!reference) throw MutationError.notFound('Allocation');
await this.lockCommitment(reference.capacityCommitmentId);
const [current] = await this.tx
.select()
.from(allocations)
.where(eq(allocations.id, id))
.limit(1)
.for('update');
if (!current) throw MutationError.notFound('Allocation');
if (current.status === 'released') {
throw new MutationError('already_released', 'The allocation is already released.', 409);
}
if (current.status === 'completed') {
throw new MutationError(
'completed_allocation',
'Completed billable usage cannot be released.',
409,
);
}
const [allocation] = await this.tx
.update(allocations)
.set({ status: 'released', releasedAt: now, holdExpiresAt: null, updatedAt: now })
.where(eq(allocations.id, id))
.returning();
if (!allocation) throw MutationError.notFound('Allocation');
const deal = current.demandDealId
? await this.demandDeal(current.demandDealId)
: undefined;
return { allocation, accountId: deal?.accountId, previousStatus: current.status };
}
}
export const VALID_ALLOCATION_STATUSES = ALLOCATION_STATUSES;