gencow 0.1.209 → 0.1.210

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gencow",
3
- "version": "0.1.209",
3
+ "version": "0.1.210",
4
4
  "description": "Gencow — AI Backend Engine",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,8 +33,8 @@
33
33
  "devDependencies": {
34
34
  "@types/node": "^25.9.5",
35
35
  "better-auth": "^1.6.23",
36
- "@gencow/client": "0.2.6",
37
36
  "@gencow/core": "0.1.43",
37
+ "@gencow/client": "0.2.6",
38
38
  "@gencow/react": "0.2.6"
39
39
  },
40
40
  "scripts": {
@@ -110044,32 +110044,6 @@ var require_output = __commonJS({
110044
110044
  }
110045
110045
  });
110046
110046
 
110047
- // ../../node_modules/.pnpm/@img+sharp-wasm32@0.34.5/node_modules/@img/sharp-wasm32/versions.json
110048
- var require_versions = __commonJS({
110049
- "../../node_modules/.pnpm/@img+sharp-wasm32@0.34.5/node_modules/@img/sharp-wasm32/versions.json"(exports2, module2) {
110050
- module2.exports = {
110051
- aom: "3.13.1",
110052
- cgif: "0.5.0",
110053
- emscripten: "4.0.18",
110054
- exif: "0.6.25",
110055
- expat: "2.7.3",
110056
- ffi: "3.5.2",
110057
- glib: "2.86.1",
110058
- heif: "1.20.2",
110059
- highway: "1.3.0",
110060
- imagequant: "2.4.1",
110061
- lcms: "2.17",
110062
- mozjpeg: "0826579",
110063
- resvg: "0.45.1",
110064
- spng: "0.7.4",
110065
- tiff: "4.7.1",
110066
- vips: "8.17.3",
110067
- webp: "1.6.0",
110068
- "zlib-ng": "2.2.5"
110069
- };
110070
- }
110071
- });
110072
-
110073
110047
  // ../../node_modules/.pnpm/sharp@0.34.5/node_modules/sharp/lib/utility.js
110074
110048
  var require_utility = __commonJS({
110075
110049
  "../../node_modules/.pnpm/sharp@0.34.5/node_modules/sharp/lib/utility.js"(exports2, module2) {
@@ -110114,7 +110088,7 @@ var require_utility = __commonJS({
110114
110088
  }
110115
110089
  } else {
110116
110090
  try {
110117
- versions = require_versions();
110091
+ versions = __require("@img/sharp-wasm32/versions");
110118
110092
  } catch (_4) {
110119
110093
  }
110120
110094
  }
@@ -415089,7 +415063,7 @@ async function persistDecision(tx, input, current, requiredTargets) {
415089
415063
  updated_at = NOW()
415090
415064
  WHERE app_id = ${input.appId}
415091
415065
  AND app_instance_id = ${input.appInstanceId}
415092
- AND route_epoch = ${input.expectedRouteEpoch}
415066
+ AND route_epoch = ${Number(current.route_epoch)}
415093
415067
  RETURNING app_id
415094
415068
  `) : await tx.execute(sql79`
415095
415069
  INSERT INTO app_serving_route_authorities (
@@ -415212,8 +415186,31 @@ async function persistPreparedDecision(tx, input, current, requiredTargets) {
415212
415186
  }
415213
415187
  return outcome(input, routeEpoch, predecessorHash, eventId, publicationSequence, false);
415214
415188
  }
415215
- async function assertAuthorityEpoch(current, input) {
415216
- if (current === null && input.expectedRouteEpoch !== 0 || current !== null && (current.environment !== input.environment || current.app_instance_id !== input.appInstanceId || Number(current.route_epoch) !== input.expectedRouteEpoch)) {
415189
+ async function loadLatestReservedEpoch(tx, input) {
415190
+ const result2 = await tx.execute(sql79`
415191
+ SELECT COALESCE(MAX(route_epoch), 0) AS route_epoch
415192
+ FROM app_serving_route_outbox
415193
+ WHERE app_id = ${input.appId}
415194
+ AND app_instance_id = ${input.appInstanceId}
415195
+ AND environment = ${input.environment}
415196
+ `);
415197
+ const routeEpoch = Number(
415198
+ rowsFromResult31(result2)[0]?.route_epoch ?? 0
415199
+ );
415200
+ if (!Number.isSafeInteger(routeEpoch) || routeEpoch < 0) fail13("APP_SERVING_ROUTE_EPOCH_CONFLICT");
415201
+ return routeEpoch;
415202
+ }
415203
+ async function assertPrepareAuthorityEpoch(tx, current, input) {
415204
+ const authorityEpoch = current ? Number(current.route_epoch) : 0;
415205
+ const reservedEpoch = await loadLatestReservedEpoch(tx, input);
415206
+ if (current !== null && (current.environment !== input.environment || current.app_instance_id !== input.appInstanceId) || authorityEpoch > input.expectedRouteEpoch || Math.max(authorityEpoch, reservedEpoch) !== input.expectedRouteEpoch) {
415207
+ fail13("APP_SERVING_ROUTE_EPOCH_CONFLICT");
415208
+ }
415209
+ }
415210
+ async function assertCommitPreparedAuthorityEpoch(tx, current, input) {
415211
+ const authorityEpoch = current ? Number(current.route_epoch) : 0;
415212
+ const reservedEpoch = await loadLatestReservedEpoch(tx, input);
415213
+ if (current !== null && (current.environment !== input.environment || current.app_instance_id !== input.appInstanceId) || authorityEpoch > input.expectedRouteEpoch || reservedEpoch !== input.expectedRouteEpoch + 1) {
415217
415214
  fail13("APP_SERVING_ROUTE_EPOCH_CONFLICT");
415218
415215
  }
415219
415216
  }
@@ -415221,7 +415218,6 @@ async function prepareNormalizedDecision(tx, input, acquireLock) {
415221
415218
  if (input.phase !== "prepare") fail13("APP_SERVING_ROUTE_DECISION_INVALID");
415222
415219
  await acquireLock(tx, `app-serving-route:${input.appId}`);
415223
415220
  const current = await loadAuthority(tx, input.appId);
415224
- await assertAuthorityEpoch(current, input);
415225
415221
  const requiredTargets = await resolveAppServingRouteTargetSet({
415226
415222
  db: tx,
415227
415223
  environment: input.environment,
@@ -415231,13 +415227,14 @@ async function prepareNormalizedDecision(tx, input, acquireLock) {
415231
415227
  });
415232
415228
  const replay = await inspectPreparedReplay(tx, input, current, requiredTargets);
415233
415229
  if (replay) return replay;
415230
+ await assertPrepareAuthorityEpoch(tx, current, input);
415234
415231
  return persistPreparedDecision(tx, input, current, requiredTargets);
415235
415232
  }
415236
415233
  async function commitPreparedNormalizedDecision(tx, input, acquireLock) {
415237
415234
  if (input.phase !== "commit") fail13("APP_SERVING_ROUTE_DECISION_INVALID");
415238
415235
  await acquireLock(tx, `app-serving-route:${input.appId}`);
415239
415236
  const current = await loadAuthority(tx, input.appId);
415240
- await assertAuthorityEpoch(current, input);
415237
+ await assertCommitPreparedAuthorityEpoch(tx, current, input);
415241
415238
  const preparedInput = { ...input, phase: "prepare" };
415242
415239
  const requiredTargets = await resolveAppServingRouteTargetSet({
415243
415240
  db: tx,
@@ -415532,8 +415529,42 @@ async function commitAppServingRouteSourceInTransaction(input) {
415532
415529
  if (authority && (authority.environment !== input.environment || authority.app_instance_id !== input.source.appInstanceId)) {
415533
415530
  fail15("APP_SERVING_ROUTE_SOURCE_DECISION_CONFLICT");
415534
415531
  }
415535
- const expectedRouteEpoch = authority ? Number(authority.route_epoch) : 0;
415536
- if (!Number.isSafeInteger(expectedRouteEpoch) || expectedRouteEpoch < 0) {
415532
+ const reservedResult = await input.tx.execute(sql80`
415533
+ SELECT COALESCE(MAX(route_epoch), 0) AS route_epoch
415534
+ FROM app_serving_route_outbox
415535
+ WHERE app_id = ${input.source.appId}
415536
+ AND app_instance_id = ${input.source.appInstanceId}
415537
+ AND environment = ${input.environment}
415538
+ `);
415539
+ const authorityEpoch = authority ? Number(authority.route_epoch) : 0;
415540
+ const reservedEpoch = Number(
415541
+ rowsFromResult32(reservedResult)[0]?.route_epoch ?? 0
415542
+ );
415543
+ let expectedRouteEpoch = Math.max(authorityEpoch, reservedEpoch);
415544
+ if (input.phase === "commit") {
415545
+ const preparedResult = await input.tx.execute(sql80`
415546
+ SELECT event_id, publication_sequence, environment, app_id, app_instance_id, route_epoch,
415547
+ phase, disposition, mutation_kind, entry_hash, predecessor_hash, topology_revision,
415548
+ target_set_id, source_revision
415549
+ FROM app_serving_route_outbox
415550
+ WHERE app_id = ${input.source.appId}
415551
+ AND app_instance_id = ${input.source.appInstanceId}
415552
+ AND mutation_kind = ${input.mutationKind}
415553
+ AND source_revision = ${input.sourceRevision}
415554
+ AND phase = 'prepare'
415555
+ FOR UPDATE
415556
+ `);
415557
+ const prepared = rowsFromResult32(preparedResult)[0];
415558
+ const preparedEpoch = Number(prepared?.route_epoch);
415559
+ const preparedEntryHash = Number.isSafeInteger(preparedEpoch) ? hashServingRouteManifestEntry(
415560
+ compileAppServingRouteEntry({ ...input.source, routeEpoch: preparedEpoch })
415561
+ ) : "";
415562
+ if (!prepared || prepared.environment !== input.environment || prepared.disposition !== input.source.disposition || prepared.topology_revision !== input.topologyRevision || prepared.target_set_id !== input.targetSetId || prepared.entry_hash !== preparedEntryHash || preparedEpoch < 1) {
415563
+ fail15("APP_SERVING_ROUTE_SOURCE_DECISION_CONFLICT");
415564
+ }
415565
+ expectedRouteEpoch = preparedEpoch - 1;
415566
+ }
415567
+ if (!Number.isSafeInteger(authorityEpoch) || authorityEpoch < 0 || !Number.isSafeInteger(reservedEpoch) || !Number.isSafeInteger(expectedRouteEpoch)) {
415537
415568
  fail15("APP_SERVING_ROUTE_SOURCE_DECISION_CONFLICT");
415538
415569
  }
415539
415570
  const entry = compileAppServingRouteEntry({
@@ -415579,9 +415610,6 @@ function fail16(code) {
415579
415610
  }
415580
415611
  async function recordActivationServingRoute(input) {
415581
415612
  if (!input.publication) return void 0;
415582
- if (input.deploymentEnvironment !== input.publication.environment) {
415583
- return fail16("ACTIVATION_SERVING_ROUTE_ENVIRONMENT_MISMATCH");
415584
- }
415585
415613
  const app2 = (await input.tx.select({
415586
415614
  instanceId: apps.instanceId,
415587
415615
  name: apps.name,
@@ -415707,7 +415735,6 @@ async function prepareCandidateActivationServingRoute(input) {
415707
415735
  publication: input.servingRoutePublication,
415708
415736
  acquireLock,
415709
415737
  appId: input.appId,
415710
- deploymentEnvironment: deployment.env,
415711
415738
  activationId: input.activationId,
415712
415739
  instanceId: input.instanceId,
415713
415740
  nodeId: activation.nodeId,
@@ -415871,7 +415898,6 @@ async function commitCandidateActivation(input) {
415871
415898
  publication: input.servingRoutePublication,
415872
415899
  acquireLock,
415873
415900
  appId: input.appId,
415874
- deploymentEnvironment: deploymentRows2[0].env,
415875
415901
  activationId: input.activationId,
415876
415902
  instanceId: input.instanceId,
415877
415903
  nodeId: activation.nodeId,
@@ -415988,7 +416014,6 @@ async function commitCandidateActivation(input) {
415988
416014
  publication: input.servingRoutePublication,
415989
416015
  acquireLock,
415990
416016
  appId: input.appId,
415991
- deploymentEnvironment: deploymentRows[0].env,
415992
416017
  activationId: input.activationId,
415993
416018
  instanceId: input.instanceId,
415994
416019
  nodeId: activation.nodeId,
@@ -419033,6 +419058,7 @@ async function runImmutableDeploymentCandidate(input) {
419033
419058
  () => input.prepareSchema({ workspacePath: generation.workspacePath }),
419034
419059
  preparation
419035
419060
  );
419061
+ await input.enterRuntimePreparation?.();
419036
419062
  if (!existingReady) {
419037
419063
  await runWithCandidateFailurePhase(
419038
419064
  "workspace_build",
@@ -421259,10 +421285,8 @@ async function deployWithRuntimeControlPlane(input) {
421259
421285
  verifyPreparedSchema: async (revisionId) => {
421260
421286
  await assertSchemaRevisionAllowsCandidate({ db: input.db, revisionId });
421261
421287
  },
421262
- build: async ({ workspacePath }) => {
421263
- await input.onExecutorPhase?.("runtime_preparing");
421264
- return provisioner.prepareWorkspace(input.app.name, workspacePath);
421265
- },
421288
+ enterRuntimePreparation: () => input.onExecutorPhase?.("runtime_preparing") ?? Promise.resolve(),
421289
+ build: ({ workspacePath }) => provisioner.prepareWorkspace(input.app.name, workspacePath),
421266
421290
  prepareIdentity,
421267
421291
  bootAndAttest: async (context2) => {
421268
421292
  await input.onExecutorPhase?.("candidate_attesting");
@@ -424053,7 +424077,7 @@ function loadAppServingRouteRolloutConfig(input) {
424053
424077
  const mode = route.publicationMode;
424054
424078
  if (mode === "off") return null;
424055
424079
  if (mode !== "enforce" || !Number.isSafeInteger(input.appId) || input.appId < 1) return fail30();
424056
- const environment = input.deploymentEnvironment;
424080
+ const deploymentEnvironment = input.deploymentEnvironment;
424057
424081
  const configuredEnvironment = route.environment ?? void 0;
424058
424082
  const topologyRevision = route.topologyRevision ?? "";
424059
424083
  const upsertTargetSetId = route.upsertTargetSetId ?? "";
@@ -424065,24 +424089,24 @@ function loadAppServingRouteRolloutConfig(input) {
424065
424089
  } catch {
424066
424090
  return fail30();
424067
424091
  }
424068
- if (!ENVIRONMENTS3.has(environment) || !ENVIRONMENTS3.has(configuredEnvironment)) {
424092
+ if (!ENVIRONMENTS3.has(deploymentEnvironment) || !ENVIRONMENTS3.has(configuredEnvironment)) {
424069
424093
  return fail30();
424070
424094
  }
424071
- if (configuredEnvironment !== environment) return null;
424095
+ const servingEnvironment = configuredEnvironment;
424072
424096
  if (!REFERENCE4.test(topologyRevision) || !REFERENCE4.test(upsertTargetSetId) || !REFERENCE4.test(tombstoneTargetSetId)) {
424073
424097
  return fail30();
424074
424098
  }
424075
424099
  if (allowlist3 !== "all" && !allowlist3.has(input.appId)) return null;
424076
424100
  return {
424077
424101
  activation: {
424078
- environment,
424102
+ environment: servingEnvironment,
424079
424103
  baseDomain,
424080
424104
  topologyRevision,
424081
424105
  targetSetId: upsertTargetSetId,
424082
424106
  backendRoutePrefixes: MANAGED_BACKEND_ROUTE_PREFIXES
424083
424107
  },
424084
424108
  deletion: {
424085
- environment,
424109
+ environment: servingEnvironment,
424086
424110
  baseDomain,
424087
424111
  topologyRevision,
424088
424112
  tombstoneTargetSetId
@@ -427993,10 +428017,15 @@ async function assertAppDeleteTreeMutationReady(input) {
427993
428017
  if (childRows.some((child) => child.userId !== input.ownerId)) {
427994
428018
  throw new AppDeletePreAdmissionError(input.correlationId);
427995
428019
  }
427996
- const targetNodeIds = /* @__PURE__ */ new Set([
427997
- input.app.nodeId,
427998
- ...childRows.map((child) => child.nodeId)
427999
- ]);
428020
+ const currentNodeId = input.currentNodeId?.trim() || process.env.GENCOW_NODE_ID?.trim() || null;
428021
+ const targetNodeIds = new Set(
428022
+ [input.app.nodeId ?? currentNodeId, ...childRows.map((child) => child.nodeId)].map((nodeId) => nodeId?.trim() || null).filter((nodeId) => nodeId !== null)
428023
+ );
428024
+ if (targetNodeIds.size === 0) {
428025
+ throw new PlatformMutationAdmissionError("PLATFORM_MUTATION_IDENTITY_INVALID", {
428026
+ correlationId: input.correlationId
428027
+ });
428028
+ }
428000
428029
  const assertTargetReady = input.assertTargetReadyImpl ?? assertTargetPlatformMutationReady;
428001
428030
  for (const nodeId of targetNodeIds) {
428002
428031
  await assertTargetReady({
@@ -428014,7 +428043,7 @@ async function isAppDeleteExecutorAvailable(input) {
428014
428043
  if (!input.operation.appInstanceId) return false;
428015
428044
  try {
428016
428045
  const rows4 = await input.db.select({ nodeId: apps.nodeId }).from(apps).where(and69(eq75(apps.id, input.operation.appId), eq75(apps.instanceId, input.operation.appInstanceId))).limit(1);
428017
- nodeId = rows4[0]?.nodeId?.trim() || null;
428046
+ nodeId = rows4[0]?.nodeId?.trim() || input.currentNodeId?.trim() || process.env.GENCOW_NODE_ID?.trim() || null;
428018
428047
  } catch {
428019
428048
  return false;
428020
428049
  }