@vtxmacro/cli 2026.10.8 → 2026.10.9

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/bin/vtx.js CHANGED
@@ -113,7 +113,7 @@ var init_routing = __esm({
113
113
  var agent_cli_release_default;
114
114
  var init_agent_cli_release = __esm({
115
115
  "agent-cli-release.json"() {
116
- agent_cli_release_default = { package_name: "@vtxmacro/cli", package_version: "2026.10.8", codex_package_name: "@openai/codex", codex_version: "0.155.0", copilot_sdk_package_name: "@github/copilot-sdk", copilot_sdk_version: "1.0.0-beta.8", copilot_cli_package_name: "@github/copilot", copilot_cli_version: "1.0.80", deepseek_harness_version: "0.1.1-rc.2", deepseek_harness_packages: ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-loop", "@deepseek-ai/dsh-agent-spine-demo", "@deepseek-ai/dsh-anonymous-user-id", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-brand", "@deepseek-ai/dsh-code-runtime", "@deepseek-ai/dsh-credentials", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-goal", "@deepseek-ai/dsh-goal-round-driver", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-jobs", "@deepseek-ai/dsh-jobs-local", "@deepseek-ai/dsh-launch-environment", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-deepseek", "@deepseek-ai/dsh-llm-retry", "@deepseek-ai/dsh-output-retention", "@deepseek-ai/dsh-sandbox", "@deepseek-ai/dsh-sandbox-policy", "@deepseek-ai/dsh-scope", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-session-checkpoint-policy", "@deepseek-ai/dsh-session-persistence", "@deepseek-ai/dsh-session-persistence-jsonl", "@deepseek-ai/dsh-session-projection", "@deepseek-ai/dsh-session-title", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-shell", "@deepseek-ai/dsh-shell-env", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-skill-filesystem", "@deepseek-ai/dsh-subprocess", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-timeout", "@deepseek-ai/dsh-tool-bash", "@deepseek-ai/dsh-tool-goal", "@deepseek-ai/dsh-tool-jobs", "@deepseek-ai/dsh-tool-skill", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-typert-protocol", "@deepseek-ai/dsh-user-approval"], deepseek_cordis_package_name: "@deepseek-ai/cordis", deepseek_cordis_version: "4.0.1", deepseek_support_packages: { "@deepseek-ai/cordis-plugin-timer": "1.1.3" }, platforms: { "linux-x64": { package_name: "@openai/codex-linux-x64", target: "x86_64-unknown-linux-musl", binary_name: "codex", sha256: "660e159a49e823ac8e5986cb238f73158ce4b957d40d9292f8de90862644b501" }, "win32-x64": { package_name: "@openai/codex-win32-x64", target: "x86_64-pc-windows-msvc", binary_name: "codex.exe", sha256: "e4c11374bd9de8ad5c3b7617fd4654bb7839901edb0863f9930666863c7a021b" } }, pi_coding_agent_package_name: "@earendil-works/pi-coding-agent", pi_ai_package_name: "@earendil-works/pi-ai", pi_version: "0.85.1", pi_support_packages: ["@earendil-works/pi-agent-core", "@earendil-works/pi-telemetry", "@earendil-works/pi-tui", "@earendil-works/chord"], grok_version: "1.0.30", grok_platforms: { "linux-x64": { package_name: "@xai-official/grok-linux-x64", binary_name: "grok", sha256: "504dd6546ab991b75d36698242875ce461489cd1f8cd84285873cb55bd5c7d54" }, "win32-x64": { package_name: "@xai-official/grok-win32-x64", binary_name: "grok.exe", sha256: "48736d1a4342a801ea26d0ecde4c516b653f791399065adaa55973f83abd8867" } } };
116
+ agent_cli_release_default = { package_name: "@vtxmacro/cli", package_version: "2026.10.9", codex_package_name: "@openai/codex", codex_version: "0.155.0", copilot_sdk_package_name: "@github/copilot-sdk", copilot_sdk_version: "1.0.0-beta.8", copilot_cli_package_name: "@github/copilot", copilot_cli_version: "1.0.80", deepseek_harness_version: "0.1.1-rc.2", deepseek_harness_packages: ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-loop", "@deepseek-ai/dsh-agent-spine-demo", "@deepseek-ai/dsh-anonymous-user-id", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-brand", "@deepseek-ai/dsh-code-runtime", "@deepseek-ai/dsh-credentials", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-goal", "@deepseek-ai/dsh-goal-round-driver", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-jobs", "@deepseek-ai/dsh-jobs-local", "@deepseek-ai/dsh-launch-environment", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-deepseek", "@deepseek-ai/dsh-llm-retry", "@deepseek-ai/dsh-output-retention", "@deepseek-ai/dsh-sandbox", "@deepseek-ai/dsh-sandbox-policy", "@deepseek-ai/dsh-scope", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-session-checkpoint-policy", "@deepseek-ai/dsh-session-persistence", "@deepseek-ai/dsh-session-persistence-jsonl", "@deepseek-ai/dsh-session-projection", "@deepseek-ai/dsh-session-title", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-shell", "@deepseek-ai/dsh-shell-env", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-skill-filesystem", "@deepseek-ai/dsh-subprocess", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-timeout", "@deepseek-ai/dsh-tool-bash", "@deepseek-ai/dsh-tool-goal", "@deepseek-ai/dsh-tool-jobs", "@deepseek-ai/dsh-tool-skill", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-typert-protocol", "@deepseek-ai/dsh-user-approval"], deepseek_cordis_package_name: "@deepseek-ai/cordis", deepseek_cordis_version: "4.0.1", deepseek_support_packages: { "@deepseek-ai/cordis-plugin-timer": "1.1.3" }, platforms: { "linux-x64": { package_name: "@openai/codex-linux-x64", target: "x86_64-unknown-linux-musl", binary_name: "codex", sha256: "660e159a49e823ac8e5986cb238f73158ce4b957d40d9292f8de90862644b501" }, "win32-x64": { package_name: "@openai/codex-win32-x64", target: "x86_64-pc-windows-msvc", binary_name: "codex.exe", sha256: "e4c11374bd9de8ad5c3b7617fd4654bb7839901edb0863f9930666863c7a021b" } }, pi_coding_agent_package_name: "@earendil-works/pi-coding-agent", pi_ai_package_name: "@earendil-works/pi-ai", pi_version: "0.85.1", pi_support_packages: ["@earendil-works/pi-agent-core", "@earendil-works/pi-telemetry", "@earendil-works/pi-tui", "@earendil-works/chord"], grok_version: "1.0.30", grok_platforms: { "linux-x64": { package_name: "@xai-official/grok-linux-x64", binary_name: "grok", sha256: "504dd6546ab991b75d36698242875ce461489cd1f8cd84285873cb55bd5c7d54" }, "win32-x64": { package_name: "@xai-official/grok-win32-x64", binary_name: "grok.exe", sha256: "48736d1a4342a801ea26d0ecde4c516b653f791399065adaa55973f83abd8867" } } };
117
117
  }
118
118
  });
119
119
 
@@ -216,6 +216,10 @@ var init_runtime_policy_generated = __esm({
216
216
  protective_plan_set_lock: {
217
217
  wait_seconds: 120
218
218
  },
219
+ execution_mutation_queue: {
220
+ wait_seconds: 120,
221
+ trade_submit_deadline_seconds: 360
222
+ },
219
223
  history_evidence: {
220
224
  device_rounds_per_beat: 6,
221
225
  device_retry_seconds: 60
@@ -22192,6 +22196,10 @@ var init_runtime_policy_generated2 = __esm({
22192
22196
  protective_plan_set_lock: {
22193
22197
  wait_seconds: 120
22194
22198
  },
22199
+ execution_mutation_queue: {
22200
+ wait_seconds: 120,
22201
+ trade_submit_deadline_seconds: 360
22202
+ },
22195
22203
  history_evidence: {
22196
22204
  device_rounds_per_beat: 6,
22197
22205
  device_retry_seconds: 60
@@ -85520,7 +85528,8 @@ var init_hyperliquid_client = __esm({
85520
85528
  isTrigger,
85521
85529
  triggerKind,
85522
85530
  triggerPrice,
85523
- isPositionTpsl
85531
+ isPositionTpsl,
85532
+ statusTimestampMs: timestamp
85524
85533
  };
85525
85534
  };
85526
85535
  fetchBrowserOrderStatusEvidence = async (input) => {
@@ -86402,6 +86411,7 @@ var init_hyperliquid_client = __esm({
86402
86411
  return signedAssetId;
86403
86412
  };
86404
86413
  exchangeRejectionReason = (message) => {
86414
+ if (/never placed|already cancel+ed|already filled|or filled/i.test(message)) return "order_not_open";
86405
86415
  if (/insufficient.*margin|margin.*insufficient/i.test(message)) return "insufficient_margin";
86406
86416
  if (/reduce.?only/i.test(message)) return "reduce_only";
86407
86417
  if (/minimum.*(?:value|notional)|(?:value|notional).*minimum|at least.*\$10/i.test(message)) return "minimum_notional";
@@ -86437,6 +86447,8 @@ var init_hyperliquid_client = __esm({
86437
86447
  let exchangeDispatched = false;
86438
86448
  let recoveryPermit = null;
86439
86449
  let settlementAttempted = false;
86450
+ let pinnedAuthority = null;
86451
+ let begunMutation = null;
86440
86452
  assertFreshPreparedExecutionContext(input.preparedContext);
86441
86453
  const captureTimeoutMs = Number(
86442
86454
  input.config?.client_runtime_execution_observability?.capture_timeout_ms
@@ -86458,9 +86470,14 @@ var init_hyperliquid_client = __esm({
86458
86470
  input,
86459
86471
  executionObservabilityDeadlineMs
86460
86472
  );
86473
+ pinnedAuthority = pinClientExchangeMutationAuthority(
86474
+ durableMutation.profileId,
86475
+ ...durableMutationAuthorityArgs(durableMutation)
86476
+ );
86461
86477
  const beginResult = await beginClientRuntimeExchangeMutation(
86462
86478
  durableMutation.profileId,
86463
86479
  {
86480
+ ...pinnedAuthority ? { pinnedAuthority } : {},
86464
86481
  mutationId: durableMutation.mutationId,
86465
86482
  operationKind: durableMutation.operationKind,
86466
86483
  symbol: durableMutation.symbol,
@@ -86486,6 +86503,7 @@ var init_hyperliquid_client = __esm({
86486
86503
  },
86487
86504
  ...durableMutationAuthorityArgs(durableMutation)
86488
86505
  );
86506
+ begunMutation = beginResult;
86489
86507
  if (beginResult.dispatch_authorized !== true) {
86490
86508
  throw new RuntimeExecutionError(
86491
86509
  "This exchange mutation was already recorded and will not be dispatched again. Durable reconciliation is required before retrying.",
@@ -86503,6 +86521,7 @@ var init_hyperliquid_client = __esm({
86503
86521
  durableMutation.profileId,
86504
86522
  durableMutation.mutationId,
86505
86523
  {
86524
+ ...pinnedAuthority ? { pinnedAuthority } : {},
86506
86525
  outcome,
86507
86526
  ...dispatchDiagnostics ? { dispatchDiagnostics } : {},
86508
86527
  ...outcome === "success" ? { requireExactSuccessSettlement: true } : {},
@@ -86517,11 +86536,11 @@ var init_hyperliquid_client = __esm({
86517
86536
  } catch {
86518
86537
  }
86519
86538
  return settled;
86520
- } catch {
86521
- throw new RuntimeExecutionError(
86539
+ } catch (settlementCause) {
86540
+ throw Object.assign(new RuntimeExecutionError(
86522
86541
  "Exchange submission may have completed; durable reconciliation is pending.",
86523
86542
  "outcome_unknown"
86524
- );
86543
+ ), { settlementCause });
86525
86544
  }
86526
86545
  };
86527
86546
  const settleDefinitiveSuccess = async (exchangeOrderId, orderMemberResults) => {
@@ -86543,6 +86562,17 @@ var init_hyperliquid_client = __esm({
86543
86562
  if (input.signal?.aborted) {
86544
86563
  throw input.signal.reason instanceof Error ? input.signal.reason : settlementError;
86545
86564
  }
86565
+ if (isClientExchangeMutationAuthorityConflict(
86566
+ settlementError.settlementCause
86567
+ )) {
86568
+ if (begunMutation != null && pinnedAuthority != null) {
86569
+ handOffClientExchangeMutationToReconciliation(begunMutation, pinnedAuthority);
86570
+ }
86571
+ throw new RuntimeExecutionError(
86572
+ "Exchange submission may have completed; durable reconciliation is pending.",
86573
+ "outcome_unknown"
86574
+ );
86575
+ }
86546
86576
  await new Promise((resolve14) => {
86547
86577
  let settled = false;
86548
86578
  const finish = () => {
@@ -86576,7 +86606,8 @@ var init_hyperliquid_client = __esm({
86576
86606
  durableMutation.mutationId,
86577
86607
  {
86578
86608
  phase: "send_started",
86579
- clientObservedAt: (/* @__PURE__ */ new Date()).toISOString()
86609
+ clientObservedAt: (/* @__PURE__ */ new Date()).toISOString(),
86610
+ ...pinnedAuthority ? { pinnedAuthority } : {}
86580
86611
  },
86581
86612
  captureController.signal,
86582
86613
  ...durableMutationAuthorityArgs(durableMutation)
@@ -87453,7 +87484,7 @@ async function handOffClientRuntimeSession(profileId, payload, options) {
87453
87484
  );
87454
87485
  }
87455
87486
  async function beginClientRuntimeExchangeMutation(profileId, payload, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId) {
87456
- const authority = resolveClientExchangeMutationAuthority(
87487
+ const authority = payload.pinnedAuthority ?? resolveClientExchangeMutationAuthority(
87457
87488
  profileId,
87458
87489
  requiredRuntimeSessionId,
87459
87490
  explicitRuntimeLeaseToken,
@@ -87744,7 +87775,7 @@ async function checkServerHostExecutionCapacity(profileId, plans, signal, requir
87744
87775
  return answer.results;
87745
87776
  }
87746
87777
  async function reportClientRuntimeExchangeAttemptTransition(profileId, mutationId, payload, signal, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId) {
87747
- const authority = resolveClientExchangeMutationAuthority(
87778
+ const authority = payload.pinnedAuthority ?? resolveClientExchangeMutationAuthority(
87748
87779
  profileId,
87749
87780
  requiredRuntimeSessionId,
87750
87781
  explicitRuntimeLeaseToken,
@@ -87766,7 +87797,7 @@ async function reportClientRuntimeExchangeAttemptTransition(profileId, mutationI
87766
87797
  );
87767
87798
  }
87768
87799
  async function settleClientRuntimeExchangeMutation(profileId, mutationId, payload, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId) {
87769
- const authority = resolveClientExchangeMutationAuthority(
87800
+ const authority = payload.pinnedAuthority ?? resolveClientExchangeMutationAuthority(
87770
87801
  profileId,
87771
87802
  requiredRuntimeSessionId,
87772
87803
  explicitRuntimeLeaseToken,
@@ -88323,7 +88354,7 @@ async function fetchClientRuntimeKillswitchContext(profileId, payload, options)
88323
88354
  options
88324
88355
  );
88325
88356
  }
88326
- var clientRuntimeSecretHeaders, preferencesWriteQueue, getCopyTradingRuntimeLeaseToken, getCopyTradingSchedulerInstanceId, resolveClientRuntimeStatusViewerHeaders, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, CLIENT_PROTECTION_CAPABILITY_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, consumeCompletedDeferredClientRuntimeStop, toNumericProfileId, buildClientRuntimeBody, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, attachRuntimeSchedulerInstanceHeader, resolveRuntimeLeaseToken, resolveSchedulerBoundRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, isRuntimeIdempotencyInProgressError, isRetryableRuntimeConflictError, resolveClientRuntimeRetryDelayMs, reconcilePendingClientExchangeMutation, CLIENT_RUNTIME_CLAIM_EXCHANGE_MUTATION_WAIT_CODES, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, isMissingActiveClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, completeClientExchangeMutationReconciliation, protectiveBoundClientExchangeMutations, rememberProtectiveBoundClientExchangeMutation, isProtectiveBoundClientExchangeMutation, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
88357
+ var clientRuntimeSecretHeaders, preferencesWriteQueue, getCopyTradingRuntimeLeaseToken, getCopyTradingSchedulerInstanceId, resolveClientRuntimeStatusViewerHeaders, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, CLIENT_PROTECTION_CAPABILITY_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, consumeCompletedDeferredClientRuntimeStop, toNumericProfileId, buildClientRuntimeBody, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, attachRuntimeSchedulerInstanceHeader, resolveRuntimeLeaseToken, resolveSchedulerBoundRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, isRuntimeIdempotencyInProgressError, isRetryableRuntimeConflictError, resolveClientRuntimeRetryDelayMs, reconcilePendingClientExchangeMutation, CLIENT_RUNTIME_CLAIM_EXCHANGE_MUTATION_WAIT_CODES, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, pinClientExchangeMutationAuthority, CLIENT_EXCHANGE_MUTATION_AUTHORITY_MISMATCH, isClientExchangeMutationAuthorityConflict, handOffClientExchangeMutationToReconciliation, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, isMissingActiveClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, completeClientExchangeMutationReconciliation, protectiveBoundClientExchangeMutations, rememberProtectiveBoundClientExchangeMutation, isProtectiveBoundClientExchangeMutation, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
88327
88358
  var init_api2 = __esm({
88328
88359
  "lib/api.ts"() {
88329
88360
  "use strict";
@@ -88808,6 +88839,25 @@ var init_api2 = __esm({
88808
88839
  }
88809
88840
  };
88810
88841
  };
88842
+ pinClientExchangeMutationAuthority = (profileId, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId) => resolveClientExchangeMutationAuthority(
88843
+ profileId,
88844
+ requiredRuntimeSessionId,
88845
+ explicitRuntimeLeaseToken,
88846
+ explicitRuntimeDeviceId,
88847
+ explicitSchedulerInstanceId
88848
+ );
88849
+ CLIENT_EXCHANGE_MUTATION_AUTHORITY_MISMATCH = "exchange_mutation_authority_mismatch";
88850
+ isClientExchangeMutationAuthorityConflict = (error48) => {
88851
+ const candidate = error48;
88852
+ if (Number(candidate?.status) !== 409) return false;
88853
+ if (candidate?.code === CLIENT_EXCHANGE_MUTATION_AUTHORITY_MISMATCH) return true;
88854
+ return /does not own this exchange mutation/i.test(String(candidate?.message ?? ""));
88855
+ };
88856
+ handOffClientExchangeMutationToReconciliation = (mutation, authority) => scheduleClientExchangeMutationReconciliation(
88857
+ authority.numericProfileId,
88858
+ mutation,
88859
+ authority.requestOptions
88860
+ );
88811
88861
  clientExchangeMutationAuthorityBody = (authority) => {
88812
88862
  const schedulerInstanceId = String(authority.requestOptions.schedulerInstanceId ?? "").trim();
88813
88863
  return {
@@ -93033,8 +93083,150 @@ var init_protective_trigger_price = __esm({
93033
93083
  }
93034
93084
  });
93035
93085
 
93086
+ // lib/runtime/protective-stop-replacement.ts
93087
+ var STOP_REPLACED, STOP_REPLACEMENT_EXHAUSTED, STOP_REPLACEMENT_REJECTED, STOP_REPLACEMENT_NOT_LANDED, STOP_CLEANUP_IN_FLIGHT, TERMINAL_WITHOUT_FILL, CANCELLED_BY_USER, POSITION_FLAT_AFTER_TERMINAL, CAPACITY_ALREADY_ALLOCATED, TRIGGER_INVALID, POSITION_ENDED_ORDER_STATUSES, finiteOrNull, floorToLot, positiveSafeInteger, decimalOrNull, positionTolerance, protectivePositionEpisodeEnded, decideProtectiveStopReplacement;
93088
+ var init_protective_stop_replacement = __esm({
93089
+ "lib/runtime/protective-stop-replacement.ts"() {
93090
+ "use strict";
93091
+ init_define_VTX_EXO_POLICY();
93092
+ init_define_VTX_GROK_POLICY();
93093
+ init_define_VTX_PI_MODEL_POLICY();
93094
+ init_hyperliquid_market_symbol();
93095
+ STOP_REPLACED = "protective_stop_replaced";
93096
+ STOP_REPLACEMENT_EXHAUSTED = "protective_stop_replacement_exhausted";
93097
+ STOP_REPLACEMENT_REJECTED = "protective_stop_replacement_rejected";
93098
+ STOP_REPLACEMENT_NOT_LANDED = "protective_stop_replacement_not_landed";
93099
+ STOP_CLEANUP_IN_FLIGHT = "protective_stop_cleanup_in_flight";
93100
+ TERMINAL_WITHOUT_FILL = "protective_order_terminal_without_fill";
93101
+ CANCELLED_BY_USER = "protective_order_cancelled_by_user";
93102
+ POSITION_FLAT_AFTER_TERMINAL = "position_flat_after_protective_terminal";
93103
+ CAPACITY_ALREADY_ALLOCATED = "protective_capacity_already_allocated";
93104
+ TRIGGER_INVALID = "protective_trigger_invalid";
93105
+ POSITION_ENDED_ORDER_STATUSES = /* @__PURE__ */ new Set([
93106
+ "reduceOnlyCanceled",
93107
+ "liquidatedCanceled"
93108
+ ]);
93109
+ finiteOrNull = (value) => {
93110
+ if (value == null || typeof value === "boolean" || value === "") return null;
93111
+ const parsed = Number(value);
93112
+ return Number.isFinite(parsed) ? parsed : null;
93113
+ };
93114
+ floorToLot = (value, sizeDecimals) => {
93115
+ const scale = 10 ** sizeDecimals;
93116
+ const lots = Math.floor(Number((value * scale).toFixed(6)));
93117
+ return Number((lots / scale).toFixed(sizeDecimals));
93118
+ };
93119
+ positiveSafeInteger = (value) => typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : null;
93120
+ decimalOrNull = (value) => {
93121
+ if (typeof value === "string" && /^-?\d+(?:\.\d+)?$/.test(value.trim())) return Number(value);
93122
+ if (typeof value === "number" && Number.isFinite(value)) return value;
93123
+ return null;
93124
+ };
93125
+ positionTolerance = (left, right) => Math.max(1e-10, Math.max(Math.abs(left), Math.abs(right)) * 1e-8);
93126
+ protectivePositionEpisodeEnded = (input) => {
93127
+ if (!POSITION_ENDED_ORDER_STATUSES.has(String(input.orderStatus ?? ""))) return false;
93128
+ const statusMs = positiveSafeInteger(input.statusTimestampMs);
93129
+ if (statusMs == null || !Array.isArray(input.fills)) return false;
93130
+ const market = normalizeHyperliquidMarketSymbol(input.symbol);
93131
+ const sign = input.isLong ? 1 : -1;
93132
+ const rows = [];
93133
+ const seen = /* @__PURE__ */ new Set();
93134
+ for (const fill of input.fills) {
93135
+ if (fill == null || typeof fill !== "object" || Array.isArray(fill)) return false;
93136
+ const record5 = fill;
93137
+ if (normalizeHyperliquidMarketSymbol(String(record5.coin ?? "")) !== market) continue;
93138
+ const tradeId = positiveSafeInteger(record5.tid);
93139
+ const time3 = positiveSafeInteger(record5.time);
93140
+ const size = decimalOrNull(record5.sz);
93141
+ const start = decimalOrNull(record5.startPosition);
93142
+ if (tradeId == null || seen.has(tradeId) || time3 == null || record5.side !== "B" && record5.side !== "A" || size == null || size <= 0 || start == null) {
93143
+ return false;
93144
+ }
93145
+ seen.add(tradeId);
93146
+ rows.push({ time: time3, tradeId, start, end: start + (record5.side === "B" ? size : -size) });
93147
+ }
93148
+ rows.sort((left, right) => left.time - right.time || left.tradeId - right.tradeId);
93149
+ for (let index = 1; index < rows.length; index += 1) {
93150
+ const previous = rows[index - 1];
93151
+ const current = rows[index];
93152
+ if (Math.abs(previous.end - current.start) > positionTolerance(previous.end, current.start)) return false;
93153
+ }
93154
+ const before = rows.filter((row) => row.time <= statusMs);
93155
+ const after = rows.filter((row) => row.time > statusMs);
93156
+ const last = before[before.length - 1];
93157
+ if (last == null || sign * last.end > positionTolerance(last.end, 0)) return false;
93158
+ return after.some((row) => sign * row.end > positionTolerance(row.end, 0));
93159
+ };
93160
+ decideProtectiveStopReplacement = (input) => {
93161
+ if (input.botCleanupInFlight) {
93162
+ return { outcome: "defer", reasonCode: STOP_CLEANUP_IN_FLIGHT };
93163
+ }
93164
+ if (input.cancelledByUser) {
93165
+ return { outcome: "not_required", reasonCode: CANCELLED_BY_USER };
93166
+ }
93167
+ const position = finiteOrNull(input.positionSize);
93168
+ if (position == null) {
93169
+ throw new Error("The live position size is required.");
93170
+ }
93171
+ if (position === 0) {
93172
+ return { outcome: "not_required", reasonCode: POSITION_FLAT_AFTER_TERMINAL };
93173
+ }
93174
+ if (input.positionEpisodeEnded && position > 0 === input.isLong) {
93175
+ return { outcome: "not_required", reasonCode: POSITION_FLAT_AFTER_TERMINAL };
93176
+ }
93177
+ if (position > 0 !== input.isLong || input.legKind !== "stop_loss") {
93178
+ return { outcome: "manual_intervention", reasonCode: TERMINAL_WITHOUT_FILL };
93179
+ }
93180
+ if (input.alreadyReplaced) {
93181
+ return { outcome: "manual_intervention", reasonCode: STOP_REPLACEMENT_EXHAUSTED };
93182
+ }
93183
+ const trigger = finiteOrNull(input.triggerPrice);
93184
+ const size = finiteOrNull(input.legSize);
93185
+ if (trigger == null || trigger <= 0 || size == null || size <= 0) {
93186
+ return { outcome: "manual_intervention", reasonCode: TRIGGER_INVALID };
93187
+ }
93188
+ const covered = (finiteOrNull(input.otherLiveStopSize) ?? 0) + (finiteOrNull(input.inFlightStopSize) ?? 0);
93189
+ const uncovered = Math.min(size, Math.max(0, Math.abs(position) - covered));
93190
+ const planned = floorToLot(uncovered, input.sizeDecimals);
93191
+ if (!(planned > 0)) {
93192
+ return { outcome: "not_required", reasonCode: CAPACITY_ALREADY_ALLOCATED };
93193
+ }
93194
+ return { outcome: "replace", reasonCode: STOP_REPLACED, size: planned, triggerPrice: trigger };
93195
+ };
93196
+ }
93197
+ });
93198
+
93036
93199
  // lib/runtime/runtime-execution.ts
93037
- var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, withClientExecutionMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, executeClientCopyTradingOrderAction;
93200
+ function capCopiedToActual(copied, actual) {
93201
+ if (Math.abs(copied) <= 1e-12) return 0;
93202
+ if (copied * actual <= 0) return 0;
93203
+ return Math.abs(copied) > Math.abs(actual) ? actual : copied;
93204
+ }
93205
+ function adjustCopiedTarget(target, longRemovedSince, shortRemovedSince) {
93206
+ if (target > 1e-12) return Math.max(0, target - Math.max(0, longRemovedSince));
93207
+ if (target < -1e-12) return Math.min(0, target + Math.max(0, shortRemovedSince));
93208
+ return 0;
93209
+ }
93210
+ function removedByCap(copied, capped) {
93211
+ if (copied > 0) return [Math.max(0, copied - Math.max(0, capped)), 0];
93212
+ if (copied < 0) return [0, Math.max(0, Math.min(0, capped) - copied)];
93213
+ return [0, 0];
93214
+ }
93215
+ function positionSpaceCopyTarget(reconciliation, recordedTarget, actualPosition) {
93216
+ if (!reconciliation || reconciliation.target_space !== "copied") return recordedTarget;
93217
+ const copiedServer = Number(reconciliation.copied_now ?? 0) || 0;
93218
+ const copiedNow = capCopiedToActual(copiedServer, actualPosition);
93219
+ const [deviceLongRemoved, deviceShortRemoved] = removedByCap(copiedServer, copiedNow);
93220
+ const longRemovedNow = (Number(reconciliation.external_long_removed_now ?? 0) || 0) + deviceLongRemoved;
93221
+ const shortRemovedNow = (Number(reconciliation.external_short_removed_now ?? 0) || 0) + deviceShortRemoved;
93222
+ const targetNow = adjustCopiedTarget(
93223
+ recordedTarget,
93224
+ longRemovedNow - (Number(reconciliation.external_long_removed_before ?? 0) || 0),
93225
+ shortRemovedNow - (Number(reconciliation.external_short_removed_before ?? 0) || 0)
93226
+ );
93227
+ return actualPosition + (targetNow - copiedNow);
93228
+ }
93229
+ var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, executeClientCopyTradingOrderAction;
93038
93230
  var init_runtime_execution = __esm({
93039
93231
  "lib/runtime/runtime-execution.ts"() {
93040
93232
  "use strict";
@@ -93057,6 +93249,7 @@ var init_runtime_execution = __esm({
93057
93249
  init_network_debug();
93058
93250
  init_protective_trigger_price();
93059
93251
  init_runtime_redaction();
93252
+ init_protective_stop_replacement();
93060
93253
  init_error_surface_contract();
93061
93254
  init_runtime_handoff();
93062
93255
  clientProtectiveMutationAuthority = (request) => request.mutationAuthority === "manual_session" ? {} : {
@@ -93145,6 +93338,32 @@ var init_runtime_execution = __esm({
93145
93338
  }
93146
93339
  return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
93147
93340
  };
93341
+ _extractFilledSize = (value) => {
93342
+ const seen = /* @__PURE__ */ new Set();
93343
+ let total = 0;
93344
+ let found = false;
93345
+ const walk = (node) => {
93346
+ if (node == null || typeof node !== "object" || seen.has(node)) return;
93347
+ seen.add(node);
93348
+ if (Array.isArray(node)) {
93349
+ node.forEach(walk);
93350
+ return;
93351
+ }
93352
+ const record5 = node;
93353
+ const filled = record5.filled;
93354
+ if (filled && typeof filled === "object" && !Array.isArray(filled)) {
93355
+ const size = Number(filled.totalSz);
93356
+ if (Number.isFinite(size) && size > 0) {
93357
+ total += size;
93358
+ found = true;
93359
+ }
93360
+ return;
93361
+ }
93362
+ Object.values(record5).forEach(walk);
93363
+ };
93364
+ walk(value);
93365
+ return found ? total : null;
93366
+ };
93148
93367
  _extractOrderId = (value) => {
93149
93368
  const seen = /* @__PURE__ */ new Set();
93150
93369
  const walk = (node) => {
@@ -93362,6 +93581,29 @@ var init_runtime_execution = __esm({
93362
93581
  protectiveGroupReadFailures.add(key);
93363
93582
  return [];
93364
93583
  }
93584
+ const replacedOrderId = legRecord.replacedOrderId == null ? void 0 : Number(legRecord.replacedOrderId);
93585
+ const userCancelledOrderId = legRecord.userCancelledOrderId == null ? void 0 : Number(legRecord.userCancelledOrderId);
93586
+ const replaceJournalRecord = legRecord.replaceJournal;
93587
+ let replaceJournal;
93588
+ if (replaceJournalRecord != null) {
93589
+ const journal = replaceJournalRecord;
93590
+ const journalMutationId = String(journal.mutationId ?? "").trim().toLowerCase();
93591
+ const journalCreatedAtMs = Number(journal.createdAtMs);
93592
+ const journalObservedAtMs = journal.unknownOidObservedAtMs == null ? void 0 : Number(journal.unknownOidObservedAtMs);
93593
+ if (typeof replaceJournalRecord !== "object" || Array.isArray(replaceJournalRecord) || !/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/.test(journalMutationId) || !Number.isSafeInteger(journalCreatedAtMs) || journalCreatedAtMs <= 0 || journalObservedAtMs !== void 0 && (!Number.isSafeInteger(journalObservedAtMs) || journalObservedAtMs <= 0)) {
93594
+ protectiveGroupReadFailures.add(key);
93595
+ return [];
93596
+ }
93597
+ replaceJournal = {
93598
+ mutationId: journalMutationId,
93599
+ createdAtMs: journalCreatedAtMs,
93600
+ ...journalObservedAtMs !== void 0 ? { unknownOidObservedAtMs: journalObservedAtMs } : {}
93601
+ };
93602
+ }
93603
+ if (replacedOrderId !== void 0 && (!Number.isSafeInteger(replacedOrderId) || replacedOrderId <= 0) || userCancelledOrderId !== void 0 && (!Number.isSafeInteger(userCancelledOrderId) || userCancelledOrderId <= 0)) {
93604
+ protectiveGroupReadFailures.add(key);
93605
+ return [];
93606
+ }
93365
93607
  const replacementRecord = legRecord.replacement;
93366
93608
  let replacement;
93367
93609
  if (replacementRecord != null) {
@@ -93394,6 +93636,9 @@ var init_runtime_execution = __esm({
93394
93636
  size,
93395
93637
  isTrailing: legRecord.isTrailing,
93396
93638
  positionTpsl: legRecord.positionTpsl === true,
93639
+ ...replacedOrderId !== void 0 ? { replacedOrderId } : {},
93640
+ ...replaceJournal ? { replaceJournal } : {},
93641
+ ...userCancelledOrderId !== void 0 ? { userCancelledOrderId } : {},
93397
93642
  ...replacement ? { replacement } : {}
93398
93643
  }];
93399
93644
  });
@@ -93615,7 +93860,9 @@ var init_runtime_execution = __esm({
93615
93860
  }
93616
93861
  });
93617
93862
  exactClientProtectiveGroupSetSnapshot = (groups) => stableProtectionSnapshot(groups.map((group) => exactClientProtectiveGroupSnapshot(group)));
93618
- replaceExactClientProtectiveGroup = (profileId, symbol2, expected, replacement) => {
93863
+ storableClientProtectiveGroup = (group) => group != null && group.legs.length === 0 && group.pendingEntry == null ? null : group;
93864
+ replaceExactClientProtectiveGroup = (profileId, symbol2, expected, candidateReplacement) => {
93865
+ const replacement = storableClientProtectiveGroup(candidateReplacement);
93619
93866
  const groups = readFreshClientProtectiveGroups(profileId, symbol2);
93620
93867
  if (hasClientProtectiveGroupReadFailure(profileId, symbol2)) return false;
93621
93868
  const expectedSnapshot = exactClientProtectiveGroupSnapshot(expected);
@@ -94050,6 +94297,7 @@ var init_runtime_execution = __esm({
94050
94297
  const observedSize = Number(shape.size);
94051
94298
  return String(shape.coin ?? "").trim().toUpperCase() === symbol2.trim().toUpperCase() && expectedSide.includes(String(shape.side ?? "").trim().toLowerCase()) && Number.isFinite(observedSize) && observedSize === leg.size && shape.reduceOnly === true && shape.triggerKind === leg.kind;
94052
94299
  };
94300
+ observedProtectiveGroupingMatches = (observed, storedPositionTpsl) => observed === false || observed === true && storedPositionTpsl === true;
94053
94301
  protectiveLiveShapeMatches = (input) => {
94054
94302
  const { shape, symbol: symbol2, isLong, leg } = input;
94055
94303
  return protectiveStableShapeMatches({
@@ -94057,7 +94305,7 @@ var init_runtime_execution = __esm({
94057
94305
  symbol: symbol2,
94058
94306
  isLong,
94059
94307
  leg
94060
- }) && shape.isTrigger === true && Number.isFinite(Number(shape.triggerPrice)) && Number(shape.triggerPrice) === leg.triggerPrice && (input.requirePositionTpsl === false || shape.isPositionTpsl === (leg.positionTpsl === true));
94308
+ }) && shape.isTrigger === true && Number.isFinite(Number(shape.triggerPrice)) && Number(shape.triggerPrice) === leg.triggerPrice && (input.requirePositionTpsl === false || observedProtectiveGroupingMatches(shape.isPositionTpsl, leg.positionTpsl));
94061
94309
  };
94062
94310
  protectiveTerminalShapeMatches = (input) => input.evidence.responseValid === true && input.evidence.orderMatches === true && input.evidence.terminal === true && protectiveStableShapeMatches({
94063
94311
  shape: input.evidence,
@@ -94258,6 +94506,22 @@ var init_runtime_execution = __esm({
94258
94506
  );
94259
94507
  return { group, cleanup, persistedGroupSet: persistenceFailed ? null : nextGroups };
94260
94508
  };
94509
+ storedClientProtectiveCover = async (request, legs) => {
94510
+ const cover = { sl: 0, tp: 0 };
94511
+ if (legs.length === 0) return cover;
94512
+ const symbol2 = request.executionContext.symbol.trim().toUpperCase();
94513
+ const orders = await fetchClientRuntimeOpenOrders(request, "trading_reduce");
94514
+ if (!Array.isArray(orders)) {
94515
+ throw new Error("Malformed live protective-order snapshot.");
94516
+ }
94517
+ const liveOrderIds = new Set(orders.filter((order) => String(order.coin).trim().toUpperCase() === symbol2).map((order) => String(order.oid)));
94518
+ for (const leg of legs) {
94519
+ if (typeof leg.orderId === "string" || liveOrderIds.has(String(leg.orderId))) {
94520
+ cover[leg.kind] += leg.size;
94521
+ }
94522
+ }
94523
+ return cover;
94524
+ };
94261
94525
  attachClientProtectivePlan = async (request, group, fill) => {
94262
94526
  const reports = [];
94263
94527
  const plan = group.pendingEntry;
@@ -94352,8 +94616,28 @@ var init_runtime_execution = __esm({
94352
94616
  return reports;
94353
94617
  }
94354
94618
  const liveExposure = Math.abs(livePositionSize);
94619
+ let storedCover;
94620
+ try {
94621
+ storedCover = await storedClientProtectiveCover(
94622
+ request,
94623
+ existingGroups.flatMap((existing) => existing.legs)
94624
+ );
94625
+ } catch (error48) {
94626
+ if (request.signal?.aborted) throw error48;
94627
+ reports.push({
94628
+ order_id: fill.orderId,
94629
+ symbol: symbol2,
94630
+ action: "PROTECTIVE_RECONCILIATION",
94631
+ status: "failed",
94632
+ execution_metadata: {
94633
+ reason_code: "protective_open_orders_unresolved",
94634
+ error: getSanitizedRuntimeErrorMessage(error48) || "Unable to read live protective orders."
94635
+ }
94636
+ });
94637
+ return reports;
94638
+ }
94355
94639
  const allocatedCandidates = planned.flatMap((candidate) => {
94356
- const allocated = existingGroups.flatMap((existing) => existing.legs).filter((leg) => leg.kind === candidate.kind).reduce((total, leg) => total + leg.size, 0);
94640
+ const allocated = storedCover[candidate.kind];
94357
94641
  const size = roundAssetSize(
94358
94642
  Math.min(fill.filledSize, Math.max(0, liveExposure - allocated)),
94359
94643
  request.executionContext.sizeDecimals
@@ -94905,11 +95189,11 @@ var init_runtime_execution = __esm({
94905
95189
  });
94906
95190
  }
94907
95191
  canonicalRows.sort((left, right) => left.time - right.time || left.tradeId - right.tradeId);
94908
- const positionTolerance = (left, right) => Math.max(1e-10, Math.max(Math.abs(left), Math.abs(right)) * 1e-8);
95192
+ const positionTolerance2 = (left, right) => Math.max(1e-10, Math.max(Math.abs(left), Math.abs(right)) * 1e-8);
94909
95193
  for (let index = 1; index < canonicalRows.length; index += 1) {
94910
95194
  const previous = canonicalRows[index - 1];
94911
95195
  const current = canonicalRows[index];
94912
- if (Math.abs(previous.endPosition - current.startPosition) > positionTolerance(previous.endPosition, current.startPosition)) {
95196
+ if (Math.abs(previous.endPosition - current.startPosition) > positionTolerance2(previous.endPosition, current.startPosition)) {
94913
95197
  throw new Error("Journaled protective fill start-position continuity is unresolved.");
94914
95198
  }
94915
95199
  }
@@ -94930,14 +95214,14 @@ var init_runtime_execution = __esm({
94930
95214
  throw new Error("Journaled protective entry chronology is unresolved.");
94931
95215
  }
94932
95216
  const firstEntry = canonicalRows[firstEntryIndex];
94933
- if (options.allowOppositeStart !== true && expectedSign * firstEntry.startPosition < -positionTolerance(firstEntry.startPosition, 0)) {
95217
+ if (options.allowOppositeStart !== true && expectedSign * firstEntry.startPosition < -positionTolerance2(firstEntry.startPosition, 0)) {
94934
95218
  throw new Error("Journaled protective entry start position is directionally unresolved.");
94935
95219
  }
94936
95220
  let expectedExposureEstablished = false;
94937
95221
  let continuityInterrupted = false;
94938
95222
  for (let index = firstEntryIndex; index < canonicalRows.length; index += 1) {
94939
95223
  const row = canonicalRows[index];
94940
- const tolerance = positionTolerance(row.startPosition, row.endPosition);
95224
+ const tolerance = positionTolerance2(row.startPosition, row.endPosition);
94941
95225
  if (expectedSign * row.startPosition > tolerance) {
94942
95226
  expectedExposureEstablished = true;
94943
95227
  }
@@ -94951,13 +95235,13 @@ var init_runtime_execution = __esm({
94951
95235
  if (!Number.isFinite(computedPosition)) {
94952
95236
  throw new Error("Journaled protective final fill exposure is unresolved.");
94953
95237
  }
94954
- if (Math.abs(computedPosition - livePositionSize) > positionTolerance(computedPosition, livePositionSize)) {
95238
+ if (Math.abs(computedPosition - livePositionSize) > positionTolerance2(computedPosition, livePositionSize)) {
94955
95239
  throw new Error("Journaled protective computed exposure does not match the fresh live position.");
94956
95240
  }
94957
95241
  if (continuityInterrupted) {
94958
95242
  return { disposition: "interrupted" };
94959
95243
  }
94960
- const liveDirectionMatches = group.isLong ? livePositionSize > positionTolerance(livePositionSize, 0) : livePositionSize < -positionTolerance(livePositionSize, 0);
95244
+ const liveDirectionMatches = group.isLong ? livePositionSize > positionTolerance2(livePositionSize, 0) : livePositionSize < -positionTolerance2(livePositionSize, 0);
94961
95245
  if (!liveDirectionMatches) return { disposition: "exposure_ended" };
94962
95246
  return { disposition: "matching" };
94963
95247
  };
@@ -95827,7 +96111,7 @@ var init_runtime_execution = __esm({
95827
96111
  }
95828
96112
  throw new Error("Ambiguous position-TPSL replacement identity requires exact recovery.");
95829
96113
  }
95830
- const exactShapeMatches = evidence.responseValid && evidence.orderMatches && Number.isSafeInteger(replacementOrderId) && replacementOrderId > 0 && String(evidence.coin ?? "").trim().toUpperCase() === symbol2.trim().toUpperCase() && expectedSide.includes(String(evidence.side ?? "").trim().toLowerCase()) && evidence.reduceOnly === true && evidence.isTrigger === true && evidence.triggerKind === effectiveLeg.kind && evidence.isPositionTpsl === (effectiveLeg.positionTpsl === true) && evidence.originalSize != null && evidence.originalSize === replacement.size && evidence.triggerPrice != null && evidence.triggerPrice === replacement.triggerPrice;
96114
+ const exactShapeMatches = evidence.responseValid && evidence.orderMatches && Number.isSafeInteger(replacementOrderId) && replacementOrderId > 0 && String(evidence.coin ?? "").trim().toUpperCase() === symbol2.trim().toUpperCase() && expectedSide.includes(String(evidence.side ?? "").trim().toLowerCase()) && evidence.reduceOnly === true && evidence.isTrigger === true && evidence.triggerKind === effectiveLeg.kind && observedProtectiveGroupingMatches(evidence.isPositionTpsl, effectiveLeg.positionTpsl) && evidence.originalSize != null && evidence.originalSize === replacement.size && evidence.triggerPrice != null && evidence.triggerPrice === replacement.triggerPrice;
95831
96115
  const fulfilledShapeMatches = Number.isSafeInteger(replacementOrderId) && replacementOrderId > 0 && classifyHyperliquidOrderStatus(evidence.orderStatus) === "filled" && evidence.fulfilled && protectiveTerminalShapeMatches({
95832
96116
  evidence: {
95833
96117
  ...evidence,
@@ -96200,6 +96484,44 @@ var init_runtime_execution = __esm({
96200
96484
  }
96201
96485
  return reports;
96202
96486
  };
96487
+ liveProtectiveOrderShape = (order) => ({
96488
+ coin: order.coin,
96489
+ side: order.side,
96490
+ size: order.sz,
96491
+ reduceOnly: order.reduce_only,
96492
+ isTrigger: order.is_trigger,
96493
+ triggerKind: order.trigger_kind,
96494
+ triggerPrice: order.trigger_px,
96495
+ isPositionTpsl: order.is_position_tpsl
96496
+ });
96497
+ observedStandaloneProtectiveGroup = (group, liveOrders, symbol2) => {
96498
+ if (!group.legs.some((leg) => leg.positionTpsl === true) || group.legs.some((leg) => leg.replacement != null)) {
96499
+ return null;
96500
+ }
96501
+ let standaloneObserved = false;
96502
+ for (const leg of group.legs) {
96503
+ const liveOrder = liveOrders.find((order) => order.oid === leg.orderId);
96504
+ if (liveOrder == null) continue;
96505
+ if (liveOrder.is_position_tpsl !== false) return null;
96506
+ if (protectiveLiveShapeMatches({
96507
+ shape: liveProtectiveOrderShape(liveOrder),
96508
+ symbol: symbol2,
96509
+ isLong: group.isLong,
96510
+ leg
96511
+ })) {
96512
+ standaloneObserved = true;
96513
+ }
96514
+ }
96515
+ return standaloneObserved ? { ...group, legs: group.legs.map((leg) => ({ ...leg, positionTpsl: false })) } : null;
96516
+ };
96517
+ migrateTrackedTrailingStopsToStandalone = (profileId, symbol2, group) => {
96518
+ const orderIds = new Set(group.legs.map((leg) => String(leg.orderId)));
96519
+ const records = readTrackedTrailingStops(profileId, symbol2);
96520
+ if (!records.some((record5) => orderIds.has(String(record5.orderId)) && record5.positionTpsl)) {
96521
+ return;
96522
+ }
96523
+ writeTrackedTrailingStops(profileId, symbol2, records.map((record5) => orderIds.has(String(record5.orderId)) ? { ...record5, positionTpsl: false } : record5));
96524
+ };
96203
96525
  reconcileClientProtectiveGroups = async (request, knownPositionSize) => {
96204
96526
  const profileId = String(request.profileId).trim();
96205
96527
  const symbol2 = request.executionContext.symbol;
@@ -96245,7 +96567,8 @@ var init_runtime_execution = __esm({
96245
96567
  return reports;
96246
96568
  }
96247
96569
  let expectedGroupSet = reconciliationGroupSet;
96248
- const transitionExactGroup = (expected, replacement) => {
96570
+ const transitionExactGroup = (expected, candidateReplacement) => {
96571
+ const replacement = storableClientProtectiveGroup(candidateReplacement);
96249
96572
  if (!replaceExactClientProtectiveGroup(profileId, symbol2, expected, replacement)) {
96250
96573
  return false;
96251
96574
  }
@@ -96303,8 +96626,101 @@ var init_runtime_execution = __esm({
96303
96626
  }
96304
96627
  })));
96305
96628
  }
96629
+ const resolveUnknownStopReplacement = async (group, leg) => {
96630
+ const journal = leg.replaceJournal;
96631
+ if (journal == null) return { leg, notLanded: false, reports: [] };
96632
+ const waiting = (reasonCode, error48) => ({
96633
+ leg,
96634
+ notLanded: false,
96635
+ reports: [{
96636
+ order_id: null,
96637
+ client_mutation_id: journal.mutationId,
96638
+ symbol: symbol2,
96639
+ action: protectiveAction(leg),
96640
+ status: "blocked",
96641
+ execution_metadata: { reason_code: reasonCode, ...error48 ? { error: error48 } : {} }
96642
+ }]
96643
+ });
96644
+ const observedAtMs = Date.now();
96645
+ const marginMs = requireClientRuntimeConfigSeconds(
96646
+ request.config,
96647
+ "client_pending_entry_never_landed_margin_seconds"
96648
+ ) * 1e3;
96649
+ let ledgerKind;
96650
+ let expiresAfterMs = Number.NaN;
96651
+ try {
96652
+ const mutation = await getClientRuntimeExchangeMutation(request.profileId, journal.mutationId, request.signal);
96653
+ if (mutation == null) {
96654
+ ledgerKind = "absent";
96655
+ } else if (mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === String(leg.orderId)) {
96656
+ ledgerKind = "found";
96657
+ expiresAfterMs = Number(mutation.exchange_expires_after_ms);
96658
+ } else {
96659
+ ledgerKind = "unavailable";
96660
+ }
96661
+ } catch (error48) {
96662
+ if (request.signal?.aborted) throw error48;
96663
+ ledgerKind = "unavailable";
96664
+ }
96665
+ let provableAtMs;
96666
+ if (ledgerKind === "found" && Number.isSafeInteger(expiresAfterMs) && expiresAfterMs > 0) {
96667
+ provableAtMs = expiresAfterMs + marginMs;
96668
+ } else if (ledgerKind === "absent") {
96669
+ const signedLifetimeSeconds = Number(
96670
+ request.config?.client_runtime_exchange_mutation?.expires_after_seconds
96671
+ );
96672
+ if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
96673
+ throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
96674
+ }
96675
+ provableAtMs = journal.createdAtMs + signedLifetimeSeconds * 1e3 + marginMs;
96676
+ } else {
96677
+ return waiting("protective_stop_replacement_unresolved", "The stop re-place ledger cannot answer yet.");
96678
+ }
96679
+ if (observedAtMs < provableAtMs) {
96680
+ return waiting("protective_stop_replacement_unresolved");
96681
+ }
96682
+ if (journal.unknownOidObservedAtMs == null || journal.unknownOidObservedAtMs < provableAtMs) {
96683
+ const observedLeg = {
96684
+ ...leg,
96685
+ replaceJournal: { ...journal, unknownOidObservedAtMs: observedAtMs }
96686
+ };
96687
+ const observedGroup = {
96688
+ ...group,
96689
+ legs: group.legs.map((candidate) => candidate.orderId === leg.orderId ? observedLeg : candidate)
96690
+ };
96691
+ if (!transitionExactGroup(group, observedGroup)) {
96692
+ return waiting("protective_lifecycle_persistence_failed");
96693
+ }
96694
+ return { ...waiting("protective_stop_replacement_unresolved"), leg: observedLeg, group: observedGroup };
96695
+ }
96696
+ return { leg, notLanded: true, reports: [] };
96697
+ };
96306
96698
  const inspectedGroups = [];
96307
- for (const group of groups) {
96699
+ for (const observedGroup of groups) {
96700
+ let group = observedGroup;
96701
+ const standaloneGroup = observedStandaloneProtectiveGroup(group, liveOrders, symbol2);
96702
+ if (standaloneGroup != null) {
96703
+ if (!transitionExactGroup(group, standaloneGroup)) {
96704
+ const legs2 = [];
96705
+ for (const leg of group.legs) {
96706
+ legs2.push({ leg, openOrder: null, state: "unresolved" });
96707
+ reports.push({
96708
+ order_id: String(leg.orderId),
96709
+ symbol: symbol2,
96710
+ action: protectiveAction(leg),
96711
+ status: "failed",
96712
+ execution_metadata: {
96713
+ reason_code: "protective_lifecycle_persistence_failed",
96714
+ execution_stage: "observed_standalone_grouping_migration"
96715
+ }
96716
+ });
96717
+ }
96718
+ inspectedGroups.push({ group, legs: legs2 });
96719
+ continue;
96720
+ }
96721
+ migrateTrackedTrailingStopsToStandalone(profileId, symbol2, standaloneGroup);
96722
+ group = standaloneGroup;
96723
+ }
96308
96724
  let durableInspectedGroup = group;
96309
96725
  const legs = [];
96310
96726
  let ambiguousPositionTpslAuthority = hasAmbiguousClientPositionTpslAuthority(group);
@@ -96394,6 +96810,13 @@ var init_runtime_execution = __esm({
96394
96810
  signal: request.signal,
96395
96811
  orderId: leg.orderId
96396
96812
  });
96813
+ if (typeof leg.orderId === "string" && leg.replaceJournal != null && evidence.responseValid && evidence.responseStatus === "unknownOid") {
96814
+ const landing = await resolveUnknownStopReplacement(durableInspectedGroup, leg);
96815
+ if (landing.group != null) durableInspectedGroup = landing.group;
96816
+ legs.push({ leg: landing.leg, openOrder: null, state: landing.notLanded ? "not_landed" : "unresolved" });
96817
+ reports.push(...landing.reports);
96818
+ continue;
96819
+ }
96397
96820
  const terminalShapeMatches = protectiveTerminalShapeMatches({
96398
96821
  evidence: {
96399
96822
  ...evidence,
@@ -96409,7 +96832,8 @@ var init_runtime_execution = __esm({
96409
96832
  legs.push({
96410
96833
  leg: inspectedLeg,
96411
96834
  openOrder: resolvedOpenOrder,
96412
- state: evidence.responseValid && evidence.orderMatches ? evidence.fulfilled ? terminalShapeMatches ? "fulfilled" : "unresolved" : evidence.terminal ? terminalShapeMatches ? "terminal" : "unresolved" : classifyHyperliquidOrderStatus(evidence.orderStatus) === "open" ? resolvedOpenOrder == null ? "unresolved" : "open" : "unresolved" : "unresolved"
96835
+ state: evidence.responseValid && evidence.orderMatches ? evidence.fulfilled ? terminalShapeMatches ? "fulfilled" : "unresolved" : evidence.terminal ? terminalShapeMatches ? "terminal" : "unresolved" : classifyHyperliquidOrderStatus(evidence.orderStatus) === "open" ? resolvedOpenOrder == null ? "unresolved" : "open" : "unresolved" : "unresolved",
96836
+ ...evidence.terminal && !evidence.fulfilled ? { terminalStatus: { orderStatus: evidence.orderStatus, statusTimestampMs: evidence.statusTimestampMs ?? null } } : {}
96413
96837
  });
96414
96838
  if (evidence.responseValid && evidence.orderMatches && evidence.terminal && !terminalShapeMatches) {
96415
96839
  reports.push({
@@ -96473,6 +96897,336 @@ var init_runtime_execution = __esm({
96473
96897
  tp: exposure
96474
96898
  };
96475
96899
  const retainedGroups = expectedGroupSet.filter((group) => group.pendingEntry != null || isProtectiveReplacementJournalGroup(group));
96900
+ let stopSizePlacedThisPass = 0;
96901
+ const unresolvedStopSize = inspectedGroups.flatMap((candidate) => candidate.legs).filter((entry) => entry.leg.kind === "sl" && entry.state === "unresolved" && !liveOrders.some((order) => order.oid === entry.leg.orderId)).reduce((total, entry) => total + entry.leg.size, 0);
96902
+ const lostOrderIds = new Set(
96903
+ inspectedGroups.flatMap((candidate) => candidate.legs).filter((entry) => entry.state === "terminal").map((entry) => String(entry.leg.orderId))
96904
+ );
96905
+ let lostLegEvidence = null;
96906
+ const readLostLegEvidence = () => {
96907
+ lostLegEvidence ??= (async () => {
96908
+ const snapshot = await fetchBrowserPositionSnapshot(
96909
+ request.config ?? {},
96910
+ walletAddress,
96911
+ symbol2,
96912
+ request.signal,
96913
+ "trading_reconcile"
96914
+ );
96915
+ const positionSize = Number(snapshot.size);
96916
+ if (!Number.isFinite(positionSize)) {
96917
+ throw new Error("Unable to verify live position exposure for a lost protective order.");
96918
+ }
96919
+ const freshOrders = await fetchClientRuntimeOpenOrders(request);
96920
+ if (!Array.isArray(freshOrders)) {
96921
+ throw new Error("Malformed live protective-order snapshot.");
96922
+ }
96923
+ const freshIsLong = positionSize > 0;
96924
+ const liveStopSize = freshOrders.filter((order) => !lostOrderIds.has(String(order.oid)) && String(order.coin).trim().toUpperCase() === symbol2.trim().toUpperCase() && order.reduce_only && order.is_trigger && order.trigger_kind === "sl" && (freshIsLong ? ["a", "sell"].includes(String(order.side).trim().toLowerCase()) : ["b", "buy"].includes(String(order.side).trim().toLowerCase()))).reduce((total, order) => total + (Number(order.sz) > 0 ? Number(order.sz) : 0), 0);
96925
+ return { positionSize, liveStopSize };
96926
+ })();
96927
+ return lostLegEvidence;
96928
+ };
96929
+ const lostLegPositionEpisodeEnded = async (group, terminalStatus, positionSize) => {
96930
+ if (terminalStatus == null || !POSITION_ENDED_ORDER_STATUSES.has(String(terminalStatus.orderStatus ?? "")) || positionSize === 0 || positionSize > 0 !== group.isLong) {
96931
+ return false;
96932
+ }
96933
+ try {
96934
+ const { rawFills, evidence } = await fetchBrowserUserFills({
96935
+ publicRequestPriority: "trading_reconcile",
96936
+ config: request.config ?? {},
96937
+ walletAddress,
96938
+ symbols: [symbol2],
96939
+ forceRefresh: true,
96940
+ signal: request.signal
96941
+ });
96942
+ return evidence?.exactTerminalFillEvidenceComplete === true && protectivePositionEpisodeEnded({
96943
+ orderStatus: terminalStatus.orderStatus,
96944
+ statusTimestampMs: terminalStatus.statusTimestampMs,
96945
+ isLong: group.isLong,
96946
+ symbol: symbol2,
96947
+ fills: rawFills
96948
+ });
96949
+ } catch (error48) {
96950
+ if (request.signal?.aborted) throw error48;
96951
+ return false;
96952
+ }
96953
+ };
96954
+ const resolveLostClientProtectiveLeg = async (group, leg, botCleanupInFlight, terminalStatus) => {
96955
+ let evidence;
96956
+ try {
96957
+ evidence = await readLostLegEvidence();
96958
+ } catch (error48) {
96959
+ if (request.signal?.aborted) throw error48;
96960
+ return {
96961
+ retain: leg,
96962
+ reports: [{
96963
+ order_id: String(leg.orderId),
96964
+ symbol: symbol2,
96965
+ action: protectiveAction(leg),
96966
+ status: "failed",
96967
+ execution_metadata: {
96968
+ reason_code: "protective_position_unresolved",
96969
+ error: getSanitizedRuntimeErrorMessage(error48) || "Unable to verify live position exposure."
96970
+ }
96971
+ }]
96972
+ };
96973
+ }
96974
+ const decision = decideProtectiveStopReplacement({
96975
+ legKind: leg.kind === "sl" ? "stop_loss" : "take_profit",
96976
+ isLong: group.isLong,
96977
+ positionSize: evidence.positionSize,
96978
+ legSize: leg.size,
96979
+ otherLiveStopSize: evidence.liveStopSize,
96980
+ inFlightStopSize: unresolvedStopSize + stopSizePlacedThisPass,
96981
+ sizeDecimals: request.executionContext.sizeDecimals,
96982
+ triggerPrice: leg.triggerPrice,
96983
+ alreadyReplaced: leg.replacedOrderId != null,
96984
+ botCleanupInFlight: botCleanupInFlight || leg.replacement != null,
96985
+ cancelledByUser: leg.userCancelledOrderId != null && String(leg.userCancelledOrderId) === String(leg.orderId),
96986
+ positionEpisodeEnded: await lostLegPositionEpisodeEnded(group, terminalStatus, evidence.positionSize)
96987
+ });
96988
+ const livePositionSize2 = evidence.positionSize;
96989
+ if (decision.outcome === "defer") {
96990
+ return {
96991
+ retain: leg,
96992
+ reports: [leg.replacement != null ? pendingProtectiveReplacementReport(symbol2, leg) : {
96993
+ order_id: String(leg.orderId),
96994
+ symbol: symbol2,
96995
+ action: protectiveAction(leg),
96996
+ status: "failed",
96997
+ execution_metadata: { reason_code: decision.reasonCode }
96998
+ }]
96999
+ };
97000
+ }
97001
+ const withoutLeg = {
97002
+ ...group,
97003
+ legs: group.legs.filter((candidate) => candidate.orderId !== leg.orderId)
97004
+ };
97005
+ const retireLeg = (reasonCode, status, extra = {}) => {
97006
+ if (!transitionExactGroup(group, withoutLeg)) {
97007
+ return {
97008
+ retain: leg,
97009
+ reports: [{
97010
+ order_id: String(leg.orderId),
97011
+ symbol: symbol2,
97012
+ action: protectiveAction(leg),
97013
+ status: "failed",
97014
+ execution_metadata: {
97015
+ reason_code: "protective_lifecycle_persistence_failed",
97016
+ execution_stage: "lost_protective_leg_retire"
97017
+ }
97018
+ }]
97019
+ };
97020
+ }
97021
+ removeTrackedTrailingStop(profileId, symbol2, leg.orderId);
97022
+ return {
97023
+ group: withoutLeg,
97024
+ reports: [{
97025
+ // Trade sync stores blocked rows by order id; this placed no order.
97026
+ order_id: status === "blocked" ? null : String(leg.orderId),
97027
+ symbol: symbol2,
97028
+ action: protectiveAction(leg),
97029
+ status,
97030
+ execution_metadata: {
97031
+ reason_code: reasonCode,
97032
+ trigger_price: leg.triggerPrice,
97033
+ protected_size: leg.size,
97034
+ live_position_size: livePositionSize2,
97035
+ ...extra
97036
+ }
97037
+ }]
97038
+ };
97039
+ };
97040
+ if (decision.outcome !== "replace") {
97041
+ return retireLeg(decision.reasonCode, decision.outcome === "not_required" ? "blocked" : "failed");
97042
+ }
97043
+ const triggerPrice = Number(formatHyperliquidTriggerPriceWire(
97044
+ decision.triggerPrice,
97045
+ request.executionContext.sizeDecimals
97046
+ ));
97047
+ const mutationId = createRuntimeId().toLowerCase();
97048
+ const clientOrderId = clientOrderIdForMutation(mutationId);
97049
+ const lostOrderId = Number(leg.orderId);
97050
+ const provisionalLeg = {
97051
+ kind: leg.kind,
97052
+ orderId: clientOrderId,
97053
+ triggerPrice,
97054
+ size: decision.size,
97055
+ isTrailing: leg.isTrailing,
97056
+ positionTpsl: false,
97057
+ replacedOrderId: lostOrderId,
97058
+ replaceJournal: { mutationId, createdAtMs: Date.now() }
97059
+ };
97060
+ const provisionalGroup = {
97061
+ ...group,
97062
+ legs: group.legs.map((candidate) => candidate.orderId === leg.orderId ? provisionalLeg : candidate)
97063
+ };
97064
+ if (!Number.isSafeInteger(lostOrderId) || !transitionExactGroup(group, provisionalGroup)) {
97065
+ return {
97066
+ retain: leg,
97067
+ reports: [{
97068
+ order_id: String(leg.orderId),
97069
+ symbol: symbol2,
97070
+ action: protectiveAction(leg),
97071
+ status: "failed",
97072
+ execution_metadata: {
97073
+ reason_code: "protective_lifecycle_persistence_failed",
97074
+ execution_stage: "lost_stop_replacement_journal"
97075
+ }
97076
+ }]
97077
+ };
97078
+ }
97079
+ stopSizePlacedThisPass += decision.size;
97080
+ let dispatchMayHaveStarted = false;
97081
+ let response;
97082
+ try {
97083
+ response = await executeClientTriggerOrder({
97084
+ profileId: request.profileId,
97085
+ ...clientProtectiveMutationAuthority(request),
97086
+ walletAddress: request.executionContext.walletAddress,
97087
+ config: request.config ?? null,
97088
+ signal: request.signal,
97089
+ signingKey: request.signingKey,
97090
+ onExchangeOrderDispatched: () => {
97091
+ if (!replaceExactClientProtectiveGroupSet(profileId, symbol2, expectedGroupSet, expectedGroupSet)) {
97092
+ throw new Error("Stop re-place dispatch authority is no longer exact.");
97093
+ }
97094
+ request.onExchangeOrderDispatched?.("protection");
97095
+ dispatchMayHaveStarted = true;
97096
+ },
97097
+ symbol: symbol2,
97098
+ side: group.isLong ? "sell" : "buy",
97099
+ size: decision.size,
97100
+ triggerPrice,
97101
+ reduceOnly: true,
97102
+ isTakeProfit: false,
97103
+ triggerIsMarket: true,
97104
+ mutationId,
97105
+ clientOrderId
97106
+ });
97107
+ } catch (error48) {
97108
+ if (error48 instanceof HyperliquidExchangeRejectionError) {
97109
+ const rejectionProjection = projectExecutionErrorContract({ error: error48, symbol: symbol2 });
97110
+ stopSizePlacedThisPass -= decision.size;
97111
+ const rejectedGroup = {
97112
+ ...provisionalGroup,
97113
+ legs: provisionalGroup.legs.filter((candidate) => candidate.orderId !== clientOrderId)
97114
+ };
97115
+ const retired = transitionExactGroup(provisionalGroup, rejectedGroup);
97116
+ if (retired) removeTrackedTrailingStop(profileId, symbol2, leg.orderId);
97117
+ return {
97118
+ ...retired ? { group: rejectedGroup } : { retain: provisionalLeg, group: provisionalGroup },
97119
+ reports: [{
97120
+ order_id: String(leg.orderId),
97121
+ client_mutation_id: error48.clientMutationId ?? mutationId,
97122
+ symbol: symbol2,
97123
+ action: protectiveAction(leg),
97124
+ status: "failed",
97125
+ execution_metadata: {
97126
+ reason_code: STOP_REPLACEMENT_REJECTED,
97127
+ error: rejectionProjection?.message ?? getSanitizedRuntimeErrorMessage(error48) ?? "Hyperliquid rejected the stop re-place.",
97128
+ replaced_order_id: lostOrderId,
97129
+ trigger_price: triggerPrice,
97130
+ protected_size: decision.size,
97131
+ order_diagnostics: error48.orderDiagnostics
97132
+ }
97133
+ }]
97134
+ };
97135
+ }
97136
+ if (!dispatchMayHaveStarted) {
97137
+ stopSizePlacedThisPass -= decision.size;
97138
+ const restored = transitionExactGroup(provisionalGroup, group);
97139
+ if (restored && isClientRuntimeWindowHandoffBeforePlanDispatch(error48)) {
97140
+ throw error48;
97141
+ }
97142
+ return {
97143
+ retain: restored ? leg : provisionalLeg,
97144
+ group: restored ? group : provisionalGroup,
97145
+ reports: [{
97146
+ order_id: String(leg.orderId),
97147
+ client_mutation_id: mutationId,
97148
+ symbol: symbol2,
97149
+ action: protectiveAction(leg),
97150
+ status: "failed",
97151
+ execution_metadata: {
97152
+ reason_code: "protective_stop_replacement_unresolved",
97153
+ error: getSanitizedRuntimeErrorMessage(error48) || "The stop re-place was not sent."
97154
+ }
97155
+ }]
97156
+ };
97157
+ }
97158
+ return {
97159
+ retain: provisionalLeg,
97160
+ group: provisionalGroup,
97161
+ reports: [{
97162
+ order_id: null,
97163
+ client_mutation_id: mutationId,
97164
+ symbol: symbol2,
97165
+ action: protectiveAction(leg),
97166
+ status: "blocked",
97167
+ execution_metadata: {
97168
+ reason_code: "protective_trigger_ack_unresolved",
97169
+ replaced_order_id: lostOrderId
97170
+ }
97171
+ }]
97172
+ };
97173
+ }
97174
+ const acknowledgement = extractCanonicalHyperliquidOrderStateAcknowledgement(response);
97175
+ const placedOrderId = Number(acknowledgement?.orderId);
97176
+ if (acknowledgement == null || !Number.isSafeInteger(placedOrderId) || placedOrderId <= 0) {
97177
+ return {
97178
+ retain: provisionalLeg,
97179
+ group: provisionalGroup,
97180
+ reports: [{
97181
+ order_id: null,
97182
+ client_mutation_id: mutationId,
97183
+ symbol: symbol2,
97184
+ action: protectiveAction(leg),
97185
+ status: "blocked",
97186
+ execution_metadata: {
97187
+ reason_code: "protective_trigger_ack_unresolved",
97188
+ replaced_order_id: lostOrderId
97189
+ }
97190
+ }]
97191
+ };
97192
+ }
97193
+ const { replaceJournal: _landedJournal, ...landedLeg } = provisionalLeg;
97194
+ const placedLeg = { ...landedLeg, orderId: placedOrderId };
97195
+ const placedGroup = {
97196
+ ...provisionalGroup,
97197
+ legs: provisionalGroup.legs.map((candidate) => candidate.orderId === clientOrderId ? placedLeg : candidate)
97198
+ };
97199
+ const bound = transitionExactGroup(provisionalGroup, placedGroup);
97200
+ if (bound && leg.isTrailing) {
97201
+ replaceTrackedTrailingStop(profileId, symbol2, leg.orderId, {
97202
+ orderId: placedOrderId,
97203
+ size: decision.size,
97204
+ triggerPrice,
97205
+ isLong: group.isLong,
97206
+ positionTpsl: false
97207
+ });
97208
+ }
97209
+ return {
97210
+ retain: bound ? placedLeg : provisionalLeg,
97211
+ group: bound ? placedGroup : provisionalGroup,
97212
+ reports: [{
97213
+ order_id: String(placedOrderId),
97214
+ client_mutation_id: mutationId,
97215
+ symbol: symbol2,
97216
+ action: protectiveAction(leg),
97217
+ status: "executed",
97218
+ execution_metadata: {
97219
+ reason_code: decision.reasonCode,
97220
+ replaced_order_id: lostOrderId,
97221
+ trigger_price: triggerPrice,
97222
+ protected_size: decision.size,
97223
+ live_position_size: livePositionSize2,
97224
+ position_tpsl: false,
97225
+ ...acknowledgement.state === "fulfilled" ? { acknowledgement_state: "fulfilled" } : {}
97226
+ }
97227
+ }]
97228
+ };
97229
+ };
96476
97230
  groupLoop: for (let groupIndex = 0; groupIndex < inspectedGroups.length; groupIndex += 1) {
96477
97231
  const inspected = inspectedGroups[groupIndex];
96478
97232
  let durableGroup = inspected.group;
@@ -96498,7 +97252,25 @@ var init_runtime_execution = __esm({
96498
97252
  for (let entryIndex = 0; entryIndex < inspected.legs.length; entryIndex += 1) {
96499
97253
  const entry = inspected.legs[entryIndex];
96500
97254
  const { leg, openOrder, state: state2 } = entry;
96501
- if (state2 === "fulfilled" || state2 === "terminal" && (groupFulfilled || exposure <= 0)) {
97255
+ if (state2 === "not_landed") {
97256
+ removeTrackedTrailingStop(profileId, symbol2, leg.orderId);
97257
+ reports.push({
97258
+ order_id: null,
97259
+ client_mutation_id: leg.replaceJournal?.mutationId,
97260
+ symbol: symbol2,
97261
+ action: protectiveAction(leg),
97262
+ status: "failed",
97263
+ execution_metadata: {
97264
+ reason_code: STOP_REPLACEMENT_NOT_LANDED,
97265
+ replaced_order_id: leg.replacedOrderId,
97266
+ trigger_price: leg.triggerPrice,
97267
+ protected_size: leg.size
97268
+ }
97269
+ });
97270
+ continue;
97271
+ }
97272
+ const botEndedLeg = inspected.legs.some((candidate) => candidate.state === "fulfilled") || inspected.group.cleanupRequired === true || exposure <= 0;
97273
+ if (state2 === "fulfilled" || state2 === "terminal" && botEndedLeg) {
96502
97274
  if (leg.replacement != null) {
96503
97275
  retainedLegs.push(leg);
96504
97276
  reports.push(pendingProtectiveReplacementReport(symbol2, leg));
@@ -96508,16 +97280,15 @@ var init_runtime_execution = __esm({
96508
97280
  continue;
96509
97281
  }
96510
97282
  if (state2 === "terminal") {
96511
- retainedLegs.push(leg);
96512
- reports.push({
96513
- order_id: String(leg.orderId),
96514
- symbol: symbol2,
96515
- action: protectiveAction(leg),
96516
- status: "failed",
96517
- execution_metadata: {
96518
- reason_code: "protective_terminal_without_confirmed_sibling_fill"
96519
- }
96520
- });
97283
+ const lost = await resolveLostClientProtectiveLeg(
97284
+ durableGroup,
97285
+ leg,
97286
+ inspected.group.cleanupRequired === true,
97287
+ entry.terminalStatus
97288
+ );
97289
+ if (lost.retain) retainedLegs.push(lost.retain);
97290
+ if (lost.group) durableGroup = lost.group;
97291
+ reports.push(...lost.reports);
96521
97292
  continue;
96522
97293
  }
96523
97294
  const mustCancel = groupFulfilled || exposure <= 0 || durableGroup.isLong !== liveIsLong;
@@ -96552,7 +97323,7 @@ var init_runtime_execution = __esm({
96552
97323
  const liveSide = String(openOrder.side).trim().toLowerCase();
96553
97324
  const sideMatches = inspected.group.isLong ? liveSide === "a" || liveSide === "sell" : liveSide === "b" || liveSide === "buy";
96554
97325
  const liveTriggerKind = openOrder.trigger_kind;
96555
- const trusted = String(openOrder.coin).trim().toUpperCase() === symbol2.trim().toUpperCase() && sideMatches && openOrder.reduce_only && openOrder.is_trigger && Number.isFinite(liveOrderSize) && liveOrderSize > 0 && Number.isFinite(liveTriggerPrice) && liveTriggerPrice > 0 && liveTriggerKind === leg.kind && openOrder.is_position_tpsl === (leg.positionTpsl === true) && liveOrderSize === leg.size && liveTriggerPrice === leg.triggerPrice;
97326
+ const trusted = String(openOrder.coin).trim().toUpperCase() === symbol2.trim().toUpperCase() && sideMatches && openOrder.reduce_only && openOrder.is_trigger && Number.isFinite(liveOrderSize) && liveOrderSize > 0 && Number.isFinite(liveTriggerPrice) && liveTriggerPrice > 0 && liveTriggerKind === leg.kind && observedProtectiveGroupingMatches(openOrder.is_position_tpsl, leg.positionTpsl) && liveOrderSize === leg.size && liveTriggerPrice === leg.triggerPrice;
96556
97327
  if (!trusted) {
96557
97328
  const reservedUntrustedExposure = Number.isFinite(liveOrderSize) && liveOrderSize > 0 ? Math.max(leg.size, liveOrderSize) : leg.size;
96558
97329
  remainingByKind[leg.kind] = Math.max(
@@ -96969,7 +97740,7 @@ var init_runtime_execution = __esm({
96969
97740
  const triggerPrice = Number(liveOrder.trigger_px);
96970
97741
  const size = Number(liveOrder.sz);
96971
97742
  const liveSide = String(liveOrder.side).trim().toLowerCase();
96972
- const isTrustedProtectiveOrder = String(liveOrder.coin).trim().toUpperCase() === symbol2.trim().toUpperCase() && (isLong ? liveSide === "a" || liveSide === "sell" : liveSide === "b" || liveSide === "buy") && liveOrder.reduce_only && liveOrder.is_trigger && liveOrder.trigger_kind === "sl" && liveOrder.is_position_tpsl === record5.positionTpsl && Number.isFinite(size) && size > 0 && Number.isFinite(triggerPrice) && triggerPrice > 0;
97743
+ const isTrustedProtectiveOrder = String(liveOrder.coin).trim().toUpperCase() === symbol2.trim().toUpperCase() && (isLong ? liveSide === "a" || liveSide === "sell" : liveSide === "b" || liveSide === "buy") && liveOrder.reduce_only && liveOrder.is_trigger && liveOrder.trigger_kind === "sl" && observedProtectiveGroupingMatches(liveOrder.is_position_tpsl, record5.positionTpsl) && Number.isFinite(size) && size > 0 && Number.isFinite(triggerPrice) && triggerPrice > 0;
96973
97744
  if (isTrustedProtectiveOrder && triggerPrice === record5.triggerPrice && size === record5.size) {
96974
97745
  eligible.push(record5);
96975
97746
  } else {
@@ -97483,10 +98254,18 @@ var init_runtime_execution = __esm({
97483
98254
  }
97484
98255
  };
97485
98256
  clientExecutionMutations = /* @__PURE__ */ new Map();
98257
+ CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE = "Another exchange action for this profile is still in progress.";
97486
98258
  withClientExecutionMutation = async (request, work) => {
97487
98259
  const key = String(request.profileId).trim();
97488
- const previous = clientExecutionMutations.get(key);
97489
- const pending3 = (previous ?? Promise.resolve()).catch(() => void 0).then(() => {
98260
+ const previous = clientExecutionMutations.get(key) ?? Promise.resolve();
98261
+ let abandoned = false;
98262
+ let startTurn;
98263
+ const turn = new Promise((resolve14) => {
98264
+ startTurn = resolve14;
98265
+ });
98266
+ const pending3 = previous.catch(() => void 0).then(async () => {
98267
+ if (abandoned) return void 0;
98268
+ startTurn();
97490
98269
  throwIfAborted2(request.signal);
97491
98270
  if (request.shouldCancelBeforeExchangeOrderDispatch?.()) {
97492
98271
  throw new Error(CLIENT_RUNTIME_WINDOW_HANDOFF_BEFORE_PLAN_DISPATCH);
@@ -97494,12 +98273,46 @@ var init_runtime_execution = __esm({
97494
98273
  return work();
97495
98274
  });
97496
98275
  clientExecutionMutations.set(key, pending3);
98276
+ const waitMs = runtime_policy_generated_default2.trading.engine.client_runtime.execution_mutation_queue.wait_seconds * 1e3;
97497
98277
  try {
98278
+ await new Promise((resolve14, reject) => {
98279
+ const signal = request.signal;
98280
+ const finish = () => {
98281
+ clearTimeout(timer);
98282
+ signal?.removeEventListener("abort", onAbort);
98283
+ };
98284
+ const giveUp = (reason) => {
98285
+ abandoned = true;
98286
+ finish();
98287
+ reject(reason);
98288
+ };
98289
+ const onAbort = () => giveUp(
98290
+ signal?.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError")
98291
+ );
98292
+ const timer = setTimeout(() => giveUp(new Error(CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE)), waitMs);
98293
+ if (signal?.aborted) {
98294
+ onAbort();
98295
+ return;
98296
+ }
98297
+ signal?.addEventListener("abort", onAbort, { once: true });
98298
+ void turn.then(() => {
98299
+ finish();
98300
+ resolve14();
98301
+ });
98302
+ });
97498
98303
  return await pending3;
97499
98304
  } finally {
97500
- if (clientExecutionMutations.get(key) === pending3) clientExecutionMutations.delete(key);
98305
+ void pending3.finally(() => {
98306
+ if (clientExecutionMutations.get(key) === pending3) clientExecutionMutations.delete(key);
98307
+ }).catch(() => void 0);
97501
98308
  }
97502
98309
  };
98310
+ withClientProtectivePlanSetMutation = (request, symbol2, work) => withClientProtectivePlanSetLock(
98311
+ request.profileId,
98312
+ symbol2,
98313
+ () => withClientExecutionMutation(request, work),
98314
+ request.signal
98315
+ );
97503
98316
  allocateServerExecutionCapacity = async (authority, plans) => {
97504
98317
  if (plans.length === 0) return [];
97505
98318
  try {
@@ -97518,12 +98331,7 @@ var init_runtime_execution = __esm({
97518
98331
  }
97519
98332
  };
97520
98333
  withClientProtectiveAdoptionMutation = (profileId, work, signal) => withClientExecutionMutation({ profileId: String(profileId).trim(), signal }, work);
97521
- executeClientRuntimeDecisionLocked = (input) => withClientExecutionMutation(input, () => withClientProtectivePlanSetLock(
97522
- input.profileId,
97523
- input.executionContext.symbol,
97524
- () => executeClientRuntimeDecisionUnlocked(input),
97525
- input.signal
97526
- ));
98334
+ executeClientRuntimeDecisionLocked = (input) => withClientProtectivePlanSetMutation(input, input.executionContext.symbol, () => executeClientRuntimeDecisionUnlocked(input));
97527
98335
  SERVER_AUDIT_RECORDED_ELSEWHERE = /* @__PURE__ */ new Set([
97528
98336
  "suppressed_duplicate_decision",
97529
98337
  "same_intent_cooldown",
@@ -97671,7 +98479,7 @@ var init_runtime_execution = __esm({
97671
98479
  await sleep2(Math.min(pollMs, remaining), input.signal);
97672
98480
  }
97673
98481
  };
97674
- maintainClientRuntimeTrailingStops = (request) => withClientExecutionMutation(request, () => withClientProtectivePlanSetLock(request.profileId, request.executionContext.symbol, async () => {
98482
+ maintainClientRuntimeTrailingStops = (request) => withClientProtectivePlanSetMutation(request, request.executionContext.symbol, async () => {
97675
98483
  const context = request.executionContext;
97676
98484
  const capturedAt = Date.parse(context.decisionSnapshotCapturedAt ?? "");
97677
98485
  const maxAge = Number(context.executionFreshnessMaxAgeSeconds) * 1e3;
@@ -97708,7 +98516,7 @@ var init_runtime_execution = __esm({
97708
98516
  }
97709
98517
  };
97710
98518
  return tightenClientTrailingStops({ request: guardedRequest, currentPositionSize: context.currentPositionSize, currentPrice: context.lastPrice });
97711
- }, request.signal));
98519
+ });
97712
98520
  listPendingClientProtectiveSymbols = (profileId) => {
97713
98521
  const storage3 = resolveClientRuntimeProtectionStorage();
97714
98522
  if (!storage3) return [];
@@ -97829,7 +98637,10 @@ var init_runtime_execution = __esm({
97829
98637
  order_id: String(leg.orderId),
97830
98638
  trigger_price: String(leg.triggerPrice),
97831
98639
  size: String(leg.size),
97832
- is_trailing: leg.isTrailing
98640
+ is_trailing: leg.isTrailing,
98641
+ // A stop re-placed once stays re-placed once under the server.
98642
+ ...leg.replacedOrderId != null ? { replaced_order_id: String(leg.replacedOrderId) } : {},
98643
+ ...leg.userCancelledOrderId != null ? { user_cancelled_order_id: String(leg.userCancelledOrderId) } : {}
97833
98644
  })),
97834
98645
  ...group.pendingEntry && group.legs.length === 0 ? [
97835
98646
  ...group.pendingEntry.stopLoss.enabled ? [{
@@ -97975,7 +98786,7 @@ var init_runtime_execution = __esm({
97975
98786
  for (const symbol2 of listPendingClientProtectiveSymbols(profileId)) {
97976
98787
  throwIfAborted2(input.signal);
97977
98788
  const retired = [];
97978
- const reports = await withClientExecutionMutation({ profileId, signal: input.signal }, () => withClientProtectivePlanSetLock(profileId, symbol2, async () => {
98789
+ const reports = await withClientProtectivePlanSetMutation({ profileId, signal: input.signal }, symbol2, async () => {
97979
98790
  const groups = readFreshClientProtectiveGroups(profileId, symbol2);
97980
98791
  if (hasClientProtectiveGroupReadFailure(profileId, symbol2)) {
97981
98792
  return [{
@@ -98009,7 +98820,7 @@ var init_runtime_execution = __esm({
98009
98820
  input.reportsStale !== false
98010
98821
  )
98011
98822
  ];
98012
- }, input.signal));
98823
+ });
98013
98824
  results.push({ symbol: symbol2, reports, ...retired.length > 0 ? { retired } : {} });
98014
98825
  }
98015
98826
  return results;
@@ -99008,13 +99819,13 @@ var init_runtime_execution = __esm({
99008
99819
  const livePositionSize = Number(liveSnapshot.size);
99009
99820
  const liveDirectionMatches = Number.isFinite(livePositionSize) && (isLong ? livePositionSize > 0 : livePositionSize < 0);
99010
99821
  const kind = triggerInput.isTakeProfit ? "tp" : "sl";
99011
- const alreadyProtected = [
99012
- ...readClientProtectiveGroups(
99822
+ const alreadyProtected = (liveDirectionMatches ? (await storedClientProtectiveCover(
99823
+ input,
99824
+ readClientProtectiveGroups(
99013
99825
  String(input.profileId).trim(),
99014
99826
  input.executionContext.symbol
99015
- ).flatMap((group) => group.legs),
99016
- ...activeLegs
99017
- ].filter((leg2) => leg2.kind === kind).reduce((total, leg2) => total + leg2.size, 0);
99827
+ ).flatMap((group) => group.legs)
99828
+ ))[kind] : 0) + activeLegs.filter((leg2) => leg2.kind === kind).reduce((total, leg2) => total + leg2.size, 0);
99018
99829
  const liveExposure = Math.abs(livePositionSize);
99019
99830
  const availableExposure = Math.max(0, liveExposure - alreadyProtected);
99020
99831
  const legSize = roundAssetSize(
@@ -99380,9 +100191,12 @@ var init_runtime_execution = __esm({
99380
100191
  let maxOrderNotional = 0;
99381
100192
  let minOrderNotional = 0;
99382
100193
  let executionReferencePrice = Number(intent.source_price);
100194
+ let dispatchedOrder = null;
99383
100195
  if (reconciliation && typeof reconciliation === "object" && !Array.isArray(reconciliation)) {
100196
+ const record5 = reconciliation;
100197
+ const copiedNowServed = typeof record5.copied_now === "number" && Number.isFinite(record5.copied_now);
99384
100198
  desiredPosition = Number(
99385
- reconciliation.desired_destination_position_after
100199
+ record5.target_space === "copied" ? copiedNowServed ? record5.copied_target_after : Number.NaN : record5.desired_destination_position_after
99386
100200
  );
99387
100201
  maxOrderNotional = Number(
99388
100202
  reconciliation.max_order_notional_usdc
@@ -99427,6 +100241,11 @@ var init_runtime_execution = __esm({
99427
100241
  if (!Number.isFinite(executionReferencePrice) || executionReferencePrice <= 0) {
99428
100242
  throw new Error("Copy Trading private-node execution mark was unavailable.");
99429
100243
  }
100244
+ desiredPosition = positionSpaceCopyTarget(
100245
+ reconciliation,
100246
+ desiredPosition,
100247
+ actualPosition
100248
+ );
99430
100249
  const liveDelta = desiredPosition - actualPosition;
99431
100250
  const tolerance = Math.max(1e-12, Math.abs(desiredPosition) * 1e-9);
99432
100251
  if (Math.abs(liveDelta) <= tolerance) {
@@ -99535,6 +100354,13 @@ var init_runtime_execution = __esm({
99535
100354
  intent.sanitized_metadata?.client_mutation_id,
99536
100355
  intent.sanitized_metadata?.client_order_id
99537
100356
  );
100357
+ dispatchedOrder = {
100358
+ quantized_size: destinationSize,
100359
+ ...desiredPosition != null && Number.isFinite(desiredPosition) && actualPosition != null && Number.isFinite(actualPosition) ? {
100360
+ desired_destination_position_after: desiredPosition,
100361
+ actual_destination_position: actualPosition
100362
+ } : {}
100363
+ };
99538
100364
  const response = await executeClientMarketOrder({
99539
100365
  profileId: String(input.profileId),
99540
100366
  runtimeSessionId: input.runtimeSessionId,
@@ -99565,6 +100391,7 @@ var init_runtime_execution = __esm({
99565
100391
  signal: input.signal,
99566
100392
  onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action")
99567
100393
  });
100394
+ const filledSize = _extractFilledSize(response);
99568
100395
  return {
99569
100396
  status: "executed",
99570
100397
  orderId: _extractOrderId(response),
@@ -99577,7 +100404,14 @@ var init_runtime_execution = __esm({
99577
100404
  quantized_size: destinationSize,
99578
100405
  sz_decimals: sizePrecision.sizeDecimals,
99579
100406
  rounding_mode: sizePrecision.roundingMode,
99580
- execution_reference_price: executionReferencePrice
100407
+ execution_reference_price: executionReferencePrice,
100408
+ // The server records the executed change in the copied-position
100409
+ // ledger from these values.
100410
+ ...filledSize != null ? { filled_size: filledSize } : {},
100411
+ ...desiredPosition != null && Number.isFinite(desiredPosition) && actualPosition != null && Number.isFinite(actualPosition) ? {
100412
+ desired_destination_position_after: desiredPosition,
100413
+ actual_destination_position: actualPosition
100414
+ } : {}
99581
100415
  }
99582
100416
  };
99583
100417
  } catch (error48) {
@@ -99587,7 +100421,10 @@ var init_runtime_execution = __esm({
99587
100421
  return {
99588
100422
  status: "failed",
99589
100423
  orderId: null,
99590
- message: error48 instanceof Error ? error48.message : "Copy Trading intent execution failed."
100424
+ message: error48 instanceof Error ? error48.message : "Copy Trading intent execution failed.",
100425
+ // When the order reached the exchange after all, the server recovers it
100426
+ // from the durable mutation and records this order in the ledger.
100427
+ ...dispatchedOrder ? { executionMetadata: dispatchedOrder } : {}
99591
100428
  };
99592
100429
  }
99593
100430
  };
@@ -101887,7 +102724,7 @@ var require_react = __commonJS({
101887
102724
  });
101888
102725
 
101889
102726
  // lib/runtime/client-runtime-status-store.ts
101890
- var import_react, finiteOrNull, readMode, orderKey, sameOwnerSeries, hasGenerations, compareClientRuntimeStatusOrder, sameGenerations, LIVENESS_CLOCK_FIELDS, sameValue, sameVisibleState, definedFields, ClientRuntimeStatusStore, clientRuntimeStatusStore;
102727
+ var import_react, finiteOrNull2, readMode, orderKey, sameOwnerSeries, hasGenerations, compareClientRuntimeStatusOrder, sameGenerations, LIVENESS_CLOCK_FIELDS, sameValue, sameVisibleState, definedFields, ClientRuntimeStatusStore, clientRuntimeStatusStore;
101891
102728
  var init_client_runtime_status_store = __esm({
101892
102729
  "lib/runtime/client-runtime-status-store.ts"() {
101893
102730
  "use strict";
@@ -101896,7 +102733,7 @@ var init_client_runtime_status_store = __esm({
101896
102733
  init_define_VTX_PI_MODEL_POLICY();
101897
102734
  import_react = __toESM(require_react(), 1);
101898
102735
  init_status_contract();
101899
- finiteOrNull = (value) => {
102736
+ finiteOrNull2 = (value) => {
101900
102737
  const parsed = Number(value);
101901
102738
  return value === null || value === void 0 || value === "" || !Number.isFinite(parsed) ? null : parsed;
101902
102739
  };
@@ -101905,9 +102742,9 @@ var init_client_runtime_status_store = __esm({
101905
102742
  return normalized === "client" || normalized === "server" ? normalized : null;
101906
102743
  };
101907
102744
  orderKey = (status) => ({
101908
- owner: finiteOrNull(status.owner_generation),
101909
- intent: finiteOrNull(status.intent_generation),
101910
- time: finiteOrNull(status.server_time),
102745
+ owner: finiteOrNull2(status.owner_generation),
102746
+ intent: finiteOrNull2(status.intent_generation),
102747
+ time: finiteOrNull2(status.server_time),
101911
102748
  mode: readMode(status.execution_mode)
101912
102749
  });
101913
102750
  sameOwnerSeries = (left, right) => left.mode === null || right.mode === null || left.mode === right.mode;
@@ -103659,7 +104496,7 @@ var init_constraint_contract = __esm({
103659
104496
  });
103660
104497
 
103661
104498
  // lib/runtime/client-account-report.ts
103662
- var sumPositionUnrealizedPnl2, resolveTotalUnrealizedPnl2, buildPromptParityAccountContext, finiteOrNull2, buildClientExchangeSnapshot;
104499
+ var sumPositionUnrealizedPnl2, resolveTotalUnrealizedPnl2, buildPromptParityAccountContext, finiteOrNull3, buildClientExchangeSnapshot;
103663
104500
  var init_client_account_report = __esm({
103664
104501
  "lib/runtime/client-account-report.ts"() {
103665
104502
  "use strict";
@@ -103709,7 +104546,7 @@ var init_client_account_report = __esm({
103709
104546
  }
103710
104547
  return context;
103711
104548
  };
103712
- finiteOrNull2 = (value) => {
104549
+ finiteOrNull3 = (value) => {
103713
104550
  const parsed = Number(value);
103714
104551
  return Number.isFinite(parsed) ? parsed : null;
103715
104552
  };
@@ -103718,17 +104555,17 @@ var init_client_account_report = __esm({
103718
104555
  captured_at: input.capturedAt,
103719
104556
  wallet_address: input.walletAddress,
103720
104557
  symbol: input.symbol,
103721
- mark_price: finiteOrNull2(input.markPrice),
104558
+ mark_price: finiteOrNull3(input.markPrice),
103722
104559
  effective_taker_rates: input.effectiveTakerRates,
103723
104560
  account_summary: {
103724
- account_value: finiteOrNull2(input.accountSummary.account_value),
104561
+ account_value: finiteOrNull3(input.accountSummary.account_value),
103725
104562
  perp_dex_accounts: input.accountSummary.perp_dex_accounts,
103726
- total_margin_used: finiteOrNull2(input.accountSummary.total_margin_used),
103727
- available_margin: finiteOrNull2(input.accountSummary.available_margin),
103728
- withdrawable: finiteOrNull2(input.accountSummary.withdrawable),
103729
- cross_margin_ratio: finiteOrNull2(input.accountSummary.cross_margin_ratio),
103730
- maintenance_margin: finiteOrNull2(input.accountSummary.maintenance_margin),
103731
- cross_account_leverage: finiteOrNull2(input.accountSummary.cross_account_leverage),
104563
+ total_margin_used: finiteOrNull3(input.accountSummary.total_margin_used),
104564
+ available_margin: finiteOrNull3(input.accountSummary.available_margin),
104565
+ withdrawable: finiteOrNull3(input.accountSummary.withdrawable),
104566
+ cross_margin_ratio: finiteOrNull3(input.accountSummary.cross_margin_ratio),
104567
+ maintenance_margin: finiteOrNull3(input.accountSummary.maintenance_margin),
104568
+ cross_account_leverage: finiteOrNull3(input.accountSummary.cross_account_leverage),
103732
104569
  total_unrealized_pnl: resolveTotalUnrealizedPnl2(input.accountSummary, input.positions),
103733
104570
  account_mode: typeof input.accountSummary.account_mode === "string" ? input.accountSummary.account_mode : typeof input.accountSummary.accountMode === "string" ? input.accountSummary.accountMode : null,
103734
104571
  mode_source: typeof input.accountSummary.mode_source === "string" ? input.accountSummary.mode_source : typeof input.accountSummary.modeSource === "string" ? input.accountSummary.modeSource : null
@@ -103736,13 +104573,13 @@ var init_client_account_report = __esm({
103736
104573
  positions: input.positions.map((position) => ({
103737
104574
  symbol: normalizeHyperliquidMarketSymbol(position.symbol),
103738
104575
  size: Number(position.size) || 0,
103739
- entry_price: finiteOrNull2(position.entry_price),
103740
- unrealized_pnl: finiteOrNull2(position.unrealized_pnl),
103741
- realized_pnl: finiteOrNull2(position.realized_pnl),
103742
- leverage: finiteOrNull2(position.leverage),
103743
- margin_used: finiteOrNull2(position.margin_used),
103744
- liquidation_price: finiteOrNull2(position.liquidation_price),
103745
- funding_usdc: finiteOrNull2(position.funding_usdc)
104576
+ entry_price: finiteOrNull3(position.entry_price),
104577
+ unrealized_pnl: finiteOrNull3(position.unrealized_pnl),
104578
+ realized_pnl: finiteOrNull3(position.realized_pnl),
104579
+ leverage: finiteOrNull3(position.leverage),
104580
+ margin_used: finiteOrNull3(position.margin_used),
104581
+ liquidation_price: finiteOrNull3(position.liquidation_price),
104582
+ funding_usdc: finiteOrNull3(position.funding_usdc)
103746
104583
  }))
103747
104584
  });
103748
104585
  }
@@ -116917,42 +117754,44 @@ var init_engine = __esm({
116917
117754
  this._deviceSecrets = postClaimSecretsState.normalized;
116918
117755
  }
116919
117756
  this._assertStartAttemptActive(startController, "post_claim_hydration");
116920
- const bindingPreferences = await this._awaitStartStage(
116921
- getFreshPreferences(
116922
- void 0,
116923
- Number(profileId),
116924
- void 0,
116925
- false,
116926
- { schedulerInstanceId: this._instanceId }
116927
- ),
116928
- startController,
116929
- "signer_binding_preferences"
116930
- );
116931
- const bindingWalletAddress = String(
116932
- bindingPreferences.preferences?.hyperliquid_wallet_address || ""
116933
- ).trim();
116934
- const bindingSigningKey = String(
116935
- this._deviceSecrets?.hyperliquidSigningKey || ""
116936
- ).trim();
116937
- if (!bindingSigningKey) {
116938
- throw new Error("Missing Hyperliquid signing key after runtime start.");
116939
- }
116940
- const bindingConfig = await this._awaitStartStage(
116941
- getLLMConfig(void 0, Number(profileId)),
116942
- startController,
116943
- "signer_binding_config"
116944
- );
116945
- await this._awaitStartStage(
116946
- assertBrowserHyperliquidSignerWalletBinding({
116947
- // Start authorizes trading: never held behind panel reads.
116948
- publicRequestPriority: "trading_execute",
116949
- signingKey: bindingSigningKey,
116950
- walletAddress: bindingWalletAddress,
116951
- config: bindingConfig
116952
- }),
116953
- startController,
116954
- "signer_binding"
116955
- );
117757
+ if (this._expectedExecutionMode !== "server") {
117758
+ const bindingPreferences = await this._awaitStartStage(
117759
+ getFreshPreferences(
117760
+ void 0,
117761
+ Number(profileId),
117762
+ void 0,
117763
+ false,
117764
+ { schedulerInstanceId: this._instanceId }
117765
+ ),
117766
+ startController,
117767
+ "signer_binding_preferences"
117768
+ );
117769
+ const bindingWalletAddress = String(
117770
+ bindingPreferences.preferences?.hyperliquid_wallet_address || ""
117771
+ ).trim();
117772
+ const bindingSigningKey = String(
117773
+ this._deviceSecrets?.hyperliquidSigningKey || ""
117774
+ ).trim();
117775
+ if (!bindingSigningKey) {
117776
+ throw new Error("Missing Hyperliquid signing key after runtime start.");
117777
+ }
117778
+ const bindingConfig = await this._awaitStartStage(
117779
+ getLLMConfig(void 0, Number(profileId)),
117780
+ startController,
117781
+ "signer_binding_config"
117782
+ );
117783
+ await this._awaitStartStage(
117784
+ assertBrowserHyperliquidSignerWalletBinding({
117785
+ // Start authorizes trading: never held behind panel reads.
117786
+ publicRequestPriority: "trading_execute",
117787
+ signingKey: bindingSigningKey,
117788
+ walletAddress: bindingWalletAddress,
117789
+ config: bindingConfig
117790
+ }),
117791
+ startController,
117792
+ "signer_binding"
117793
+ );
117794
+ }
116956
117795
  this._assertStartAttemptActive(startController, "signer_binding");
116957
117796
  if (this._mode === "trader" && options.claimKind === "explicit") {
116958
117797
  clearClientRuntimeKillswitchBlock(profileId);