@vtxmacro/cli 2026.8.16 → 2026.8.18

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/bin/vtx.js +152 -50
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -127,7 +127,7 @@ object to `vtx inference-host agent-fail --json`.
127
127
  Keep `agent-run` open in a separate terminal and keep calling `agent-next`
128
128
  while the host should remain available. The independent keeper preserves
129
129
  truthful liveness while the harness reasons. This same loop
130
- supports Main, Review, and Screener; Provider response and Decision candidate;
130
+ supports Main, Review, and Screener; Provider and Decision;
131
131
  and normally running VTX Client Mode or Server Mode bots. Server Mode keeps the
132
132
  normal VTX call fee. Client Mode has no VTX platform fee. Neither mode falls back
133
133
  to another model when the agent host is unavailable.
package/bin/vtx.js CHANGED
@@ -38,7 +38,7 @@ var init_agent_cli_release = __esm({
38
38
  "agent-cli-release.json"() {
39
39
  agent_cli_release_default = {
40
40
  package_name: "@vtxmacro/cli",
41
- package_version: "2026.8.16",
41
+ package_version: "2026.8.18",
42
42
  codex_package_name: "@openai/codex",
43
43
  codex_version: "0.147.0",
44
44
  platforms: {
@@ -17303,7 +17303,7 @@ var init_mcp_client = __esm({
17303
17303
  }
17304
17304
  if (name === "inference.job.claim") {
17305
17305
  if (result2.claim_request_id !== request.claim_request_id) invalidBoundResult(name);
17306
- if (result2.claim_state === "claimed" && (result2.host_id !== request.host_id || result2.host_generation !== request.host_generation || result2.advertisement_generation !== request.advertisement_generation || result2.key_generation !== request.key_generation)) invalidBoundResult(name);
17306
+ if (result2.claim_state === "claimed" && (result2.host_id !== request.host_id || result2.host_generation !== request.host_generation || result2.advertisement_generation > request.advertisement_generation || result2.key_generation !== request.key_generation)) invalidBoundResult(name);
17307
17307
  return;
17308
17308
  }
17309
17309
  if (name === "inference.job.start") {
@@ -17403,11 +17403,24 @@ var init_mcp_client = __esm({
17403
17403
  }).passthrough().parse(rawResult);
17404
17404
  if (callResult.isError === true) {
17405
17405
  const errorText = (callResult.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("\n");
17406
- const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.")) || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew."));
17406
+ const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.")) || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew.")) || name === "inference.host.heartbeat" && errorText.includes("Heartbeat time is outside the allowed clock skew.") || name === "inference.job.claim" && (errorText.includes(
17407
+ "External inference claim request was not applied before its generation became stale"
17408
+ ) || errorText.includes("External inference host advertisement is expired or superseded"));
17409
+ const retryableInfrastructureRejection = EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS.includes(name) && (errorText.includes("External inference polling is at its configured concurrency limit") || errorText.includes("The Insights action reached the response timeout") || errorText.includes("Insights capability failed without exposing private runtime details"));
17410
+ const retryableClaimRejection = name === "inference.job.claim" && !definitivelyNotApplied && (retryableInfrastructureRejection || errorText.includes("External inference host is not live enough to claim work") || errorText.includes("External inference host request generation is stale"));
17411
+ const retryableHeartbeatClockSkew = name === "inference.host.heartbeat" && definitivelyNotApplied;
17412
+ const retryableAdvertisementClockSkew = (name === "inference.host.register" || name === "inference.host.advertise") && definitivelyNotApplied;
17407
17413
  throw new ExternalInferenceMcpError(
17408
17414
  "tool_rejected",
17409
17415
  `Insights MCP rejected ${name}.`,
17410
- { definitivelyNotApplied }
17416
+ {
17417
+ definitivelyNotApplied,
17418
+ // Claim polling is an idempotent control-plane operation. During an
17419
+ // API rotation the MCP server can return a tool error after the
17420
+ // request reached the application boundary, so retain and replay
17421
+ // the exact request unless the server proves it was not applied.
17422
+ retryable: retryableInfrastructureRejection || retryableClaimRejection || retryableHeartbeatClockSkew || retryableAdvertisementClockSkew
17423
+ }
17411
17424
  );
17412
17425
  }
17413
17426
  const structured = inlineStructuredContentSchema.parse(callResult.structuredContent);
@@ -17515,11 +17528,13 @@ var init_mcp_client = __esm({
17515
17528
  const remoteError = external_exports.object({ code: external_exports.number().int() }).passthrough().safeParse(
17516
17529
  document2.error
17517
17530
  );
17531
+ const remoteCode = remoteError.success ? remoteError.data.code : null;
17518
17532
  throw new ExternalInferenceMcpError(
17519
17533
  "remote_error",
17520
17534
  "Insights MCP rejected the JSON-RPC request.",
17521
17535
  {
17522
- definitivelyNotApplied: remoteError.success && [-32700, -32600, -32601, -32602].includes(remoteError.data.code)
17536
+ definitivelyNotApplied: remoteCode !== null && [-32700, -32600, -32601, -32602].includes(remoteCode),
17537
+ retryable: remoteCode === -32603 || remoteCode !== null && remoteCode >= -32099 && remoteCode <= -32e3
17523
17538
  }
17524
17539
  );
17525
17540
  }
@@ -27700,7 +27715,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
27700
27715
  envelopePublicKey: options.envelopePublicKey
27701
27716
  };
27702
27717
  }
27703
- var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, DEFAULT_MAX_CONCURRENCY, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, CODEX_INFERENCE_ADVERTISED_MODEL, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
27718
+ var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, DEFAULT_MAX_CONCURRENCY, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, CODEX_INFERENCE_ADVERTISED_MODEL, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
27704
27719
  var init_runner = __esm({
27705
27720
  "lib/inference-host/runner.ts"() {
27706
27721
  "use strict";
@@ -27724,6 +27739,7 @@ var init_runner = __esm({
27724
27739
  DEFAULT_MAX_CONCURRENCY = 1;
27725
27740
  MIN_SLEEP_MS = 10;
27726
27741
  DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
27742
+ MIN_CLAIM_START_WINDOW_MS = 5e3;
27727
27743
  CODEX_INFERENCE_ADVERTISED_MODEL = Object.freeze({
27728
27744
  model_id: INITIAL_CODEX_INFERENCE_MODEL,
27729
27745
  label: "Codex GPT-5.6 Sol",
@@ -27877,7 +27893,7 @@ var init_runner = __esm({
27877
27893
  throw new Error("Inference host runtime receipt is invalid.");
27878
27894
  }
27879
27895
  const record2 = value;
27880
- if (!exactObjectKeys(record2, [
27896
+ const legacyKeys = [
27881
27897
  "schema_version",
27882
27898
  "host_id",
27883
27899
  "host_generation",
@@ -27890,10 +27906,16 @@ var init_runner = __esm({
27890
27906
  "claim_sequence",
27891
27907
  "attempts",
27892
27908
  "updated_at"
27893
- ]) || record2.schema_version !== RUNTIME_RECEIPT_SCHEMA_VERSION || typeof record2.host_id !== "string" || !record2.host_id || !safeInteger(record2.host_generation, 1) || !safeInteger(record2.key_generation, 1) || !safeInteger(record2.advertisement_generation, 1) || record2.advertisement_expires_at !== null && !validIso(record2.advertisement_expires_at) || typeof record2.registered !== "boolean" || !safeInteger(record2.host_heartbeat_sequence, 0) || !safeInteger(record2.claim_sequence, 0) || !record2.attempts || typeof record2.attempts !== "object" || Array.isArray(record2.attempts) || !validIso(record2.updated_at)) {
27909
+ ];
27910
+ const currentKeys = [...legacyKeys, "pending_claim_request"];
27911
+ if (!(exactObjectKeys(record2, legacyKeys) || exactObjectKeys(record2, currentKeys)) || record2.schema_version !== RUNTIME_RECEIPT_SCHEMA_VERSION || typeof record2.host_id !== "string" || !record2.host_id || !safeInteger(record2.host_generation, 1) || !safeInteger(record2.key_generation, 1) || !safeInteger(record2.advertisement_generation, 1) || record2.advertisement_expires_at !== null && !validIso(record2.advertisement_expires_at) || typeof record2.registered !== "boolean" || !safeInteger(record2.host_heartbeat_sequence, 0) || !safeInteger(record2.claim_sequence, 0) || !record2.attempts || typeof record2.attempts !== "object" || Array.isArray(record2.attempts) || !validIso(record2.updated_at)) {
27894
27912
  throw new Error("Inference host runtime receipt is invalid.");
27895
27913
  }
27896
27914
  const pendingAdvertisement = record2.pending_advertisement === null ? null : hostAdvertisementSchema.parse(record2.pending_advertisement);
27915
+ const pendingClaimRequest = record2.pending_claim_request == null ? null : jobClaimRequestSchema.parse(record2.pending_claim_request);
27916
+ if (pendingClaimRequest && (pendingClaimRequest.host_id !== record2.host_id || pendingClaimRequest.host_generation !== record2.host_generation || pendingClaimRequest.key_generation !== record2.key_generation || pendingClaimRequest.advertisement_generation > Number(record2.advertisement_generation))) {
27917
+ throw new Error("Inference host pending claim receipt is invalid.");
27918
+ }
27897
27919
  const attempts = Object.fromEntries(
27898
27920
  Object.entries(record2.attempts).map(([key, attempt]) => {
27899
27921
  const validated = validateAttemptReceipt(attempt);
@@ -27906,6 +27928,7 @@ var init_runner = __esm({
27906
27928
  return {
27907
27929
  ...record2,
27908
27930
  pending_advertisement: pendingAdvertisement,
27931
+ pending_claim_request: pendingClaimRequest,
27909
27932
  attempts
27910
27933
  };
27911
27934
  };
@@ -28154,7 +28177,7 @@ var init_runner = __esm({
28154
28177
  if (result2.claim_request_id !== request.claim_request_id) {
28155
28178
  runnerIdentityMismatch("Job claim");
28156
28179
  }
28157
- if (result2.claim_state === "claimed" && (result2.host_id !== request.host_id || result2.host_generation !== request.host_generation || result2.advertisement_generation !== request.advertisement_generation || result2.key_generation !== request.key_generation)) runnerIdentityMismatch("Job claim");
28180
+ if (result2.claim_state === "claimed" && (result2.host_id !== request.host_id || result2.host_generation !== request.host_generation || result2.advertisement_generation > request.advertisement_generation || result2.key_generation !== request.key_generation)) runnerIdentityMismatch("Job claim");
28158
28181
  };
28159
28182
  assertStartResult = (request, result2) => {
28160
28183
  if (result2.job_id !== request.job_id || result2.attempt_id !== request.attempt_id || result2.attempt_index !== request.attempt_index || result2.state !== "dispatch_intent") runnerIdentityMismatch("Job start");
@@ -28350,7 +28373,7 @@ var init_runner = __esm({
28350
28373
  await mcp.initialize({ signal: this.options.signal });
28351
28374
  const existingReceipt = await this.dependencies.receiptStore.read();
28352
28375
  const identityMatches = existingReceipt && existingReceipt.host_id === localState.host_id && existingReceipt.host_generation === localState.host_generation && existingReceipt.key_generation === localState.key_generation;
28353
- if (existingReceipt && !identityMatches && Object.keys(existingReceipt.attempts).length > 0) {
28376
+ if (existingReceipt && !identityMatches && (Object.keys(existingReceipt.attempts).length > 0 || existingReceipt.pending_claim_request !== null)) {
28354
28377
  throw new InferenceHostRecoveryRequiredError(
28355
28378
  "A prior attempt belongs to another host generation and must be reconciled before takeover."
28356
28379
  );
@@ -28371,6 +28394,7 @@ var init_runner = __esm({
28371
28394
  advertisement_expires_at: null,
28372
28395
  registered: false,
28373
28396
  pending_advertisement: null,
28397
+ pending_claim_request: null,
28374
28398
  host_heartbeat_sequence: 0,
28375
28399
  claim_sequence: 0,
28376
28400
  attempts: {},
@@ -28398,7 +28422,7 @@ var init_runner = __esm({
28398
28422
  return await operation();
28399
28423
  } catch (error48) {
28400
28424
  lastError = error48;
28401
- if (!retryableRemoteError(error48) || attempt === settings.remoteRetryLimit) throw error48;
28425
+ if (!retryableRemoteError(error48) || error48 instanceof ExternalInferenceMcpError && error48.definitivelyNotApplied || attempt === settings.remoteRetryLimit) throw error48;
28402
28426
  const requestedRetryDelay = remoteRetryAfterMs(
28403
28427
  error48,
28404
28428
  Math.min(250 * attempt, 1e3)
@@ -28499,7 +28523,7 @@ var init_runner = __esm({
28499
28523
  }
28500
28524
  const hostHeartbeat = async (status, requestOptions = {
28501
28525
  signal: this.options.signal
28502
- }, retryRemote = true, allowOfflineProjection = false) => {
28526
+ }, retryRemote = true, allowOfflineProjection = false, definitiveReseedAttempt = 0) => {
28503
28527
  const sequence = receipt.host_heartbeat_sequence + 1;
28504
28528
  const request = {
28505
28529
  schema_version: "external_inference_host_heartbeat_v1",
@@ -28525,7 +28549,22 @@ var init_runner = __esm({
28525
28549
  request,
28526
28550
  requestOptions
28527
28551
  );
28528
- const result2 = status === "draining" || !retryRemote ? await heartbeatOperation() : await retryExact(heartbeatOperation, requestOptions);
28552
+ let result2;
28553
+ try {
28554
+ result2 = status === "draining" || !retryRemote ? await heartbeatOperation() : await retryExact(heartbeatOperation, requestOptions);
28555
+ } catch (error48) {
28556
+ if (status !== "draining" && retryRemote && error48 instanceof ExternalInferenceMcpError && error48.definitivelyNotApplied && error48.retryable && definitiveReseedAttempt < settings.remoteRetryLimit - 1) {
28557
+ await sleep4(remoteRetryAfterMs(error48, MIN_SLEEP_MS), requestOptions.signal);
28558
+ return await hostHeartbeat(
28559
+ status,
28560
+ requestOptions,
28561
+ retryRemote,
28562
+ allowOfflineProjection,
28563
+ definitiveReseedAttempt + 1
28564
+ );
28565
+ }
28566
+ throw error48;
28567
+ }
28529
28568
  assertHostHeartbeatResult(request, result2, allowOfflineProjection);
28530
28569
  if (result2.host.status === "revoked" || result2.host.status === "offline" && !allowOfflineProjection) {
28531
28570
  const error48 = new InferenceHostRunnerError(
@@ -28540,8 +28579,9 @@ var init_runner = __esm({
28540
28579
  let nextAdvertisementAttemptAt = 0;
28541
28580
  let providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
28542
28581
  let nextClaimAt = Math.max(now(), providerRetryAtMs ?? 0);
28582
+ let pendingClaimPromotions = 0;
28543
28583
  let onceClaimed = false;
28544
- const launchClaim = (claim, recovery) => {
28584
+ const launchClaim = (claim, recovery, claimRequest) => {
28545
28585
  if (!recovery) {
28546
28586
  claimed += 1;
28547
28587
  onceClaimed = true;
@@ -28555,6 +28595,13 @@ var init_runner = __esm({
28555
28595
  ]);
28556
28596
  const controller = new AbortController();
28557
28597
  attemptControllers.set(attemptId, controller);
28598
+ let claimPromotionSettled = claimRequest === void 0;
28599
+ const settleClaimPromotion = () => {
28600
+ if (claimPromotionSettled) return;
28601
+ claimPromotionSettled = true;
28602
+ pendingClaimPromotions = Math.max(0, pendingClaimPromotions - 1);
28603
+ };
28604
+ if (claimRequest) pendingClaimPromotions += 1;
28558
28605
  const promise2 = this.executeClaim({
28559
28606
  claim,
28560
28607
  attemptId,
@@ -28582,7 +28629,9 @@ var init_runner = __esm({
28582
28629
  providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, retryAtMs);
28583
28630
  nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
28584
28631
  },
28585
- resumeReceipt: recovery
28632
+ resumeReceipt: recovery,
28633
+ claimRequest,
28634
+ onClaimPersisted: settleClaimPromotion
28586
28635
  }).then((outcome) => {
28587
28636
  if (outcome === "completed") completed += 1;
28588
28637
  else failed += 1;
@@ -28590,6 +28639,7 @@ var init_runner = __esm({
28590
28639
  failed += 1;
28591
28640
  requestDrain(controlPlaneFatal(error48) ? "authority_lost" : "attempt_terminal_unconfirmed");
28592
28641
  }).finally(() => {
28642
+ settleClaimPromotion();
28593
28643
  active.delete(attemptId);
28594
28644
  attemptControllers.delete(attemptId);
28595
28645
  });
@@ -28686,29 +28736,33 @@ var init_runner = __esm({
28686
28736
  const recovery = recoveryQueue.shift();
28687
28737
  launchClaim(recovery.claim, recovery);
28688
28738
  }
28689
- while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && active.size < settings.maxConcurrency && now() >= nextClaimAt) {
28690
- const claimSequence = receipt.claim_sequence + 1;
28691
- const request = {
28692
- schema_version: "external_inference_job_claim_v1",
28693
- contract_version: EXTERNAL_INFERENCE_CONTRACT_VERSION,
28694
- host_id: localState.host_id,
28695
- host_generation: localState.host_generation,
28696
- advertisement_generation: receipt.advertisement_generation,
28697
- key_generation: localState.key_generation,
28698
- claim_request_id: stableOperationId("claim", [
28699
- localState.host_id,
28700
- localState.host_generation,
28701
- receipt.advertisement_generation,
28702
- claimSequence
28703
- ]),
28704
- requested_at: isoAt(now())
28705
- };
28706
- receipt = {
28707
- ...receipt,
28708
- claim_sequence: claimSequence,
28709
- updated_at: isoAt(now())
28710
- };
28711
- await this.persistReceipt(receipt, now);
28739
+ while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && active.size < settings.maxConcurrency && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
28740
+ if (!receipt.pending_claim_request) {
28741
+ const claimSequence = receipt.claim_sequence + 1;
28742
+ const pendingClaimRequest = {
28743
+ schema_version: "external_inference_job_claim_v1",
28744
+ contract_version: EXTERNAL_INFERENCE_CONTRACT_VERSION,
28745
+ host_id: localState.host_id,
28746
+ host_generation: localState.host_generation,
28747
+ advertisement_generation: receipt.advertisement_generation,
28748
+ key_generation: localState.key_generation,
28749
+ claim_request_id: stableOperationId("claim", [
28750
+ localState.host_id,
28751
+ localState.host_generation,
28752
+ receipt.advertisement_generation,
28753
+ claimSequence
28754
+ ]),
28755
+ requested_at: isoAt(now())
28756
+ };
28757
+ receipt = {
28758
+ ...receipt,
28759
+ claim_sequence: claimSequence,
28760
+ pending_claim_request: pendingClaimRequest,
28761
+ updated_at: isoAt(now())
28762
+ };
28763
+ await this.persistReceipt(receipt, now);
28764
+ }
28765
+ const request = receipt.pending_claim_request;
28712
28766
  let claim;
28713
28767
  try {
28714
28768
  claim = await mcp.callTool(
@@ -28720,6 +28774,18 @@ var init_runner = __esm({
28720
28774
  } catch (error48) {
28721
28775
  if (!this.options.signal?.aborted && controlPlaneFatal(error48)) {
28722
28776
  requestDrain("authority_lost");
28777
+ } else if (!this.options.signal?.aborted && error48 instanceof ExternalInferenceMcpError && error48.definitivelyNotApplied) {
28778
+ if (request.advertisement_generation < receipt.advertisement_generation) {
28779
+ receipt = {
28780
+ ...receipt,
28781
+ pending_claim_request: null,
28782
+ updated_at: isoAt(now())
28783
+ };
28784
+ await this.persistReceipt(receipt, now);
28785
+ nextClaimAt = now();
28786
+ } else {
28787
+ requestDrain("claim_failed");
28788
+ }
28723
28789
  } else if (!this.options.signal?.aborted && retryableRemoteError(error48)) {
28724
28790
  nextClaimAt = now() + remoteRetryAfterMs(error48, 1e3);
28725
28791
  } else if (!this.options.signal?.aborted) {
@@ -28728,11 +28794,27 @@ var init_runner = __esm({
28728
28794
  break;
28729
28795
  }
28730
28796
  if (claim.claim_state === "empty") {
28797
+ receipt = {
28798
+ ...receipt,
28799
+ pending_claim_request: null,
28800
+ updated_at: isoAt(now())
28801
+ };
28802
+ await this.persistReceipt(receipt, now);
28731
28803
  nextClaimAt = now() + Math.max(MIN_SLEEP_MS, claim.retry_after_ms);
28732
28804
  if (this.options.once) requestDrain("once_empty");
28733
28805
  break;
28734
28806
  }
28735
- launchClaim(claim);
28807
+ if (Date.parse(claim.lease_expires_at) <= now() + MIN_CLAIM_START_WINDOW_MS || Date.parse(claim.deadline_at) <= now() + MIN_CLAIM_START_WINDOW_MS) {
28808
+ receipt = {
28809
+ ...receipt,
28810
+ pending_claim_request: null,
28811
+ updated_at: isoAt(now())
28812
+ };
28813
+ await this.persistReceipt(receipt, now);
28814
+ nextClaimAt = now();
28815
+ break;
28816
+ }
28817
+ launchClaim(claim, void 0, request);
28736
28818
  if (this.options.once) requestDrain("once_complete");
28737
28819
  }
28738
28820
  if (drainRequested) break;
@@ -28805,7 +28887,7 @@ var init_runner = __esm({
28805
28887
  const sealCandidate = this.dependencies.sealCandidate ?? sealExternalInferenceCandidate;
28806
28888
  const validateOutput = this.dependencies.validateOutput ?? defaultValidateOutput;
28807
28889
  const activeReceipt = options.receipt();
28808
- if (claim.host_id !== localState.host_id || claim.host_generation !== localState.host_generation || (options.resumeReceipt ? claim.advertisement_generation > activeReceipt.advertisement_generation : claim.advertisement_generation !== activeReceipt.advertisement_generation) || claim.key_generation !== localState.key_generation) {
28890
+ if (claim.host_id !== localState.host_id || claim.host_generation !== localState.host_generation || (options.resumeReceipt || options.claimRequest ? claim.advertisement_generation > activeReceipt.advertisement_generation : claim.advertisement_generation !== activeReceipt.advertisement_generation) || claim.key_generation !== localState.key_generation) {
28809
28891
  throw new InferenceHostRunnerError(
28810
28892
  "claim_generation_mismatch",
28811
28893
  "The claimed job crossed the active host generation fence."
@@ -28839,11 +28921,15 @@ var init_runner = __esm({
28839
28921
  );
28840
28922
  }
28841
28923
  if (!options.resumeReceipt) {
28924
+ const currentReceipt = options.receipt();
28925
+ const pendingClaimRequest = options.claimRequest && currentReceipt.pending_claim_request?.claim_request_id === options.claimRequest.claim_request_id ? null : currentReceipt.pending_claim_request ?? null;
28842
28926
  await options.updateReceipt({
28843
- ...options.receipt(),
28844
- attempts: { ...options.receipt().attempts, [attemptId]: attemptReceipt },
28927
+ ...currentReceipt,
28928
+ pending_claim_request: pendingClaimRequest,
28929
+ attempts: { ...currentReceipt.attempts, [attemptId]: attemptReceipt },
28845
28930
  updated_at: isoAt(now())
28846
28931
  });
28932
+ options.onClaimPersisted?.();
28847
28933
  }
28848
28934
  const updateAttempt = async (changes) => {
28849
28935
  attemptReceipt = validateAttemptReceipt({
@@ -28867,12 +28953,28 @@ var init_runner = __esm({
28867
28953
  });
28868
28954
  };
28869
28955
  if (attemptReceipt.phase === "claimed") {
28870
- const attemptDeadlineAtMs = Date.parse(claim.deadline_at);
28871
- const startResult = await retryExact(() => mcp.callTool(
28872
- "inference.job.start",
28873
- startRequest,
28874
- { signal, deadlineAtMs: attemptDeadlineAtMs }
28875
- ), { signal, deadlineAtMs: attemptDeadlineAtMs });
28956
+ const attemptDeadlineAtMs = Math.min(
28957
+ Date.parse(claim.deadline_at),
28958
+ Date.parse(claim.lease_expires_at)
28959
+ );
28960
+ if (attemptDeadlineAtMs <= now() + MIN_CLAIM_START_WINDOW_MS) {
28961
+ await removeAttempt();
28962
+ return "failed";
28963
+ }
28964
+ let startResult;
28965
+ try {
28966
+ startResult = await retryExact(() => mcp.callTool(
28967
+ "inference.job.start",
28968
+ startRequest,
28969
+ { signal, deadlineAtMs: attemptDeadlineAtMs }
28970
+ ), { signal, deadlineAtMs: attemptDeadlineAtMs });
28971
+ } catch (error48) {
28972
+ if (attemptDeadlineAtMs <= now() + MIN_CLAIM_START_WINDOW_MS) {
28973
+ await removeAttempt();
28974
+ return "failed";
28975
+ }
28976
+ throw error48;
28977
+ }
28876
28978
  assertStartResult(startRequest, startResult);
28877
28979
  await updateAttempt({ phase: "started" });
28878
28980
  }
@@ -29582,7 +29684,7 @@ private-file fallback. See https://vtxmacro.com/insights#subscription-inference.
29582
29684
  const receipt = await new FileInferenceHostRuntimeReceiptStore(
29583
29685
  runtimeReceiptPath(config2)
29584
29686
  ).read();
29585
- const pendingAttempts = receipt ? Object.keys(receipt.attempts).length : 0;
29687
+ const pendingAttempts = receipt ? Object.keys(receipt.attempts).length + (receipt.pending_claim_request ? 1 : 0) : 0;
29586
29688
  const codexRecoveryPresent = await fileExistsPrivately(
29587
29689
  codexRecoveryPath(config2),
29588
29690
  "Codex attempt recovery file"
@@ -29873,7 +29975,7 @@ Waiting for approval...
29873
29975
  runtime: receipt ? {
29874
29976
  registered: receipt.registered,
29875
29977
  advertisement_generation: receipt.advertisement_generation,
29876
- pending_attempts: Object.keys(receipt.attempts).length,
29978
+ pending_attempts: Object.keys(receipt.attempts).length + (receipt.pending_claim_request ? 1 : 0),
29877
29979
  updated_at: receipt.updated_at
29878
29980
  } : null,
29879
29981
  agent_attempt: agentAttempt ? {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.16",
3
+ "version": "2026.8.18",
4
4
  "description": "VTX Macro CLI, MCP server, and foreground subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",