@kynver-app/runtime 0.1.48 → 0.1.49

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/dist/cli.js CHANGED
@@ -1906,7 +1906,7 @@ function inferModelRoutingFromTask(task) {
1906
1906
  rule: "lane:landing"
1907
1907
  };
1908
1908
  }
1909
- if (ref.includes("review") || title.startsWith("review ") || roleLane.includes("review")) {
1909
+ if (ref.includes("review") || /^review[\s:]/.test(title) || roleLane.includes("review")) {
1910
1910
  if (isOpusLane(ref, title) || roleLane === "deep_reviewer") {
1911
1911
  return { model: "claude-opus-4-7", provider: "claude", rule: "lane:deep_review" };
1912
1912
  }
@@ -2369,6 +2369,11 @@ function isHarnessExpertReviewWorker(worker) {
2369
2369
 
2370
2370
  // src/pr-handoff/pr-handoff-assess.ts
2371
2371
  var REVIEW_LANE_RULE = /^(lane:)?(review|deep_review|planning|landing)(:|$)/i;
2372
+ var REVIEW_PERSONA_SLUGS = /* @__PURE__ */ new Set(["lorentz", "sentinel"]);
2373
+ var NO_PR_COMMITS_BETWEEN_RE = /no commits between/i;
2374
+ function isGhNoCommitsBetweenError(detail) {
2375
+ return Boolean(detail && NO_PR_COMMITS_BETWEEN_RE.test(detail));
2376
+ }
2372
2377
  function trimOrNull4(value) {
2373
2378
  if (typeof value !== "string") return null;
2374
2379
  const trimmed = value.trim();
@@ -2387,8 +2392,30 @@ function extractPrUrlFromText(value) {
2387
2392
  );
2388
2393
  return m ? trimOrNull4(m[0]) : null;
2389
2394
  }
2390
- function hasWorkProduct(snapshot) {
2395
+ function countCommitsAheadOfBase(worktreePath, baseRef, exec) {
2396
+ const base = baseRef.trim();
2397
+ if (!base) return null;
2398
+ const count = exec.git(worktreePath, ["rev-list", "--count", `${base}..HEAD`]);
2399
+ if (count.status !== 0) return null;
2400
+ const n = Number.parseInt(count.stdout.trim(), 10);
2401
+ return Number.isFinite(n) ? n : null;
2402
+ }
2403
+ function isReviewArtifactWorker(worker, snapshot) {
2404
+ if (snapshot.changedFiles.length > 0) return false;
2405
+ const persona = trimOrNull4(worker.personaSlug)?.toLowerCase();
2406
+ if (persona && REVIEW_PERSONA_SLUGS.has(persona)) return true;
2407
+ const rule = trimOrNull4(worker.routingRule) ?? "";
2408
+ if (rule && REVIEW_LANE_RULE.test(rule)) return true;
2409
+ return false;
2410
+ }
2411
+ function hasWorkProduct(snapshot, options) {
2391
2412
  if (snapshot.changedFiles.length > 0) return true;
2413
+ const baseRef = trimOrNull4(options?.baseRef);
2414
+ if (baseRef && options?.exec && options.worktreePath) {
2415
+ const ahead = countCommitsAheadOfBase(options.worktreePath, baseRef, options.exec);
2416
+ if (ahead === 0) return false;
2417
+ if (ahead !== null && ahead > 0) return true;
2418
+ }
2392
2419
  if (trimOrNull4(snapshot.headCommit)) return true;
2393
2420
  if (committedHead(snapshot.gitAncestry)) return true;
2394
2421
  return false;
@@ -2409,6 +2436,13 @@ function assessPrHandoffRequirement(input) {
2409
2436
  if (rule && REVIEW_LANE_RULE.test(rule)) {
2410
2437
  return { required: false, reason: "review_lane" };
2411
2438
  }
2439
+ const workerCtx = input.worker ?? {
2440
+ personaSlug: input.personaSlug,
2441
+ routingRule: input.routingRule
2442
+ };
2443
+ if (isReviewArtifactWorker(workerCtx, input.snapshot)) {
2444
+ return { required: false, reason: "review_artifact" };
2445
+ }
2412
2446
  if (trimOrNull4(input.patchPath) || trimOrNull4(input.artifactBundlePath)) {
2413
2447
  return { required: false, reason: "patch_or_bundle" };
2414
2448
  }
@@ -2416,7 +2450,12 @@ function assessPrHandoffRequirement(input) {
2416
2450
  if (prUrl) {
2417
2451
  return { required: false, reason: "already_has_pr" };
2418
2452
  }
2419
- if (!hasWorkProduct(input.snapshot)) {
2453
+ const workProductOpts = input.exec && input.baseRef ? {
2454
+ baseRef: input.baseRef,
2455
+ exec: input.exec,
2456
+ worktreePath: input.snapshot.worktreePath
2457
+ } : void 0;
2458
+ if (!hasWorkProduct(input.snapshot, workProductOpts)) {
2420
2459
  return { required: false, reason: "no_work_product" };
2421
2460
  }
2422
2461
  return { required: true, snapshot: input.snapshot };
@@ -2625,15 +2664,19 @@ function ensurePrReadyHandoff(input, exec = defaultPrHandoffExec) {
2625
2664
  prUrl: prUrlHint,
2626
2665
  headCommit: null
2627
2666
  });
2667
+ const baseRef = input.run.baseCommit?.trim() || input.run.base?.trim() || "origin/main";
2628
2668
  const requirement = assessPrHandoffRequirement({
2629
2669
  dispatched: input.worker.dispatched,
2630
2670
  routingRule: input.worker.routingRule,
2671
+ personaSlug: input.worker.personaSlug,
2631
2672
  prUrl: prUrlHint,
2632
2673
  taskTitle: input.worker.taskTitle,
2633
2674
  executorRef: input.worker.executorRef,
2634
2675
  parentTaskId: input.worker.parentTaskId,
2635
- personaSlug: input.worker.personaSlug,
2636
2676
  taskPrUrl: input.worker.taskPrUrl,
2677
+ baseRef,
2678
+ exec,
2679
+ worker: input.worker,
2637
2680
  snapshot
2638
2681
  });
2639
2682
  if (!requirement.required) {
@@ -2718,6 +2761,14 @@ function ensurePrReadyHandoff(input, exec = defaultPrHandoffExec) {
2718
2761
  exec
2719
2762
  });
2720
2763
  if (!pr.ok || !pr.prUrl) {
2764
+ if (isGhNoCommitsBetweenError(pr.detail)) {
2765
+ return {
2766
+ ok: true,
2767
+ headCommit: headCommit ?? void 0,
2768
+ committed,
2769
+ pushed
2770
+ };
2771
+ }
2721
2772
  const dirty = snapshot.changedFiles.length;
2722
2773
  const detail = dirty ? `${dirty} uncommitted change(s) and no PR URL after handoff attempt` : "no PR URL after handoff attempt";
2723
2774
  return {
@@ -6586,7 +6637,12 @@ var defaultRuntimeTakeoverProbes = {
6586
6637
  openclawCronSecret: Boolean(process.env.OPENCLAW_CRON_SECRET?.trim()),
6587
6638
  kynverHarnessRoot: process.env.KYNVER_HARNESS_ROOT?.trim() || void 0,
6588
6639
  opusHarnessRoot: process.env.OPUS_HARNESS_ROOT?.trim() || void 0,
6589
- kynverSchedulerProvider: process.env.KYNVER_SCHEDULER_PROVIDER?.trim() || void 0
6640
+ kynverSchedulerProvider: process.env.KYNVER_SCHEDULER_PROVIDER?.trim() || void 0,
6641
+ qstashTokenPresent: Boolean(process.env.QSTASH_TOKEN?.trim()),
6642
+ kynverHostedDeployment: (() => {
6643
+ const v = process.env.KYNVER_HOSTED_DEPLOYMENT?.trim().toLowerCase();
6644
+ return v === "1" || v === "true" || v === "yes";
6645
+ })()
6590
6646
  }),
6591
6647
  harnessRoot: () => resolveHarnessRoot(),
6592
6648
  legacyOpenclawHarnessRoot: () => path36.join(homedir6(), ".openclaw", "harness"),
@@ -6596,10 +6652,76 @@ var defaultRuntimeTakeoverProbes = {
6596
6652
  vercelWhoami: () => captureCommand("vercel", ["whoami"])
6597
6653
  };
6598
6654
 
6599
- // src/doctor/runtime-takeover.ts
6655
+ // src/doctor/runtime-takeover-scheduler.ts
6600
6656
  function check(partial) {
6601
6657
  return partial;
6602
6658
  }
6659
+ function assessRuntimeTakeoverScheduler(env, ctx) {
6660
+ const runnerOpenclaw = env.kynverSchedulerProvider === "openclaw-cron";
6661
+ const runnerQstash = env.kynverSchedulerProvider === "qstash";
6662
+ const hostedDeployment = Boolean(env.qstashTokenPresent) || Boolean(env.kynverHostedDeployment);
6663
+ const daemonDispatchReady = Boolean(ctx.agentOsId?.trim()) && Boolean(ctx.apiBaseUrl?.trim()) && ctx.hasScopedRunnerToken;
6664
+ const deploymentNeedsQstash = hostedDeployment && !env.qstashTokenPresent && env.kynverSchedulerProvider !== "qstash";
6665
+ const deploymentOpenclaw = hostedDeployment && env.kynverSchedulerProvider === "openclaw-cron";
6666
+ if (runnerOpenclaw) {
6667
+ return check({
6668
+ id: "hotspot_openclaw_scheduler",
6669
+ label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
6670
+ status: "warn",
6671
+ summary: "KYNVER_SCHEDULER_PROVIDER=openclaw-cron on this runner \u2014 hosted dispatch still depends on the OpenClaw local-cron adapter",
6672
+ remediation: "Unset KYNVER_SCHEDULER_PROVIDER on user runners. Use `kynver daemon` (pipeline-tick \u2192 operator/tick). On the Kynver server set KYNVER_SCHEDULER_PROVIDER=qstash when QStash is configured.",
6673
+ details: { schedulerProvider: env.kynverSchedulerProvider ?? null, hostedDeployment }
6674
+ });
6675
+ }
6676
+ if (deploymentOpenclaw || deploymentNeedsQstash) {
6677
+ return check({
6678
+ id: "hotspot_openclaw_scheduler",
6679
+ label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
6680
+ status: "warn",
6681
+ summary: deploymentOpenclaw ? "Hosted deployment has KYNVER_SCHEDULER_PROVIDER=openclaw-cron \u2014 AgentOS scheduled ticks should use QStash" : "Hosted deployment without QSTASH_TOKEN \u2014 scheduler may fall back to openclaw-cron",
6682
+ remediation: "Set QSTASH_TOKEN and KYNVER_SCHEDULER_PROVIDER=qstash on the Kynver server. User runners use `kynver daemon` for dispatch and should not set a scheduler provider.",
6683
+ details: {
6684
+ schedulerProvider: env.kynverSchedulerProvider ?? null,
6685
+ qstashTokenPresent: env.qstashTokenPresent ?? false,
6686
+ hostedDeployment
6687
+ }
6688
+ });
6689
+ }
6690
+ if (daemonDispatchReady) {
6691
+ return check({
6692
+ id: "hotspot_openclaw_scheduler",
6693
+ label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
6694
+ status: "pass",
6695
+ summary: runnerQstash ? "Runner override qstash present; hosted dispatch still owned by kynver daemon pipeline-tick" : "Hosted dispatch owned by kynver daemon (pipeline-tick \u2192 operator/tick); no OpenClaw cron on runner",
6696
+ details: {
6697
+ schedulerProvider: env.kynverSchedulerProvider ?? null,
6698
+ dispatchPath: "kynver-daemon-pipeline-tick",
6699
+ hostedDeployment
6700
+ }
6701
+ });
6702
+ }
6703
+ if (!env.kynverSchedulerProvider) {
6704
+ return check({
6705
+ id: "hotspot_openclaw_scheduler",
6706
+ label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
6707
+ status: "pass",
6708
+ summary: "No KYNVER_SCHEDULER_PROVIDER on runner (expected) \u2014 finish runner setup so daemon pipeline-tick owns dispatch",
6709
+ details: { schedulerProvider: null, dispatchPath: "kynver-daemon-pipeline-tick-pending" }
6710
+ });
6711
+ }
6712
+ return check({
6713
+ id: "hotspot_openclaw_scheduler",
6714
+ label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
6715
+ status: "pass",
6716
+ summary: `KYNVER_SCHEDULER_PROVIDER=${env.kynverSchedulerProvider}`,
6717
+ details: { schedulerProvider: env.kynverSchedulerProvider ?? null }
6718
+ });
6719
+ }
6720
+
6721
+ // src/doctor/runtime-takeover.ts
6722
+ function check2(partial) {
6723
+ return partial;
6724
+ }
6603
6725
  function summarizeCounts(sections) {
6604
6726
  const counts = { pass: 0, warn: 0, fail: 0 };
6605
6727
  for (const section of sections) {
@@ -6616,14 +6738,14 @@ function assessCliPackage(probes) {
6616
6738
  const firstPath = onPath ? which.stdout.split(/\r?\n/)[0]?.trim() : void 0;
6617
6739
  const displayCliPath = firstPath ? displayUserPath(firstPath) : void 0;
6618
6740
  const checks = [
6619
- check({
6741
+ check2({
6620
6742
  id: "cli_running_version",
6621
6743
  label: "Running @kynver-app/runtime version",
6622
6744
  status: "pass",
6623
6745
  summary: `@kynver-app/runtime ${runningVersion}`,
6624
6746
  details: { version: runningVersion }
6625
6747
  }),
6626
- check({
6748
+ check2({
6627
6749
  id: "cli_on_path",
6628
6750
  label: "kynver executable on PATH",
6629
6751
  status: onPath ? "pass" : "warn",
@@ -6637,7 +6759,7 @@ function assessCliPackage(probes) {
6637
6759
  const installedVersion = versionProbe.stdout.replace(/^kynver\s+/i, "").trim() || void 0;
6638
6760
  const versionMatch = versionProbe.ok && (!installedVersion || installedVersion === runningVersion);
6639
6761
  checks.push(
6640
- check({
6762
+ check2({
6641
6763
  id: "cli_installed_version",
6642
6764
  label: "Installed kynver CLI version matches running package",
6643
6765
  status: versionMatch ? "pass" : "warn",
@@ -6655,7 +6777,7 @@ function assessUserConfig(probes) {
6655
6777
  const exists = probes.pathExists(configPath);
6656
6778
  const config = probes.loadConfig();
6657
6779
  const checks = [
6658
- check({
6780
+ check2({
6659
6781
  id: "config_file",
6660
6782
  label: "~/.kynver/config.json present",
6661
6783
  status: exists ? "pass" : "fail",
@@ -6670,7 +6792,7 @@ function assessUserConfig(probes) {
6670
6792
  const defaultRepo = config.defaultRepo?.trim();
6671
6793
  const displayDefaultRepo = defaultRepo ? displayUserPath(defaultRepo) : null;
6672
6794
  checks.push(
6673
- check({
6795
+ check2({
6674
6796
  id: "config_api_base_url",
6675
6797
  label: "Default API base URL",
6676
6798
  status: apiBaseUrl ? "pass" : "warn",
@@ -6678,7 +6800,7 @@ function assessUserConfig(probes) {
6678
6800
  remediation: apiBaseUrl ? void 0 : "Set `apiBaseUrl` via `kynver setup --api-base-url https://\u2026`.",
6679
6801
  details: { apiBaseUrl: apiBaseUrl ?? null }
6680
6802
  }),
6681
- check({
6803
+ check2({
6682
6804
  id: "config_agent_os_id",
6683
6805
  label: "Default AgentOS id",
6684
6806
  status: agentOsId ? "pass" : "warn",
@@ -6686,7 +6808,7 @@ function assessUserConfig(probes) {
6686
6808
  remediation: agentOsId ? void 0 : "Set `agentOsId` via `kynver setup --agent-os-id <uuid>`.",
6687
6809
  details: { agentOsId: agentOsId ?? null, agentOsSlug: config.agentOsSlug ?? null }
6688
6810
  }),
6689
- check({
6811
+ check2({
6690
6812
  id: "config_default_repo",
6691
6813
  label: "Default repo path",
6692
6814
  status: defaultRepo ? "pass" : "warn",
@@ -6714,7 +6836,7 @@ function assessRunnerToken(probes) {
6714
6836
  const scopedSaved = Boolean(savedToken) && (!targetAgentOsId || !savedAgentOsId || savedAgentOsId === targetAgentOsId);
6715
6837
  const hasScoped = Boolean(envToken?.startsWith("krc1.")) || scopedSaved && savedToken?.startsWith("krc1.");
6716
6838
  const checks = [
6717
- check({
6839
+ check2({
6718
6840
  id: "runner_token_scoped",
6719
6841
  label: "Scoped runner token (krc1.*) ready",
6720
6842
  status: hasScoped ? "pass" : "fail",
@@ -6727,7 +6849,7 @@ function assessRunnerToken(probes) {
6727
6849
  credentialsPath: displayCredPath
6728
6850
  }
6729
6851
  }),
6730
- check({
6852
+ check2({
6731
6853
  id: "runner_token_agent_os_match",
6732
6854
  label: "Saved runner token matches configured agentOsId",
6733
6855
  status: !savedToken || !targetAgentOsId || !savedAgentOsId || savedAgentOsId === targetAgentOsId ? "pass" : "warn",
@@ -6735,7 +6857,7 @@ function assessRunnerToken(probes) {
6735
6857
  remediation: savedToken && targetAgentOsId && savedAgentOsId && savedAgentOsId !== targetAgentOsId ? "`kynver runner credential --agent-os-id <configured-id>` to mint a workspace-bound token." : void 0,
6736
6858
  details: { configuredAgentOsId: targetAgentOsId ?? null, savedAgentOsId: savedAgentOsId ?? null }
6737
6859
  }),
6738
- check({
6860
+ check2({
6739
6861
  id: "runner_api_key_for_refresh",
6740
6862
  label: "API key available for token refresh",
6741
6863
  status: creds.hasApiKey || Boolean(process.env.KYNVER_API_KEY?.trim()) ? "pass" : "warn",
@@ -6754,7 +6876,7 @@ function assessVercelCli(probes) {
6754
6876
  id: "vercel_cli",
6755
6877
  label: "Vercel CLI",
6756
6878
  checks: [
6757
- check({
6879
+ check2({
6758
6880
  id: "vercel_installed",
6759
6881
  label: "Vercel CLI installed",
6760
6882
  status: installed ? "pass" : "warn",
@@ -6762,7 +6884,7 @@ function assessVercelCli(probes) {
6762
6884
  remediation: installed ? void 0 : "Install Vercel CLI (`npm i -g vercel`) for deploy evidence and env pulls.",
6763
6885
  details: { stderr: version.stderr || null }
6764
6886
  }),
6765
- check({
6887
+ check2({
6766
6888
  id: "vercel_authenticated",
6767
6889
  label: "Vercel CLI authenticated",
6768
6890
  status: !installed ? "warn" : whoami.ok ? "pass" : "warn",
@@ -6786,14 +6908,14 @@ function assessHarnessDirs(probes) {
6786
6908
  id: "harness_dirs",
6787
6909
  label: "Harness / daemon directories",
6788
6910
  checks: [
6789
- check({
6911
+ check2({
6790
6912
  id: "harness_root",
6791
6913
  label: "Harness root resolved",
6792
6914
  status: "pass",
6793
6915
  summary: displayHarnessRoot,
6794
6916
  details: { harnessRoot: displayHarnessRoot }
6795
6917
  }),
6796
- check({
6918
+ check2({
6797
6919
  id: "harness_runs_dir",
6798
6920
  label: "Runs directory ready",
6799
6921
  status: runsExists && probes.pathWritable(runsDir) ? "pass" : runsExists ? "warn" : "warn",
@@ -6801,7 +6923,7 @@ function assessHarnessDirs(probes) {
6801
6923
  remediation: runsExists && !probes.pathWritable(runsDir) ? `Fix permissions on ${displayRunsDir} or set KYNVER_HARNESS_ROOT to a writable path.` : void 0,
6802
6924
  details: { runsDir: displayRunsDir, exists: runsExists, writable: probes.pathWritable(runsDir) }
6803
6925
  }),
6804
- check({
6926
+ check2({
6805
6927
  id: "harness_worktrees_dir",
6806
6928
  label: "Worktrees directory ready",
6807
6929
  status: worktreesExists && probes.pathWritable(worktreesDir) ? "pass" : "warn",
@@ -6822,7 +6944,7 @@ function assessCallbackAuth(probes) {
6822
6944
  const creds = probes.readCredentials();
6823
6945
  const savedScoped = creds.runnerTokenPrefix?.startsWith("krc1.");
6824
6946
  const checks = [
6825
- check({
6947
+ check2({
6826
6948
  id: "callback_base_url",
6827
6949
  label: "Callback base URL configured",
6828
6950
  status: baseUrl ? usingLegacyBase ? "warn" : "pass" : "fail",
@@ -6833,7 +6955,7 @@ function assessCallbackAuth(probes) {
6833
6955
  baseUrl: baseUrl ?? null
6834
6956
  }
6835
6957
  }),
6836
- check({
6958
+ check2({
6837
6959
  id: "callback_auth_mode",
6838
6960
  label: "Callback auth uses scoped runner token",
6839
6961
  status: envScoped || savedScoped ? "pass" : legacySecret ? "warn" : "fail",
@@ -6849,15 +6971,22 @@ function assessCallbackAuth(probes) {
6849
6971
  }
6850
6972
  function assessOpenclawHotspots(probes) {
6851
6973
  const env = probes.envSnapshot();
6974
+ const config = probes.loadConfig();
6975
+ const creds = probes.readCredentials();
6852
6976
  const harnessRoot = probes.harnessRoot();
6853
6977
  const legacyRoot = probes.legacyOpenclawHarnessRoot();
6854
6978
  const displayHarnessRoot = redactHomePath(harnessRoot);
6855
6979
  const displayLegacyRoot = redactHomePath(legacyRoot);
6856
6980
  const displayOpusHarnessRoot = env.opusHarnessRoot ? redactHomePath(env.opusHarnessRoot) : null;
6857
6981
  const legacyHarnessActive = harnessRoot === legacyRoot && probes.pathExists(legacyRoot);
6858
- const schedulerOpenclaw = !env.kynverSchedulerProvider || env.kynverSchedulerProvider === "openclaw-cron";
6982
+ const targetAgentOsId = config.agentOsId?.trim();
6983
+ const envToken = env.kynverRunnerTokenPrefix;
6984
+ const savedToken = creds.runnerTokenPrefix;
6985
+ const savedAgentOsId = creds.runnerTokenAgentOsId;
6986
+ const scopedSaved = Boolean(savedToken) && (!targetAgentOsId || !savedAgentOsId || savedAgentOsId === targetAgentOsId);
6987
+ const hasScopedRunnerToken = Boolean(envToken?.startsWith("krc1.")) || scopedSaved && Boolean(savedToken?.startsWith("krc1."));
6859
6988
  const checks = [
6860
- check({
6989
+ check2({
6861
6990
  id: "hotspot_legacy_harness_root",
6862
6991
  label: "Legacy ~/.openclaw/harness still active",
6863
6992
  status: legacyHarnessActive ? "warn" : "pass",
@@ -6865,7 +6994,7 @@ function assessOpenclawHotspots(probes) {
6865
6994
  remediation: legacyHarnessActive ? "Set KYNVER_HARNESS_ROOT=~/.kynver/harness (or run setup), migrate artifacts, retire OPUS_HARNESS_ROOT." : env.opusHarnessRoot ? "Prefer KYNVER_HARNESS_ROOT over OPUS_HARNESS_ROOT." : void 0,
6866
6995
  details: { harnessRoot: displayHarnessRoot, legacyRoot: displayLegacyRoot, opusHarnessRoot: displayOpusHarnessRoot }
6867
6996
  }),
6868
- check({
6997
+ check2({
6869
6998
  id: "hotspot_openclaw_env_secrets",
6870
6999
  label: "OpenClaw deployment secrets in runner env",
6871
7000
  status: env.openclawCronSecret || env.openclawCronFireBaseUrl ? "warn" : "pass",
@@ -6875,15 +7004,12 @@ function assessOpenclawHotspots(probes) {
6875
7004
  ].filter(Boolean).join("; ") : "No OpenClaw cron env overrides on this runner",
6876
7005
  remediation: env.openclawCronSecret || env.openclawCronFireBaseUrl ? "Move to KYNVER_API_URL + scoped runner tokens; unset OpenClaw cron env on user-hosted runners." : void 0
6877
7006
  }),
6878
- check({
6879
- id: "hotspot_openclaw_scheduler",
6880
- label: "openclaw-cron scheduler dependency (deployment)",
6881
- status: schedulerOpenclaw ? "warn" : "pass",
6882
- summary: schedulerOpenclaw ? env.kynverSchedulerProvider === "openclaw-cron" ? "KYNVER_SCHEDULER_PROVIDER=openclaw-cron \u2014 AgentOS ticks still routed via OpenClaw local cron adapter" : "KYNVER_SCHEDULER_PROVIDER unset \u2014 server may fall back to openclaw-cron when QStash is absent" : `KYNVER_SCHEDULER_PROVIDER=${env.kynverSchedulerProvider}`,
6883
- remediation: schedulerOpenclaw ? "On Kynver-hosted scheduler: set KYNVER_SCHEDULER_PROVIDER=qstash where QStash is configured; retire openclaw-cron stub when runtime daemon owns dispatch." : void 0,
6884
- details: { schedulerProvider: env.kynverSchedulerProvider ?? null }
7007
+ assessRuntimeTakeoverScheduler(env, {
7008
+ agentOsId: targetAgentOsId ?? null,
7009
+ apiBaseUrl: config.apiBaseUrl?.trim() ?? env.kynverApiUrl ?? null,
7010
+ hasScopedRunnerToken
6885
7011
  }),
6886
- check({
7012
+ check2({
6887
7013
  id: "hotspot_lease_source_names",
6888
7014
  label: "Harness lease/completion source names",
6889
7015
  status: "pass",