@outerlayer/cli 0.33.0-next.20261023120437 → 0.33.0-next.20261023151440

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +12 -2
  2. package/dist/build-info.json +1 -1
  3. package/dist/{check-4QNLMDP7.js → check-XPMN4GHD.js} +9 -9
  4. package/dist/{chunk-FZUFUVLK.js → chunk-2LFWCIIE.js} +5 -5
  5. package/dist/{chunk-IUPY54BZ.js → chunk-4YLL2E7Y.js} +2 -2
  6. package/dist/{chunk-2JLM4GUF.js → chunk-BLHUFOOB.js} +2 -2
  7. package/dist/{chunk-MZYOUIY5.js → chunk-DA3PLB5N.js} +1 -1
  8. package/dist/chunk-RZOO7X4G.js +81 -0
  9. package/dist/{chunk-SQQD5MST.js → chunk-VMIOUVJF.js} +1 -1
  10. package/dist/{chunk-YXMGHGHR.js → chunk-VSLJ6PPG.js} +6 -2
  11. package/dist/{chunk-YSM4EEUK.js → chunk-YY3OQJ4X.js} +83 -17
  12. package/dist/{chunk-XCRET2GZ.js → chunk-Z57X4KNC.js} +4 -3
  13. package/dist/{cli-BC7JWQUQ.js → cli-65ZQJ622.js} +43 -43
  14. package/dist/{command-SQ4466SL.js → command-QENZQGZL.js} +3 -3
  15. package/dist/{container-start-AQJ64LCF.js → container-start-RVH5743X.js} +34 -11
  16. package/dist/{doctor-4YZOP343.js → doctor-MFLM7DMY.js} +4 -4
  17. package/dist/{governing-source-IRRP7G5G.js → governing-source-INEXO2CK.js} +2 -2
  18. package/dist/index.js +1 -1
  19. package/dist/{init-63X6ECKF.js → init-VWJIINBC.js} +3 -3
  20. package/dist/{init-T64C4MID.js → init-WIHSXL74.js} +3 -3
  21. package/dist/{init-cmd-7CGCDLBZ.js → init-cmd-3VWJUWXA.js} +2 -2
  22. package/dist/{loop-YJF27PUS.js → loop-5QV4VZOF.js} +9 -9
  23. package/dist/{machine-VBITNWTR.js → machine-XTSUAX3K.js} +3 -3
  24. package/dist/{runner-key-5SGBLTDJ.js → runner-key-N4IIFMUX.js} +3 -3
  25. package/dist/{spec-cmd-E6SINBX6.js → spec-cmd-7W4ERDL7.js} +1 -1
  26. package/dist/{status-AYHBGIAP.js → status-VBUCLDN5.js} +4 -4
  27. package/dist/{work-claim-cmd-CIVWB7EJ.js → work-claim-cmd-G3DC5LJK.js} +7 -5
  28. package/dist/{work-cmd-OO6K6ELP.js → work-cmd-J2LJ3V4A.js} +1 -1
  29. package/dist/{work-comment-cmd-SY7NY2CR.js → work-comment-cmd-QEZHRXC5.js} +1 -1
  30. package/dist/{work-demo-cmd-Y7EU335L.js → work-demo-cmd-A7XE4NKA.js} +1 -1
  31. package/dist/{work-logs-cmd-PWOFLTGD.js → work-logs-cmd-UA5PAXRP.js} +1 -1
  32. package/dist/{work-open-pr-cmd-AJUTKYWN.js → work-open-pr-cmd-ZYKNAJJM.js} +1 -1
  33. package/dist/{work-proofs-cmd-6W6DDAP6.js → work-proofs-cmd-XBESDEPM.js} +1 -1
  34. package/dist/{work-stop-cmd-WZHBEKE4.js → work-stop-cmd-ZDIW3MVX.js} +1 -1
  35. package/package.json +1 -1
  36. package/dist/chunk-YGZLRX5U.js +0 -36
package/README.md CHANGED
@@ -168,9 +168,19 @@ content:
168
168
  fetches the package's dependencies, and both npm runs use this user's npm
169
169
  configuration, including any registry token in `~/.npmrc`. Set
170
170
  `runner.autoUpdate` to `false` to stop them.
171
+ When `outerlayer runner start` fails a start-up check before its first
172
+ heartbeat, it sends one report with `POST /v1/hosts/startup-report`. The
173
+ report holds the host name, the CLI version, the name of the failed check
174
+ and the error text, with terminal control codes removed, scrubbed of the
175
+ keys the runner holds and cut to 200 characters. It sends none when another
176
+ runner already runs on the same config, or when the gateway refused the
177
+ runner key or its host key's signature. The call waits at most 5 seconds,
178
+ and a gateway with no such route ignores it.
171
179
  `outerlayer runner container-start`, the runner image's entrypoint, writes
172
- the config from its environment variables with no network call. It then
173
- runs `outerlayer runner start`, which makes the calls above. In the image
180
+ the config from its environment variables. When the container reaches no
181
+ Docker it can use, it sends that report, with the check `docker`, and
182
+ stops. Otherwise it runs `outerlayer runner start`, which makes the calls
183
+ above. In the image
174
184
  the runner never calls the npm registry. It logs the image tag to pull.
175
185
  `runner check` makes a list call and a host-key lookup to confirm the key
176
186
  works and sends nothing else; `runner status` and `runner logs` make no network call at all.
@@ -1 +1 @@
1
- {"id":"2026-10-23T12:05:53.102Z+82d4e55","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-23T15:16:37.060Z+5648b3a","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-YSM4EEUK.js';
4
- import './chunk-FZUFUVLK.js';
3
+ import { probeCredentials } from './chunk-YY3OQJ4X.js';
5
4
  import './chunk-GH246BGV.js';
6
- import './chunk-ZVB57WI6.js';
7
5
  import './chunk-57L2YAJA.js';
8
6
  import './chunk-3JVYMD4G.js';
9
7
  import './chunk-E7R2GIAW.js';
10
- import './chunk-YGZLRX5U.js';
11
- import './chunk-MZYOUIY5.js';
8
+ import './chunk-RZOO7X4G.js';
9
+ import './chunk-2LFWCIIE.js';
10
+ import './chunk-ZVB57WI6.js';
11
+ import './chunk-DA3PLB5N.js';
12
12
  import './chunk-HVRQQOMH.js';
13
13
  import './chunk-6LBSAW6I.js';
14
14
  import './chunk-I3LTIAOR.js';
@@ -16,10 +16,10 @@ import './chunk-7IFYI7XF.js';
16
16
  import './chunk-D3EDZPJR.js';
17
17
  import './chunk-7UPMYRPS.js';
18
18
  import './chunk-ESVW4MJY.js';
19
- import { managedProblems, managedFactsOf } from './chunk-SQQD5MST.js';
19
+ import { managedProblems, managedFactsOf } from './chunk-VMIOUVJF.js';
20
20
  import './chunk-NBZ7XBT6.js';
21
21
  import './chunk-TBT347UY.js';
22
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, probeHelper, HELPER_ENV, helperSocketPath, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-IUPY54BZ.js';
22
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, probeHelper, HELPER_ENV, helperSocketPath, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-4YLL2E7Y.js';
23
23
  import './chunk-2PGI6RDE.js';
24
24
  import './chunk-EXZACZ2P.js';
25
25
  import './chunk-YXHKCHWG.js';
@@ -28,7 +28,7 @@ import './chunk-JBJTC3UU.js';
28
28
  import './chunk-OGFGZQA3.js';
29
29
  import './chunk-5THSC6BD.js';
30
30
  import './chunk-L26V6ILJ.js';
31
- import './chunk-XCRET2GZ.js';
31
+ import './chunk-Z57X4KNC.js';
32
32
  import './chunk-MZBQTVFG.js';
33
33
  import './chunk-TQMI335S.js';
34
34
  import { DEFAULT_UNIT_NAME } from './chunk-EHOFFTVX.js';
@@ -37,7 +37,7 @@ import './chunk-X4JEBMYN.js';
37
37
  import './chunk-OGMXVPCS.js';
38
38
  import './chunk-3Z3MPR55.js';
39
39
  import './chunk-NE63JADS.js';
40
- import './chunk-YXMGHGHR.js';
40
+ import './chunk-VSLJ6PPG.js';
41
41
  import './chunk-IP7BIBXJ.js';
42
42
  import './chunk-HLZMAJJD.js';
43
43
  import './chunk-S5CNYXUA.js';
@@ -6,23 +6,23 @@ import { writeDockerClientConfig } from './chunk-6LBSAW6I.js';
6
6
  import { zodProblem } from './chunk-I3LTIAOR.js';
7
7
  import { senderPidfile } from './chunk-7IFYI7XF.js';
8
8
  import { installScrubContext } from './chunk-D3EDZPJR.js';
9
- import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, makeBuildsDirPrivate, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, startJailedInto, resolveAgentUser, AgentUserError, runBuildSteps, startHostServices, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, closeHostBuild, containerSenderCommand, hostCommandEnvironment, execArgv, signalInContainer, syncInContainer, copyTranscriptsFromContainer, MANAGED_UNJAILED_REASON, senderAliveScript, helperFirecrackerNote, stopJailed, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, ROOT_DISK_ID_PREFIX, copyJudgeTree } from './chunk-IUPY54BZ.js';
9
+ import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, makeBuildsDirPrivate, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, startJailedInto, resolveAgentUser, AgentUserError, runBuildSteps, startHostServices, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, closeHostBuild, containerSenderCommand, hostCommandEnvironment, execArgv, signalInContainer, syncInContainer, copyTranscriptsFromContainer, MANAGED_UNJAILED_REASON, senderAliveScript, helperFirecrackerNote, stopJailed, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, ROOT_DISK_ID_PREFIX, copyJudgeTree } from './chunk-4YLL2E7Y.js';
10
10
  import { readBranchHead, fetchCommit, diffBetween } from './chunk-YXHKCHWG.js';
11
11
  import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
12
12
  import { waitForAgent, vmExecArgs } from './chunk-5THSC6BD.js';
13
13
  import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-L26V6ILJ.js';
14
- import { describeCallFailure, resolveGoverningSource, prefetchGovernedContext, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, WORKFLOW_PERMISSION_REASON, keptContextTree } from './chunk-XCRET2GZ.js';
14
+ import { describeCallFailure, resolveGoverningSource, prefetchGovernedContext, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, WORKFLOW_PERMISSION_REASON, keptContextTree } from './chunk-Z57X4KNC.js';
15
15
  import { imageBuildOf, isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-VWQCYOBS.js';
16
16
  import { DEFAULT_CACHE_DISK, formatBytes, allocatedBytes } from './chunk-X4JEBMYN.js';
17
17
  import { parseSize, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, withAnswerProtocol, judgeCommand, MAX_REPORT_BYTES, JUDGE_MAX_TURNS, JUDGE_DIR, COMMAND_DIR, MAX_ITEMS_BYTES } from './chunk-OGMXVPCS.js';
18
18
  import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-NE63JADS.js';
19
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-YXMGHGHR.js';
19
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-VSLJ6PPG.js';
20
20
  import { planArtifactUpload } from './chunk-MPC2UAW2.js';
21
21
  import { scrubText } from './chunk-NIY2UBT6.js';
22
22
  import { readCloudConfig } from './chunk-PJDQPF5N.js';
23
23
  import { signerFor } from './chunk-SOI6K5DY.js';
24
24
  import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath, jobConsolePath } from './chunk-PA6CK6WQ.js';
25
- import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, buildMavenSettingsXml, RELAY_PORT, repositoryPath, lifecycleWorkdir, CHECK_ITEMS_FILE, MAVEN_SETTINGS_FILE, CLAUDE_CREDENTIAL_VARIABLES, currentClaudeCredential, removedClaudeCredentialValues, checkEnvironment, EVAL_INPUT_DIR } from './chunk-BALIE3BA.js';
25
+ import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, buildMavenSettingsXml, CLAUDE_CREDENTIAL_VARIABLES, currentClaudeCredential, removedClaudeCredentialValues, RELAY_PORT, repositoryPath, lifecycleWorkdir, CHECK_ITEMS_FILE, MAVEN_SETTINGS_FILE, checkEnvironment, EVAL_INPUT_DIR } from './chunk-BALIE3BA.js';
26
26
  import { resolvePackRoot } from './chunk-44V5SD4G.js';
27
27
  import { MAINTAINED_SKILLS } from './chunk-CDDED64E.js';
28
28
  import { resolveVersion } from './chunk-RA3O54FC.js';
@@ -3547,4 +3547,4 @@ async function stopSender(input) {
3547
3547
  }
3548
3548
  }
3549
3549
 
3550
- export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, GUEST_USAGE_INTERVAL_MS, MICROVM_COMMAND_DIR, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, finishJob, foldSample, hookLimitsFor, inTeardown, isContainerTracked, isGroupAlive, isIdle, isMicroVmTracked, isReadable, isTimedOut, isTracked, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, microVmCommandLine, microVmOomKills, needsRenew, outcomeFromExitCode, probeCommand, probeMicroVmCommand, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, restartSender, retryFailedReleases, runCommand, runHook, sampleGuest, serveLease, setStage, startMicroVmCommand, startSender, stopOrphanedMicroVms, unfinishedJobs, vmAlive, workdirProblem, writeGuestGhConfig };
3550
+ export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, GUEST_USAGE_INTERVAL_MS, MICROVM_COMMAND_DIR, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, finishJob, foldSample, hookLimitsFor, inTeardown, isContainerTracked, isGroupAlive, isIdle, isMicroVmTracked, isReadable, isTimedOut, isTracked, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, microVmCommandLine, microVmOomKills, needsRenew, outcomeFromExitCode, probeCommand, probeMicroVmCommand, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, restartSender, retryFailedReleases, runCommand, runHook, sampleGuest, scrubReason, serveLease, setStage, startMicroVmCommand, startSender, stopOrphanedMicroVms, stripTerminalControls, unfinishedJobs, vmAlive, workdirProblem, writeGuestGhConfig };
@@ -7,14 +7,14 @@ import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
7
7
  import { currentCliBuild } from './chunk-OGFGZQA3.js';
8
8
  import { runExec, execCapture, waitForAgent } from './chunk-5THSC6BD.js';
9
9
  import { GUEST_CID, linkVsockSockets } from './chunk-L26V6ILJ.js';
10
- import { describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-XCRET2GZ.js';
10
+ import { describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-Z57X4KNC.js';
11
11
  import { runnerImageVersion } from './chunk-MZBQTVFG.js';
12
12
  import { runnerCredentialProblem, builtinKind, hostAllowed } from './chunk-VWQCYOBS.js';
13
13
  import { formatBytes, allocatedBytes } from './chunk-X4JEBMYN.js';
14
14
  import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, readDu, JUDGE_DIR, MAX_ITEMS_BYTES, JUDGE_ITEMS, MAX_REPORT_BYTES, JUDGE_REPORT, spawnRun } from './chunk-OGMXVPCS.js';
15
15
  import { RecipeError, DOCKER_FEATURE, writeSanitizedRecipe, classifyProperties } from './chunk-3Z3MPR55.js';
16
16
  import { firecrackerArch, MICROVM_ARCHES, FIRECRACKER_VERSION, hostHelperPinned, CLAUDE_CODE_VERSION, guestAssetsPinned, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, BUILDER_DISK_VERSION, builderDiskPinned, FFMPEG_STATIC, FFMPEG_BUILD_TAG, GH_SHA256, GH_VERSION, TINI_SHA256, TINI_VERSION, VOICE_PACK_FILES, BUILDER_DISK_SHA256, BUILDER_DISK_BASE_URL, DEFAULT_BASE_IMAGE } from './chunk-NE63JADS.js';
17
- import { WorkCommandError, getJson } from './chunk-YXMGHGHR.js';
17
+ import { WorkCommandError, getJson } from './chunk-VSLJ6PPG.js';
18
18
  import { sanitizeTerminal } from './chunk-MPC2UAW2.js';
19
19
  import { setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-NIY2UBT6.js';
20
20
  import { signerFor } from './chunk-SOI6K5DY.js';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { checkStarterFiles, contextIsGoverned } from './chunk-DKFUXYGD.js';
4
4
  import { fleetCheck, checkBuildSkill, checkMachineSkills, checkCommittedMaintainedSkills, checkMaintainedReferences, checkIgnoredSkillFolders } from './chunk-EJL6CWSP.js';
5
- import { resolveCredentials, getJson, WorkCommandError } from './chunk-YXMGHGHR.js';
5
+ import { resolveCredentials, getJson, WorkCommandError } from './chunk-VSLJ6PPG.js';
6
6
  import { isLinkedRepository } from './chunk-S5CNYXUA.js';
7
7
  import { sanitizeTerminal } from './chunk-MPC2UAW2.js';
8
8
  import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-NIY2UBT6.js';
@@ -1217,7 +1217,7 @@ async function gatherDoctorChecks() {
1217
1217
  const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
1218
1218
  checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
1219
1219
  } else if (hasRunnerBlock(configPath)) {
1220
- const { runnerHostChecks } = await import('./doctor-4YZOP343.js');
1220
+ const { runnerHostChecks } = await import('./doctor-MFLM7DMY.js');
1221
1221
  const gateway = (() => {
1222
1222
  try {
1223
1223
  const { url, apiKey, appId } = loadRunnerConfig(configPath);
@@ -4,6 +4,6 @@ import { createRequire } from 'node:module';
4
4
  createRequire(import.meta.url);
5
5
 
6
6
  // src/runner/protocol.ts
7
- var RUNNER_PROTOCOL = 28;
7
+ var RUNNER_PROTOCOL = 31;
8
8
 
9
9
  export { RUNNER_PROTOCOL };
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { scrubReason, stripTerminalControls } from './chunk-2LFWCIIE.js';
4
+ import { RunnerAlreadyRunningError, readPidFile } from './chunk-F5UL23I2.js';
5
+ import { isSameProcess } from './chunk-JBJTC3UU.js';
6
+ import { checkFit, RUNNER_RESERVE_BYTES } from './chunk-EHOFFTVX.js';
7
+ import { isSignatureRefusal, postJson } from './chunk-VSLJ6PPG.js';
8
+ import { signerFor } from './chunk-SOI6K5DY.js';
9
+ import { pidFilePath } from './chunk-PA6CK6WQ.js';
10
+ import { readFileSync } from 'fs';
11
+
12
+ createRequire(import.meta.url);
13
+ var GIB = 1024 ** 3;
14
+ var DEFAULT_GIB = 8;
15
+ var MINIMUM_GIB = 4;
16
+ var BUILD_MEMORY_VARIABLE = "OUTERLAYER_BUILD_MEMORY";
17
+ function memoryIsSet(configPath) {
18
+ try {
19
+ const raw = JSON.parse(readFileSync(configPath, "utf8"));
20
+ return raw.runner.build.memory !== void 0;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+ function gib(bytes) {
26
+ return `${Number((bytes / GIB).toFixed(1))} GiB`;
27
+ }
28
+ function fitImageBuildMemory(config, totalMemoryBytes) {
29
+ if (memoryIsSet(config.configPath)) return { config };
30
+ const current = config.build?.memory ?? `${DEFAULT_GIB}g`;
31
+ if (checkFit({ concurrency: config.concurrency, buildMemory: current, usableBytes: totalMemoryBytes }).fits) return { config };
32
+ const available = Math.max(0, totalMemoryBytes - RUNNER_RESERVE_BYTES);
33
+ const perBuild = Math.floor(available / config.concurrency / GIB);
34
+ if (perBuild < MINIMUM_GIB) return { config };
35
+ const memory = `${perBuild}g`;
36
+ return {
37
+ config: { ...config, build: { ...config.build, memory } },
38
+ note: `builds get ${memory} of memory to fit this machine's ${gib(totalMemoryBytes)}; set ${BUILD_MEMORY_VARIABLE} to choose another value`
39
+ };
40
+ }
41
+
42
+ // src/runner/startup-report.ts
43
+ var REPORT_TIMEOUT_MS = 5e3;
44
+ var EMPTY_MESSAGE = "the check failed with no message";
45
+ async function reportFailedStart(failed, fetchImpl, deps = {}) {
46
+ try {
47
+ if (failed.error instanceof RunnerAlreadyRunningError || refusesReport(failed.refusal)) return;
48
+ if (otherRunnerLive(failed.config.configPath, deps.isSameProcess ?? isSameProcess)) return;
49
+ await sendStartupReport(failed, fetchImpl, deps);
50
+ } catch {
51
+ }
52
+ }
53
+ function refusesReport(refusal) {
54
+ return refusal !== void 0 && (refusal.status === 401 || isSignatureRefusal(refusal.code));
55
+ }
56
+ function otherRunnerLive(configPath, isSame) {
57
+ const entry = readPidFile(pidFilePath(configPath));
58
+ return entry !== null && entry.pid !== process.pid && isSame(entry.pid, entry.start);
59
+ }
60
+ async function sendStartupReport(failed, fetchImpl, deps) {
61
+ const now = deps.now ?? (() => performance.now());
62
+ const startedAt = now();
63
+ const { config } = failed;
64
+ const text = failed.error instanceof Error ? failed.error.message : String(failed.error);
65
+ const message = (deps.scrub ?? scrubReason)(stripTerminalControls(text), config) ?? EMPTY_MESSAGE;
66
+ const signer = await signerFor(config.configPath).catch(() => void 0);
67
+ const left = REPORT_TIMEOUT_MS - (now() - startedAt);
68
+ if (left <= 0) return;
69
+ await postJson(
70
+ config.url,
71
+ "/v1/hosts/startup-report",
72
+ config.apiKey,
73
+ config.appId,
74
+ { host: config.host, cliVersion: failed.cliVersion, check: failed.check, message },
75
+ fetchImpl,
76
+ left,
77
+ signer
78
+ );
79
+ }
80
+
81
+ export { BUILD_MEMORY_VARIABLE, fitImageBuildMemory, reportFailedStart };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { placeholderQueues, placeholderProblem } from './chunk-IUPY54BZ.js';
3
+ import { placeholderQueues, placeholderProblem } from './chunk-4YLL2E7Y.js';
4
4
  import { checkFit } from './chunk-EHOFFTVX.js';
5
5
  import { builtinKind, imageBuildOf } from './chunk-VWQCYOBS.js';
6
6
  import { realBuildDiskProbe, checkDiskFit, DEFAULT_CACHE_DISK, DEFAULT_BUILD_DISK } from './chunk-X4JEBMYN.js';
@@ -115,13 +115,14 @@ var WorkCommandError = class extends Error {
115
115
  * reached a response. A caller that has to tell one refusal from another —
116
116
  * a claim lost to another host from a key that no longer works — reads it
117
117
  * rather than matching on the message. */
118
- constructor(message, retryable = false, status, code, reason, billingUrl) {
118
+ constructor(message, retryable = false, status, code, reason, billingUrl, lowestVersion) {
119
119
  super(message);
120
120
  this.retryable = retryable;
121
121
  this.status = status;
122
122
  this.code = code;
123
123
  this.reason = reason;
124
124
  this.billingUrl = billingUrl;
125
+ this.lowestVersion = lowestVersion;
125
126
  }
126
127
  };
127
128
  var WORK_LINK_RETRY_DELAYS_MS = [1e3, 5e3, 15e3, 6e4];
@@ -247,7 +248,10 @@ async function sendJsonBefore(method, url, path, apiKey, appId, body, fetchImpl,
247
248
  json.error?.message ?? `request failed (${response.status})`,
248
249
  response.status >= 500 || response.status === 429,
249
250
  response.status,
250
- json.error?.code
251
+ json.error?.code,
252
+ void 0,
253
+ void 0,
254
+ typeof json.error?.lowestVersion === "string" ? json.error.lowestVersion : void 0
251
255
  );
252
256
  }
253
257
  return { status: response.status, data: json.data ?? json };
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, readProvisionOut, workdirProblem, MICROVM_COMMAND_DIR, commandLogOffset, startMicroVmCommand, microVmCommandLine, runCommand, startSender, finishJob, sampleGuest, foldSample, isContainerTracked, isMicroVmTracked, probeMicroVmCommand, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isTracked, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listUnreadableJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, GUEST_USAGE_INTERVAL_MS, hookLimitsFor, AttemptLogBook, microVmOomKills, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, serveLease, vmAlive, writeGuestGhConfig, ALREADY_RELEASED, inTeardown } from './chunk-FZUFUVLK.js';
4
3
  import { writePendingUpdate } from './chunk-GH246BGV.js';
5
- import { JOB_STATE_FORMAT, readsJobState, jobStateFormatOf } from './chunk-ZVB57WI6.js';
6
4
  import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-57L2YAJA.js';
7
5
  import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
8
6
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-E7R2GIAW.js';
9
- import { fitImageBuildMemory } from './chunk-YGZLRX5U.js';
10
- import { RUNNER_PROTOCOL } from './chunk-MZYOUIY5.js';
11
- import { realBlockedProbes, checkBlockedWithSlots, keepsHostBuilder } from './chunk-SQQD5MST.js';
12
- import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, isInLayout, cleanVersions, stagingDir } from './chunk-NBZ7XBT6.js';
7
+ import { reportFailedStart, fitImageBuildMemory } from './chunk-RZOO7X4G.js';
8
+ import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, readProvisionOut, workdirProblem, MICROVM_COMMAND_DIR, commandLogOffset, startMicroVmCommand, microVmCommandLine, runCommand, startSender, finishJob, sampleGuest, foldSample, isContainerTracked, isMicroVmTracked, probeMicroVmCommand, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isTracked, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listUnreadableJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, GUEST_USAGE_INTERVAL_MS, hookLimitsFor, AttemptLogBook, microVmOomKills, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, serveLease, vmAlive, writeGuestGhConfig, ALREADY_RELEASED, inTeardown } from './chunk-2LFWCIIE.js';
9
+ import { JOB_STATE_FORMAT, readsJobState, jobStateFormatOf } from './chunk-ZVB57WI6.js';
10
+ import { RUNNER_PROTOCOL } from './chunk-DA3PLB5N.js';
11
+ import { realBlockedProbes, checkBlockedWithSlots, keepsHostBuilder } from './chunk-VMIOUVJF.js';
12
+ import { writeMarker, readMarker, currentVersion, removeMarker, isInLayout, startedThroughCurrent, entryIn, versionDir, switchCurrent, cleanVersions, stagingDir } from './chunk-NBZ7XBT6.js';
13
13
  import { RepoFilter } from './chunk-TBT347UY.js';
14
- import { leaseTimeLeftMs, createContainerRuntime, withTunnelLog, LEASE_SECONDS, attemptNote, needsBuildSkill, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, provisionEnvironment, resolveHostBuild, listenOnBroker, hostEnvironment, deliverExecMaven, runWithSpawn, hostCommandEnvironment, lifecycleSteps, execArgv, lifecycleFailureReason, decideHostBuildSkill, prepareBranch, currentSkillCommand, formerSkillProblem, containerCommandExec, execCommandLine, startHostServices, setUpRunnerCgroup, sweepImageBuilders, measureDisk, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied, gitRemoteFor, startServicesFor, createLeaseChannel } from './chunk-IUPY54BZ.js';
14
+ import { leaseTimeLeftMs, createContainerRuntime, withTunnelLog, LEASE_SECONDS, attemptNote, needsBuildSkill, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, provisionEnvironment, resolveHostBuild, listenOnBroker, hostEnvironment, deliverExecMaven, runWithSpawn, hostCommandEnvironment, lifecycleSteps, execArgv, lifecycleFailureReason, decideHostBuildSkill, prepareBranch, currentSkillCommand, formerSkillProblem, containerCommandExec, execCommandLine, startHostServices, setUpRunnerCgroup, sweepImageBuilders, measureDisk, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied, gitRemoteFor, startServicesFor, createLeaseChannel } from './chunk-4YLL2E7Y.js';
15
15
  import { claimPidFile, writePidFile, readPidFile, releasePidFile } from './chunk-F5UL23I2.js';
16
16
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
17
- import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, resolveGoverningSource, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-XCRET2GZ.js';
17
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, resolveGoverningSource, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-Z57X4KNC.js';
18
18
  import { tagToPull, pullInstruction, imageTag, writeUpdateStatus } from './chunk-MZBQTVFG.js';
19
19
  import { isVersion, compareVersions, satisfiesRange } from './chunk-TQMI335S.js';
20
20
  import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-VWQCYOBS.js';
21
21
  import { freeBytes, formatBytes, volumeBytes } from './chunk-X4JEBMYN.js';
22
22
  import { writeJobFile, ensureRunnerIdentity, readJobFile, exceedsDisk, builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, spawnRun, BUILD_LABEL, RUNNER_LABEL, readJobFileChecked } from './chunk-OGMXVPCS.js';
23
- import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-YXMGHGHR.js';
23
+ import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-VSLJ6PPG.js';
24
24
  import { loadHostKey, ensureHostKey, signerFor } from './chunk-SOI6K5DY.js';
25
25
  import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, RUNNER_FILE_MODE, jobsDir, pidFilePath, spoolDir, imagesDir, rootfsDir, builderCacheDiskPath } from './chunk-PA6CK6WQ.js';
26
26
  import { parseClaimIdentity, parseClaimedRepositories, parseUnreachable, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, takeClaudeCredential, heldClaudeCredential, currentClaudeCredential } from './chunk-BALIE3BA.js';
@@ -121,7 +121,8 @@ async function sendHeartbeat(args, fetchImpl) {
121
121
  blocked: args.blocked === void 0 ? void 0 : { reason: cutForGateway(args.blocked.reason, BLOCKED_REASON_MAX) },
122
122
  state: args.state,
123
123
  waitingItems: args.waitingItems === void 0 ? void 0 : args.waitingItems.slice(0, WAITING_ITEMS_MAX),
124
- takes: args.takes === void 0 ? void 0 : takesBody(args.takes)
124
+ takes: args.takes === void 0 ? void 0 : takesBody(args.takes),
125
+ selfUpdate: args.selfUpdate
125
126
  };
126
127
  try {
127
128
  const response = await postJson(
@@ -1284,10 +1285,12 @@ async function sendTickHeartbeat(state, workRequest) {
1284
1285
  }),
1285
1286
  // Left out unless a draining runner has builds to wait on, so the gateway stores null.
1286
1287
  waitingItems: waitingItems.length > 0 ? waitingItems : void 0,
1287
- takes: { queues: state.config.queues, repos: { include: state.config.repos?.include, exclude: state.config.repos?.exclude } }
1288
+ takes: { queues: state.config.queues, repos: { include: state.config.repos?.include, exclude: state.config.repos?.exclude } },
1289
+ selfUpdate: selfUpdateReport(state)
1288
1290
  },
1289
1291
  state.deps.fetchImpl
1290
1292
  );
1293
+ if (result.ok) state.heartbeatSent = true;
1291
1294
  reportRepeating(state, "the heartbeat", result.ok ? void 0 : `heartbeat failed: ${result.reason}`);
1292
1295
  if (result.ok) {
1293
1296
  considerNamedVersion(state, result.runnerVersion);
@@ -1335,7 +1338,18 @@ function selfUpdateBlocker(configPath, entryPath, own) {
1335
1338
  if (current !== own) return `\`current\` names ${current ?? "nothing"}, not the running ${own} \xB7 restart the runner`;
1336
1339
  return void 0;
1337
1340
  }
1341
+ function selfUpdateReport(state) {
1342
+ if (state.deps.image !== void 0) return { enabled: false, reason: "runner-image" };
1343
+ const update = state.deps.update;
1344
+ const configPath = state.config.configPath;
1345
+ if (update === void 0 || !isInLayout(configPath, update.entryPath) || !startedThroughCurrent(configPath, update.entryPath)) {
1346
+ return { enabled: false, reason: "outside-install-layout" };
1347
+ }
1348
+ if (!state.config.autoUpdate) return { enabled: false, reason: "auto-update-off" };
1349
+ return { enabled: true };
1350
+ }
1338
1351
  function considerNamedVersion(state, named) {
1352
+ if (named !== void 0 && isVersion(named)) state.namedVersion = named;
1339
1353
  if (state.deps.image !== void 0) {
1340
1354
  considerNamedImage(state, named);
1341
1355
  return;
@@ -1371,6 +1385,14 @@ function considerNamedImage(state, named) {
1371
1385
  state.imageLogged = named;
1372
1386
  logOf(state).line(`the factory names ${named}, newer than the ${own} this image runs \xB7 ${pullInstruction(imageTag(named))}`);
1373
1387
  }
1388
+ function upgradeStepFor(state, floor) {
1389
+ const named = state.namedVersion ?? floor;
1390
+ const target = named !== void 0 && isVersion(named) ? named : void 0;
1391
+ if (state.deps.image !== void 0) return pullInstruction(tagToPull(target));
1392
+ const npm = `npm install -g @outerlayer/cli@${target ?? "latest"}, then "$(npm prefix -g)/bin/outerlayer" runner install`;
1393
+ if (state.deps.update?.underService !== true) return `${npm}, then start the runner again`;
1394
+ return builtinKind(state.config.hooks.provision) === "own" ? npm : `${npm} --service`;
1395
+ }
1374
1396
  function recordImageStatus(state) {
1375
1397
  if (state.deps.image === void 0) return;
1376
1398
  const named = state.imageNamed;
@@ -1864,7 +1886,7 @@ var CLAIM_REFUSAL_CODES = new Set(
1864
1886
  "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected repository_not_reachable branch_claimed_elsewhere".split(" ")
1865
1887
  );
1866
1888
  async function tryClaimAndStart(state, item, queue) {
1867
- const { postJson: postJson2 } = await import('./work-cmd-OO6K6ELP.js');
1889
+ const { postJson: postJson2 } = await import('./work-cmd-J2LJ3V4A.js');
1868
1890
  const log = logOf(state);
1869
1891
  const hostKey = await loadHostKey(state.config.configPath);
1870
1892
  const claim = await retrySend(
@@ -1878,6 +1900,7 @@ async function tryClaimAndStart(state, item, queue) {
1878
1900
  kind: queue,
1879
1901
  seconds: LEASE_SECONDS,
1880
1902
  runnerProtocol: RUNNER_PROTOCOL,
1903
+ cliVersion: state.deps.cliVersion ?? resolveVersion(),
1881
1904
  ...hostKey === void 0 ? {} : { hostKey: hostKey.hostKey }
1882
1905
  },
1883
1906
  state.deps.fetchImpl,
@@ -1904,6 +1927,17 @@ async function tryClaimAndStart(state, item, queue) {
1904
1927
  reportRepeating(state, "the organization's billing", claim.message ?? claim.reason);
1905
1928
  return { kind: "read_only" };
1906
1929
  }
1930
+ if (claim.code === "runner_version_unsupported") {
1931
+ if (state.heartbeatSent !== true) return { kind: "outdated" };
1932
+ const floor = claim.lowestVersion ?? "the minimum version";
1933
+ if (state.versionRefusalLogged !== floor) {
1934
+ state.versionRefusalLogged = floor;
1935
+ logOf(state).error(`the gateway refuses work from this runner: it runs ${ownVersionOf(state.deps)}, below ${floor} \xB7 ${upgradeStepFor(state, claim.lowestVersion)}`);
1936
+ }
1937
+ state.upgradeRefused = true;
1938
+ recordImageStatus(state);
1939
+ return { kind: "outdated" };
1940
+ }
1907
1941
  if (claim.code === "runner_upgrade_required") {
1908
1942
  const tag = tagToPull(state.imageNamed);
1909
1943
  reportRepeating(
@@ -1920,6 +1954,7 @@ async function tryClaimAndStart(state, item, queue) {
1920
1954
  reportRepeating(state, "the organization's billing", void 0);
1921
1955
  reportRepeating(state, "the runner protocol", void 0);
1922
1956
  state.upgradeRefused = false;
1957
+ state.versionRefusalLogged = void 0;
1923
1958
  recordImageStatus(state);
1924
1959
  reportRepeating(state, "the request signature", void 0);
1925
1960
  const { data } = claim.value;
@@ -2813,21 +2848,26 @@ async function probeCredentials(config, fetchImpl = fetch) {
2813
2848
  return { ok: true };
2814
2849
  } catch (err) {
2815
2850
  const status = err instanceof WorkCommandError ? err.status : void 0;
2851
+ const code = err instanceof WorkCommandError ? err.code : void 0;
2816
2852
  if (err instanceof WorkCommandError && isSignatureRefusal(err.code)) {
2817
2853
  return {
2818
2854
  ok: false,
2819
2855
  fatal: err.code === "runner_key_signature_invalid",
2820
- reason: `${config.configPath}: ${err.message}`
2856
+ reason: `${config.configPath}: ${err.message}`,
2857
+ status,
2858
+ code
2821
2859
  };
2822
2860
  }
2823
2861
  if (status === 401 || status === 403) {
2824
2862
  return {
2825
2863
  ok: false,
2826
2864
  fatal: true,
2827
- reason: `${config.configPath}: the API key was refused (${status}). A runner key needs git.read and work.read to list and read work items, and work.claim to claim, renew and release.`
2865
+ reason: `${config.configPath}: the API key was refused (${status}). A runner key needs git.read and work.read to list and read work items, and work.claim to claim, renew and release.`,
2866
+ status,
2867
+ code
2828
2868
  };
2829
2869
  }
2830
- return { ok: false, fatal: false, reason: describeCallFailure(err) };
2870
+ return { ok: false, fatal: false, reason: describeCallFailure(err), status, code };
2831
2871
  }
2832
2872
  }
2833
2873
  async function rejoinContainerBuild(state, adopted) {
@@ -3071,6 +3111,15 @@ function hooksOf(configPath) {
3071
3111
  }
3072
3112
  }
3073
3113
  async function start(configPath, deps = { fetchImpl: fetch }) {
3114
+ const startup = {};
3115
+ try {
3116
+ return await startRunner(configPath, deps, startup);
3117
+ } catch (err) {
3118
+ await startup.report?.(err);
3119
+ throw err;
3120
+ }
3121
+ }
3122
+ async function startRunner(configPath, deps, startup) {
3074
3123
  const log = deps.log ??= createRunnerLog(deps.now ?? (() => /* @__PURE__ */ new Date()));
3075
3124
  takeClaudeCredential(process.env, hooksOf(configPath));
3076
3125
  const update = deps.update;
@@ -3081,7 +3130,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
3081
3130
  check: update.check ? () => update.check(configPath) : async () => {
3082
3131
  const held = heldClaudeCredential();
3083
3132
  const env = held === void 0 ? process.env : { ...process.env, [held.variable]: held.value };
3084
- return (await import('./check-4QNLMDP7.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl, env });
3133
+ return (await import('./check-XPMN4GHD.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl, env });
3085
3134
  },
3086
3135
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
3087
3136
  log
@@ -3092,22 +3141,37 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
3092
3141
  }
3093
3142
  }
3094
3143
  const loaded = loadRunnerConfig(configPath);
3144
+ let check = "hooks";
3145
+ let probeRefusal;
3146
+ startup.report = (err) => reportFailedStart(
3147
+ { config: loaded, cliVersion: deps.cliVersion ?? resolveVersion(), check, error: err, refusal: probeRefusal },
3148
+ deps.fetchImpl
3149
+ );
3095
3150
  const hookProblem = checkHooks(loaded);
3096
3151
  if (hookProblem) throw new RunnerStartError(hookProblem);
3152
+ check = "image";
3097
3153
  const { config, note: fitNote } = fitForImage(deps, loaded);
3154
+ check = "host-key";
3098
3155
  await ensureHostKey(configPath);
3156
+ check = "identity";
3099
3157
  if (builtinKind(config.hooks.provision) === "container" || builtinKind(config.hooks.provision) === "vm") {
3100
3158
  await ensureRunnerIdentity(configPath, {
3101
3159
  docker: deps.runnerIdentity ?? (deps.container?.host === void 0 ? void 0 : { holdsObjects: async () => false }),
3102
3160
  log: (line) => log.error(line)
3103
3161
  }).catch((err) => log.error(`the runner's Docker identity could not be stored: ${describeCallFailure(err)} \xB7 using the names its folder's path gives`));
3104
3162
  }
3163
+ check = "credentials";
3105
3164
  const probe = await probeCredentials(config, deps.fetchImpl);
3106
- if (!probe.ok && probe.fatal) throw new RunnerStartError(probe.reason);
3165
+ if (!probe.ok && probe.fatal) {
3166
+ probeRefusal = { status: probe.status, code: probe.code };
3167
+ throw new RunnerStartError(probe.reason);
3168
+ }
3107
3169
  if (!probe.ok) log.error(`the gateway did not answer at start: ${probe.reason} \xB7 starting anyway`);
3170
+ check = "pid-file";
3108
3171
  mkdirSync(jobsDir(configPath), { recursive: true, mode: RUNNER_DIR_MODE });
3109
3172
  const self = { pid: process.pid, start: startTimeOf(process.pid) ?? "" };
3110
3173
  claimPidFile(pidFilePath(configPath), self);
3174
+ check = "cgroup";
3111
3175
  const { delegated, refusal } = setUpRunnerCgroup();
3112
3176
  if (refusal !== void 0) log.error(`the kernel refused a cgroup step for the runner's service: ${refusal}`);
3113
3177
  if (isBuiltinVm(config.hooks.provision) && !delegated) {
@@ -3122,6 +3186,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
3122
3186
  const state = { config, jobs: /* @__PURE__ */ new Map(), deps, configMtimeMs };
3123
3187
  log.line(`runner ${config.host} started \xB7 config ${configPath} \xB7 ${describeConfig(config)}`);
3124
3188
  if (fitNote !== void 0) log.line(fitNote);
3189
+ check = "recovery";
3125
3190
  const leavesBuilds = await canLeaveBuilds(state);
3126
3191
  let sigusr2Target;
3127
3192
  let sigusr2Early = false;
@@ -3189,6 +3254,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
3189
3254
  `recovered job ${recovered.queue} #${recovered.item} (claim ${shortClaim(recovered.claimId)}) as ${recovered.outcome ?? "interrupted"}: ${why}`
3190
3255
  );
3191
3256
  }
3257
+ startup.report = void 0;
3192
3258
  let intakeClosed = false;
3193
3259
  let closed = false;
3194
3260
  let stopping = false;
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { WorkCommandError, postJson } from './chunk-YXMGHGHR.js';
3
+ import { WorkCommandError, postJson } from './chunk-VSLJ6PPG.js';
4
4
  import { defaultGitRunner, materializeContext, fetchControlPlaneCommit, lookupGoverningSource } from './chunk-AKZRGFGT.js';
5
5
  import { signingFetchFor } from './chunk-6RKD7YZ6.js';
6
6
  import { signerFor } from './chunk-SOI6K5DY.js';
@@ -92,9 +92,10 @@ async function retrySend(send, deps = {}) {
92
92
  const code = err instanceof WorkCommandError ? err.code : void 0;
93
93
  const status = err instanceof WorkCommandError ? err.status : void 0;
94
94
  const message = err instanceof WorkCommandError ? err.message : void 0;
95
- if (!isRetryable(err)) return { ok: false, attempts, reason, retryable: false, code, status, message };
95
+ const lowestVersion = err instanceof WorkCommandError ? err.lowestVersion : void 0;
96
+ if (!isRetryable(err)) return { ok: false, attempts, reason, retryable: false, code, status, message, lowestVersion };
96
97
  const elapsedMs = now().getTime() - startedMs;
97
- if (elapsedMs + backoffMs >= windowMs) return { ok: false, attempts, reason, retryable: true, code, status, message };
98
+ if (elapsedMs + backoffMs >= windowMs) return { ok: false, attempts, reason, retryable: true, code, status, message, lowestVersion };
98
99
  await sleep(backoffMs);
99
100
  backoffMs = Math.min(backoffMs * 2, MAX_BACKOFF_MS);
100
101
  }