terminalhire 0.42.38 → 0.42.39

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.
@@ -29349,7 +29349,7 @@ function resolvePublishedImage(image, runtime, version, variant) {
29349
29349
  if (shape && shape.declaredIsFloor && atLeast(shape.defaultVersion, version)) {
29350
29350
  return unversionedImage(shape);
29351
29351
  }
29352
- throw new RunRefusalError(`the repo declares ${runtime} ${version}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.");
29352
+ throw new RunRefusalError(`the repo declares ${runtime} ${version}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.", { origin: "repository" });
29353
29353
  }
29354
29354
  function resolveImageForSpec(spec, override) {
29355
29355
  const variant = imageVariantFor(spec);
@@ -29588,6 +29588,17 @@ var init_execute = __esm({
29588
29588
  EnvRunError = class extends Error {
29589
29589
  };
29590
29590
  RunRefusalError = class extends EnvRunError {
29591
+ /**
29592
+ * Whose side refused (TERM-1313), set at the throw and never read back out of the message.
29593
+ * A baseline intake labels a posting not-runnable on `repository`, so that value is passed
29594
+ * only where envrun can show the repository asked for something we cannot supply. Every
29595
+ * other refusal, including one nobody has classified yet, is `ours` by default.
29596
+ */
29597
+ origin;
29598
+ constructor(message2, options) {
29599
+ super(message2, options);
29600
+ this.origin = options?.origin ?? "ours";
29601
+ }
29591
29602
  };
29592
29603
  MAX_CAUSE_FRAMES = 16;
29593
29604
  CHAIN_UNREADABLE = "<the cause chain stopped: a value refused to be read>";
@@ -30509,7 +30520,8 @@ var init_result = __esm({
30509
30520
  "imageSource",
30510
30521
  "leaksClean",
30511
30522
  "leakState",
30512
- "venue"
30523
+ "venue",
30524
+ "refusalOrigin"
30513
30525
  ];
30514
30526
  RENDER_NONE = null;
30515
30527
  FIELD_VIEWS = {
@@ -30569,7 +30581,10 @@ var init_result = __esm({
30569
30581
  // Absent on most runs, so it prints only when there is something to say. Silence
30570
30582
  // here is the honest rendering of "no venue answered": a placeholder line would
30571
30583
  // invite a reader to treat an unanswered probe as a described venue.
30572
- venue: (r) => r.venue === null ? null : renderVenueLine(r.venue)
30584
+ venue: (r) => r.venue === null ? null : renderVenueLine(r.venue),
30585
+ // For the worker and the baseline intake, not the terminal: `reason` already says which
30586
+ // side refused in words a developer reads.
30587
+ refusalOrigin: RENDER_NONE
30573
30588
  };
30574
30589
  }
30575
30590
  });
@@ -37047,6 +37062,18 @@ function applyPatch(repoDir, patch, what) {
37047
37062
  throw new ThRunError(`the ${what} did not apply cleanly to the target checkout: ${(res.stderr ?? "").trim()}. The diff was built against a different commit than the one being verified.`);
37048
37063
  }
37049
37064
  }
37065
+ function imageInputsAt(repoDir) {
37066
+ try {
37067
+ const pinned = deriveEnvironmentSpec(repoDir);
37068
+ return {
37069
+ runtime: pinned.runtime,
37070
+ runtimeVersion: pinned.runtimeVersion,
37071
+ variant: imageVariantFor(pinned)
37072
+ };
37073
+ } catch {
37074
+ return null;
37075
+ }
37076
+ }
37050
37077
  function tail(text, bytes = OUTPUT_TAIL_BYTES) {
37051
37078
  return text.length <= bytes ? text : text.slice(-bytes);
37052
37079
  }
@@ -37102,9 +37129,17 @@ function refusedRun(fields) {
37102
37129
  // A refused run never held a lease, so there is no venue to describe. Same
37103
37130
  // reasoning as `leaksClean` above: null because nothing happened, and it must
37104
37131
  // not read as a venue we looked at and could not name.
37105
- venue: null
37132
+ venue: null,
37133
+ refusalOrigin: fields.origin
37106
37134
  };
37107
37135
  }
37136
+ function refusalOriginOf(refusal2) {
37137
+ try {
37138
+ return refusal2.origin === "repository" ? "repository" : "ours";
37139
+ } catch {
37140
+ return "ours";
37141
+ }
37142
+ }
37108
37143
  function unacceptableTarget(req) {
37109
37144
  try {
37110
37145
  assertSafeTargetUrl(req.targetRepo);
@@ -37185,7 +37220,8 @@ async function verifyWorkingDiff(req) {
37185
37220
  const ctx = {
37186
37221
  startedAt: Date.now(),
37187
37222
  runId: req.runId ?? `run-${randomUUID3().slice(0, 8)}`,
37188
- touchedPaths: []
37223
+ touchedPaths: [],
37224
+ imageChosenByRepository: false
37189
37225
  };
37190
37226
  const target = {
37191
37227
  claimId: req.claimId,
@@ -37200,6 +37236,10 @@ async function verifyWorkingDiff(req) {
37200
37236
  throw err;
37201
37237
  return {
37202
37238
  result: refusedRun({
37239
+ // `repository` survives only when the repository's files alone chose the image.
37240
+ // `resolvePublishedImage` knows the version came from the repo, but not whether an
37241
+ // override picked the image variant the missing tag belongs to (Codex, TERM-1313).
37242
+ origin: refusalOriginOf(refusal2) === "repository" && ctx.imageChosenByRepository ? "repository" : "ours",
37203
37243
  runId: ctx.runId,
37204
37244
  claimId: target.claimId,
37205
37245
  // `describeThrown`, not `refusal.message`. Classifying a value does not make
@@ -37267,6 +37307,7 @@ async function runVerification(req, ctx) {
37267
37307
  if (badTarget !== null) {
37268
37308
  return {
37269
37309
  result: refusedRun({
37310
+ origin: "ours",
37270
37311
  runId,
37271
37312
  claimId: req.claimId,
37272
37313
  reason: badTarget,
@@ -37290,6 +37331,7 @@ async function runVerification(req, ctx) {
37290
37331
  if (placement.refusal !== null) {
37291
37332
  return {
37292
37333
  result: refusedRun({
37334
+ origin: "ours",
37293
37335
  runId,
37294
37336
  claimId: req.claimId,
37295
37337
  reason: placement.refusal,
@@ -37333,6 +37375,7 @@ async function runVerification(req, ctx) {
37333
37375
  const first = pre.refusals[0];
37334
37376
  return {
37335
37377
  result: refusedRun({
37378
+ origin: "ours",
37336
37379
  runId,
37337
37380
  claimId: req.claimId,
37338
37381
  reason: first?.detail ?? "the diff was refused by the local slice pre-flight, but no reason was recorded",
@@ -37367,6 +37410,7 @@ async function runVerification(req, ctx) {
37367
37410
  // there and passing it unconditionally keeps one code path instead of two.
37368
37411
  ...req.targetAuth ? { auth: req.targetAuth } : {}
37369
37412
  });
37413
+ const pinnedImageInputs = imageInputsAt(cloneDir);
37370
37414
  const baselinePatch = source.kind === "working-diff" ? source.baselinePatch : void 0;
37371
37415
  const hasBaselinePatch = baselinePatch !== void 0 && baselinePatch.trim() !== "";
37372
37416
  if (hasBaselinePatch) {
@@ -37387,6 +37431,9 @@ async function runVerification(req, ctx) {
37387
37431
  if (lockfileRefusals.length > 0) {
37388
37432
  return {
37389
37433
  result: refusedRun({
37434
+ // The developer's diff, not the repository's environment, so never `repository`
37435
+ // (TERM-1313). Only a working diff is judged here; a dispatched baseline has none.
37436
+ origin: "ours",
37390
37437
  runId,
37391
37438
  claimId: req.claimId,
37392
37439
  reason: lockfileRefusals[0]?.detail ?? "a lockfile in the diff was refused",
@@ -37408,6 +37455,7 @@ async function runVerification(req, ctx) {
37408
37455
  const baselinePatchSha256 = hasBaselinePatch ? sha256Hex(baselinePatch ?? "") : null;
37409
37456
  const derived = deriveEnvironmentSpec(cloneDir);
37410
37457
  const { spec, imageSource } = resolveRunEnvironment(derived, req);
37458
+ ctx.imageChosenByRepository = imageSource === "detected" && imageVariantFor(spec) === imageVariantFor(derived) && pinnedImageInputs !== null && pinnedImageInputs.runtime === spec.runtime && pinnedImageInputs.runtimeVersion === spec.runtimeVersion && pinnedImageInputs.variant === imageVariantFor(spec);
37411
37459
  progress("derive", `runtime=${spec.runtime} install=${String(spec.installCommand)} test=${String(spec.testCommand)}`);
37412
37460
  const unfrozenNote = installUnfrozenNote(spec);
37413
37461
  if (unfrozenNote !== null)
@@ -37418,6 +37466,7 @@ async function runVerification(req, ctx) {
37418
37466
  if (!resolved.ok) {
37419
37467
  return {
37420
37468
  result: refusedRun({
37469
+ origin: "ours",
37421
37470
  runId,
37422
37471
  claimId: req.claimId,
37423
37472
  reason: resolved.refusal,
@@ -37529,7 +37578,9 @@ async function runVerification(req, ctx) {
37529
37578
  // Built from the LEASE, over the client that ran the steps — never from
37530
37579
  // `req.placement`, which is a request. `venueDescriptor.ts` carries the
37531
37580
  // reasoning and the #735 failure that makes the distinction load-bearing.
37532
- venue: describeVenue(lease)
37581
+ venue: describeVenue(lease),
37582
+ // A run that reached a verdict was not refused, so neither side refused it.
37583
+ refusalOrigin: null
37533
37584
  };
37534
37585
  let later = null;
37535
37586
  if (req.screenshots !== void 0) {
@@ -35124,7 +35124,7 @@ function resolvePublishedImage(image, runtime, version2, variant) {
35124
35124
  if (shape && shape.declaredIsFloor && atLeast(shape.defaultVersion, version2)) {
35125
35125
  return unversionedImage(shape);
35126
35126
  }
35127
- throw new RunRefusalError(`the repo declares ${runtime} ${version2}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.");
35127
+ throw new RunRefusalError(`the repo declares ${runtime} ${version2}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.", { origin: "repository" });
35128
35128
  }
35129
35129
  function resolveImageForSpec(spec, override) {
35130
35130
  const variant = imageVariantFor(spec);
@@ -35363,6 +35363,17 @@ var init_execute = __esm({
35363
35363
  EnvRunError = class extends Error {
35364
35364
  };
35365
35365
  RunRefusalError = class extends EnvRunError {
35366
+ /**
35367
+ * Whose side refused (TERM-1313), set at the throw and never read back out of the message.
35368
+ * A baseline intake labels a posting not-runnable on `repository`, so that value is passed
35369
+ * only where envrun can show the repository asked for something we cannot supply. Every
35370
+ * other refusal, including one nobody has classified yet, is `ours` by default.
35371
+ */
35372
+ origin;
35373
+ constructor(message2, options) {
35374
+ super(message2, options);
35375
+ this.origin = options?.origin ?? "ours";
35376
+ }
35366
35377
  };
35367
35378
  MAX_CAUSE_FRAMES = 16;
35368
35379
  CHAIN_UNREADABLE = "<the cause chain stopped: a value refused to be read>";
@@ -36284,7 +36295,8 @@ var init_result = __esm({
36284
36295
  "imageSource",
36285
36296
  "leaksClean",
36286
36297
  "leakState",
36287
- "venue"
36298
+ "venue",
36299
+ "refusalOrigin"
36288
36300
  ];
36289
36301
  RENDER_NONE = null;
36290
36302
  FIELD_VIEWS = {
@@ -36344,7 +36356,10 @@ var init_result = __esm({
36344
36356
  // Absent on most runs, so it prints only when there is something to say. Silence
36345
36357
  // here is the honest rendering of "no venue answered": a placeholder line would
36346
36358
  // invite a reader to treat an unanswered probe as a described venue.
36347
- venue: (r) => r.venue === null ? null : renderVenueLine(r.venue)
36359
+ venue: (r) => r.venue === null ? null : renderVenueLine(r.venue),
36360
+ // For the worker and the baseline intake, not the terminal: `reason` already says which
36361
+ // side refused in words a developer reads.
36362
+ refusalOrigin: RENDER_NONE
36348
36363
  };
36349
36364
  }
36350
36365
  });
@@ -42822,6 +42837,18 @@ function applyPatch(repoDir, patch, what) {
42822
42837
  throw new ThRunError(`the ${what} did not apply cleanly to the target checkout: ${(res.stderr ?? "").trim()}. The diff was built against a different commit than the one being verified.`);
42823
42838
  }
42824
42839
  }
42840
+ function imageInputsAt(repoDir) {
42841
+ try {
42842
+ const pinned = deriveEnvironmentSpec(repoDir);
42843
+ return {
42844
+ runtime: pinned.runtime,
42845
+ runtimeVersion: pinned.runtimeVersion,
42846
+ variant: imageVariantFor(pinned)
42847
+ };
42848
+ } catch {
42849
+ return null;
42850
+ }
42851
+ }
42825
42852
  function tail(text, bytes = OUTPUT_TAIL_BYTES) {
42826
42853
  return text.length <= bytes ? text : text.slice(-bytes);
42827
42854
  }
@@ -42877,9 +42904,17 @@ function refusedRun(fields) {
42877
42904
  // A refused run never held a lease, so there is no venue to describe. Same
42878
42905
  // reasoning as `leaksClean` above: null because nothing happened, and it must
42879
42906
  // not read as a venue we looked at and could not name.
42880
- venue: null
42907
+ venue: null,
42908
+ refusalOrigin: fields.origin
42881
42909
  };
42882
42910
  }
42911
+ function refusalOriginOf(refusal2) {
42912
+ try {
42913
+ return refusal2.origin === "repository" ? "repository" : "ours";
42914
+ } catch {
42915
+ return "ours";
42916
+ }
42917
+ }
42883
42918
  function unacceptableTarget(req) {
42884
42919
  try {
42885
42920
  assertSafeTargetUrl(req.targetRepo);
@@ -42960,7 +42995,8 @@ async function verifyWorkingDiff(req) {
42960
42995
  const ctx = {
42961
42996
  startedAt: Date.now(),
42962
42997
  runId: req.runId ?? `run-${randomUUID3().slice(0, 8)}`,
42963
- touchedPaths: []
42998
+ touchedPaths: [],
42999
+ imageChosenByRepository: false
42964
43000
  };
42965
43001
  const target = {
42966
43002
  claimId: req.claimId,
@@ -42975,6 +43011,10 @@ async function verifyWorkingDiff(req) {
42975
43011
  throw err;
42976
43012
  return {
42977
43013
  result: refusedRun({
43014
+ // `repository` survives only when the repository's files alone chose the image.
43015
+ // `resolvePublishedImage` knows the version came from the repo, but not whether an
43016
+ // override picked the image variant the missing tag belongs to (Codex, TERM-1313).
43017
+ origin: refusalOriginOf(refusal2) === "repository" && ctx.imageChosenByRepository ? "repository" : "ours",
42978
43018
  runId: ctx.runId,
42979
43019
  claimId: target.claimId,
42980
43020
  // `describeThrown`, not `refusal.message`. Classifying a value does not make
@@ -43042,6 +43082,7 @@ async function runVerification(req, ctx) {
43042
43082
  if (badTarget !== null) {
43043
43083
  return {
43044
43084
  result: refusedRun({
43085
+ origin: "ours",
43045
43086
  runId,
43046
43087
  claimId: req.claimId,
43047
43088
  reason: badTarget,
@@ -43065,6 +43106,7 @@ async function runVerification(req, ctx) {
43065
43106
  if (placement.refusal !== null) {
43066
43107
  return {
43067
43108
  result: refusedRun({
43109
+ origin: "ours",
43068
43110
  runId,
43069
43111
  claimId: req.claimId,
43070
43112
  reason: placement.refusal,
@@ -43108,6 +43150,7 @@ async function runVerification(req, ctx) {
43108
43150
  const first = pre.refusals[0];
43109
43151
  return {
43110
43152
  result: refusedRun({
43153
+ origin: "ours",
43111
43154
  runId,
43112
43155
  claimId: req.claimId,
43113
43156
  reason: first?.detail ?? "the diff was refused by the local slice pre-flight, but no reason was recorded",
@@ -43142,6 +43185,7 @@ async function runVerification(req, ctx) {
43142
43185
  // there and passing it unconditionally keeps one code path instead of two.
43143
43186
  ...req.targetAuth ? { auth: req.targetAuth } : {}
43144
43187
  });
43188
+ const pinnedImageInputs = imageInputsAt(cloneDir);
43145
43189
  const baselinePatch = source.kind === "working-diff" ? source.baselinePatch : void 0;
43146
43190
  const hasBaselinePatch = baselinePatch !== void 0 && baselinePatch.trim() !== "";
43147
43191
  if (hasBaselinePatch) {
@@ -43162,6 +43206,9 @@ async function runVerification(req, ctx) {
43162
43206
  if (lockfileRefusals.length > 0) {
43163
43207
  return {
43164
43208
  result: refusedRun({
43209
+ // The developer's diff, not the repository's environment, so never `repository`
43210
+ // (TERM-1313). Only a working diff is judged here; a dispatched baseline has none.
43211
+ origin: "ours",
43165
43212
  runId,
43166
43213
  claimId: req.claimId,
43167
43214
  reason: lockfileRefusals[0]?.detail ?? "a lockfile in the diff was refused",
@@ -43183,6 +43230,7 @@ async function runVerification(req, ctx) {
43183
43230
  const baselinePatchSha256 = hasBaselinePatch ? sha256Hex(baselinePatch ?? "") : null;
43184
43231
  const derived = deriveEnvironmentSpec(cloneDir);
43185
43232
  const { spec, imageSource } = resolveRunEnvironment(derived, req);
43233
+ ctx.imageChosenByRepository = imageSource === "detected" && imageVariantFor(spec) === imageVariantFor(derived) && pinnedImageInputs !== null && pinnedImageInputs.runtime === spec.runtime && pinnedImageInputs.runtimeVersion === spec.runtimeVersion && pinnedImageInputs.variant === imageVariantFor(spec);
43186
43234
  progress("derive", `runtime=${spec.runtime} install=${String(spec.installCommand)} test=${String(spec.testCommand)}`);
43187
43235
  const unfrozenNote = installUnfrozenNote(spec);
43188
43236
  if (unfrozenNote !== null)
@@ -43193,6 +43241,7 @@ async function runVerification(req, ctx) {
43193
43241
  if (!resolved.ok) {
43194
43242
  return {
43195
43243
  result: refusedRun({
43244
+ origin: "ours",
43196
43245
  runId,
43197
43246
  claimId: req.claimId,
43198
43247
  reason: resolved.refusal,
@@ -43304,7 +43353,9 @@ async function runVerification(req, ctx) {
43304
43353
  // Built from the LEASE, over the client that ran the steps — never from
43305
43354
  // `req.placement`, which is a request. `venueDescriptor.ts` carries the
43306
43355
  // reasoning and the #735 failure that makes the distinction load-bearing.
43307
- venue: describeVenue(lease)
43356
+ venue: describeVenue(lease),
43357
+ // A run that reached a verdict was not refused, so neither side refused it.
43358
+ refusalOrigin: null
43308
43359
  };
43309
43360
  let later = null;
43310
43361
  if (req.screenshots !== void 0) {
@@ -29890,7 +29890,7 @@ function resolvePublishedImage(image, runtime, version2, variant) {
29890
29890
  if (shape && shape.declaredIsFloor && atLeast(shape.defaultVersion, version2)) {
29891
29891
  return unversionedImage(shape);
29892
29892
  }
29893
- throw new RunRefusalError(`the repo declares ${runtime} ${version2}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.");
29893
+ throw new RunRefusalError(`the repo declares ${runtime} ${version2}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.", { origin: "repository" });
29894
29894
  }
29895
29895
  function resolveImageForSpec(spec, override) {
29896
29896
  const variant = imageVariantFor(spec);
@@ -30129,6 +30129,17 @@ var init_execute = __esm({
30129
30129
  EnvRunError = class extends Error {
30130
30130
  };
30131
30131
  RunRefusalError = class extends EnvRunError {
30132
+ /**
30133
+ * Whose side refused (TERM-1313), set at the throw and never read back out of the message.
30134
+ * A baseline intake labels a posting not-runnable on `repository`, so that value is passed
30135
+ * only where envrun can show the repository asked for something we cannot supply. Every
30136
+ * other refusal, including one nobody has classified yet, is `ours` by default.
30137
+ */
30138
+ origin;
30139
+ constructor(message2, options) {
30140
+ super(message2, options);
30141
+ this.origin = options?.origin ?? "ours";
30142
+ }
30132
30143
  };
30133
30144
  MAX_CAUSE_FRAMES = 16;
30134
30145
  CHAIN_UNREADABLE = "<the cause chain stopped: a value refused to be read>";
@@ -31050,7 +31061,8 @@ var init_result = __esm({
31050
31061
  "imageSource",
31051
31062
  "leaksClean",
31052
31063
  "leakState",
31053
- "venue"
31064
+ "venue",
31065
+ "refusalOrigin"
31054
31066
  ];
31055
31067
  RENDER_NONE = null;
31056
31068
  FIELD_VIEWS = {
@@ -31110,7 +31122,10 @@ var init_result = __esm({
31110
31122
  // Absent on most runs, so it prints only when there is something to say. Silence
31111
31123
  // here is the honest rendering of "no venue answered": a placeholder line would
31112
31124
  // invite a reader to treat an unanswered probe as a described venue.
31113
- venue: (r) => r.venue === null ? null : renderVenueLine(r.venue)
31125
+ venue: (r) => r.venue === null ? null : renderVenueLine(r.venue),
31126
+ // For the worker and the baseline intake, not the terminal: `reason` already says which
31127
+ // side refused in words a developer reads.
31128
+ refusalOrigin: RENDER_NONE
31114
31129
  };
31115
31130
  }
31116
31131
  });
@@ -37588,6 +37603,18 @@ function applyPatch(repoDir, patch, what) {
37588
37603
  throw new ThRunError(`the ${what} did not apply cleanly to the target checkout: ${(res.stderr ?? "").trim()}. The diff was built against a different commit than the one being verified.`);
37589
37604
  }
37590
37605
  }
37606
+ function imageInputsAt(repoDir) {
37607
+ try {
37608
+ const pinned = deriveEnvironmentSpec(repoDir);
37609
+ return {
37610
+ runtime: pinned.runtime,
37611
+ runtimeVersion: pinned.runtimeVersion,
37612
+ variant: imageVariantFor(pinned)
37613
+ };
37614
+ } catch {
37615
+ return null;
37616
+ }
37617
+ }
37591
37618
  function tail(text, bytes = OUTPUT_TAIL_BYTES) {
37592
37619
  return text.length <= bytes ? text : text.slice(-bytes);
37593
37620
  }
@@ -37643,9 +37670,17 @@ function refusedRun(fields) {
37643
37670
  // A refused run never held a lease, so there is no venue to describe. Same
37644
37671
  // reasoning as `leaksClean` above: null because nothing happened, and it must
37645
37672
  // not read as a venue we looked at and could not name.
37646
- venue: null
37673
+ venue: null,
37674
+ refusalOrigin: fields.origin
37647
37675
  };
37648
37676
  }
37677
+ function refusalOriginOf(refusal2) {
37678
+ try {
37679
+ return refusal2.origin === "repository" ? "repository" : "ours";
37680
+ } catch {
37681
+ return "ours";
37682
+ }
37683
+ }
37649
37684
  function unacceptableTarget(req) {
37650
37685
  try {
37651
37686
  assertSafeTargetUrl(req.targetRepo);
@@ -37726,7 +37761,8 @@ async function verifyWorkingDiff(req) {
37726
37761
  const ctx = {
37727
37762
  startedAt: Date.now(),
37728
37763
  runId: req.runId ?? `run-${randomUUID3().slice(0, 8)}`,
37729
- touchedPaths: []
37764
+ touchedPaths: [],
37765
+ imageChosenByRepository: false
37730
37766
  };
37731
37767
  const target = {
37732
37768
  claimId: req.claimId,
@@ -37741,6 +37777,10 @@ async function verifyWorkingDiff(req) {
37741
37777
  throw err;
37742
37778
  return {
37743
37779
  result: refusedRun({
37780
+ // `repository` survives only when the repository's files alone chose the image.
37781
+ // `resolvePublishedImage` knows the version came from the repo, but not whether an
37782
+ // override picked the image variant the missing tag belongs to (Codex, TERM-1313).
37783
+ origin: refusalOriginOf(refusal2) === "repository" && ctx.imageChosenByRepository ? "repository" : "ours",
37744
37784
  runId: ctx.runId,
37745
37785
  claimId: target.claimId,
37746
37786
  // `describeThrown`, not `refusal.message`. Classifying a value does not make
@@ -37808,6 +37848,7 @@ async function runVerification(req, ctx) {
37808
37848
  if (badTarget !== null) {
37809
37849
  return {
37810
37850
  result: refusedRun({
37851
+ origin: "ours",
37811
37852
  runId,
37812
37853
  claimId: req.claimId,
37813
37854
  reason: badTarget,
@@ -37831,6 +37872,7 @@ async function runVerification(req, ctx) {
37831
37872
  if (placement.refusal !== null) {
37832
37873
  return {
37833
37874
  result: refusedRun({
37875
+ origin: "ours",
37834
37876
  runId,
37835
37877
  claimId: req.claimId,
37836
37878
  reason: placement.refusal,
@@ -37874,6 +37916,7 @@ async function runVerification(req, ctx) {
37874
37916
  const first = pre.refusals[0];
37875
37917
  return {
37876
37918
  result: refusedRun({
37919
+ origin: "ours",
37877
37920
  runId,
37878
37921
  claimId: req.claimId,
37879
37922
  reason: first?.detail ?? "the diff was refused by the local slice pre-flight, but no reason was recorded",
@@ -37908,6 +37951,7 @@ async function runVerification(req, ctx) {
37908
37951
  // there and passing it unconditionally keeps one code path instead of two.
37909
37952
  ...req.targetAuth ? { auth: req.targetAuth } : {}
37910
37953
  });
37954
+ const pinnedImageInputs = imageInputsAt(cloneDir);
37911
37955
  const baselinePatch = source.kind === "working-diff" ? source.baselinePatch : void 0;
37912
37956
  const hasBaselinePatch = baselinePatch !== void 0 && baselinePatch.trim() !== "";
37913
37957
  if (hasBaselinePatch) {
@@ -37928,6 +37972,9 @@ async function runVerification(req, ctx) {
37928
37972
  if (lockfileRefusals.length > 0) {
37929
37973
  return {
37930
37974
  result: refusedRun({
37975
+ // The developer's diff, not the repository's environment, so never `repository`
37976
+ // (TERM-1313). Only a working diff is judged here; a dispatched baseline has none.
37977
+ origin: "ours",
37931
37978
  runId,
37932
37979
  claimId: req.claimId,
37933
37980
  reason: lockfileRefusals[0]?.detail ?? "a lockfile in the diff was refused",
@@ -37949,6 +37996,7 @@ async function runVerification(req, ctx) {
37949
37996
  const baselinePatchSha256 = hasBaselinePatch ? sha256Hex(baselinePatch ?? "") : null;
37950
37997
  const derived = deriveEnvironmentSpec(cloneDir);
37951
37998
  const { spec, imageSource } = resolveRunEnvironment(derived, req);
37999
+ ctx.imageChosenByRepository = imageSource === "detected" && imageVariantFor(spec) === imageVariantFor(derived) && pinnedImageInputs !== null && pinnedImageInputs.runtime === spec.runtime && pinnedImageInputs.runtimeVersion === spec.runtimeVersion && pinnedImageInputs.variant === imageVariantFor(spec);
37952
38000
  progress("derive", `runtime=${spec.runtime} install=${String(spec.installCommand)} test=${String(spec.testCommand)}`);
37953
38001
  const unfrozenNote = installUnfrozenNote(spec);
37954
38002
  if (unfrozenNote !== null)
@@ -37959,6 +38007,7 @@ async function runVerification(req, ctx) {
37959
38007
  if (!resolved.ok) {
37960
38008
  return {
37961
38009
  result: refusedRun({
38010
+ origin: "ours",
37962
38011
  runId,
37963
38012
  claimId: req.claimId,
37964
38013
  reason: resolved.refusal,
@@ -38070,7 +38119,9 @@ async function runVerification(req, ctx) {
38070
38119
  // Built from the LEASE, over the client that ran the steps — never from
38071
38120
  // `req.placement`, which is a request. `venueDescriptor.ts` carries the
38072
38121
  // reasoning and the #735 failure that makes the distinction load-bearing.
38073
- venue: describeVenue(lease)
38122
+ venue: describeVenue(lease),
38123
+ // A run that reached a verdict was not refused, so neither side refused it.
38124
+ refusalOrigin: null
38074
38125
  };
38075
38126
  let later = null;
38076
38127
  if (req.screenshots !== void 0) {
@@ -3724,7 +3724,7 @@ function resolvePublishedImage(image, runtime, version, variant) {
3724
3724
  if (shape && shape.declaredIsFloor && atLeast(shape.defaultVersion, version)) {
3725
3725
  return unversionedImage(shape);
3726
3726
  }
3727
- throw new RunRefusalError(`the repo declares ${runtime} ${version}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.");
3727
+ throw new RunRefusalError(`the repo declares ${runtime} ${version}, and no image is published at ${image}` + (shape && shape.declaredIsFloor ? `. Our default is ${shape.defaultVersion}, which is OLDER than that, so falling back would run the repo under a toolchain it says it cannot use` : `. ${runtime} treats a declared version as an exact pin, not a minimum, so a different one is a different environment`) + ". Refusing rather than booting a version the repo did not ask for \u2014 that substitution is what made this class of failure unattributable (TERM-643). Pass an explicit image to override.", { origin: "repository" });
3728
3728
  }
3729
3729
  function resolveImageForSpec(spec, override) {
3730
3730
  const variant = imageVariantFor(spec);
@@ -3963,6 +3963,17 @@ var init_execute = __esm({
3963
3963
  EnvRunError = class extends Error {
3964
3964
  };
3965
3965
  RunRefusalError = class extends EnvRunError {
3966
+ /**
3967
+ * Whose side refused (TERM-1313), set at the throw and never read back out of the message.
3968
+ * A baseline intake labels a posting not-runnable on `repository`, so that value is passed
3969
+ * only where envrun can show the repository asked for something we cannot supply. Every
3970
+ * other refusal, including one nobody has classified yet, is `ours` by default.
3971
+ */
3972
+ origin;
3973
+ constructor(message2, options) {
3974
+ super(message2, options);
3975
+ this.origin = options?.origin ?? "ours";
3976
+ }
3966
3977
  };
3967
3978
  MAX_CAUSE_FRAMES = 16;
3968
3979
  CHAIN_UNREADABLE = "<the cause chain stopped: a value refused to be read>";
@@ -4884,7 +4895,8 @@ var init_result = __esm({
4884
4895
  "imageSource",
4885
4896
  "leaksClean",
4886
4897
  "leakState",
4887
- "venue"
4898
+ "venue",
4899
+ "refusalOrigin"
4888
4900
  ];
4889
4901
  RENDER_NONE = null;
4890
4902
  FIELD_VIEWS = {
@@ -4944,7 +4956,10 @@ var init_result = __esm({
4944
4956
  // Absent on most runs, so it prints only when there is something to say. Silence
4945
4957
  // here is the honest rendering of "no venue answered": a placeholder line would
4946
4958
  // invite a reader to treat an unanswered probe as a described venue.
4947
- venue: (r) => r.venue === null ? null : renderVenueLine(r.venue)
4959
+ venue: (r) => r.venue === null ? null : renderVenueLine(r.venue),
4960
+ // For the worker and the baseline intake, not the terminal: `reason` already says which
4961
+ // side refused in words a developer reads.
4962
+ refusalOrigin: RENDER_NONE
4948
4963
  };
4949
4964
  }
4950
4965
  });
@@ -11597,6 +11612,18 @@ function applyPatch(repoDir, patch, what) {
11597
11612
  throw new ThRunError(`the ${what} did not apply cleanly to the target checkout: ${(res.stderr ?? "").trim()}. The diff was built against a different commit than the one being verified.`);
11598
11613
  }
11599
11614
  }
11615
+ function imageInputsAt(repoDir) {
11616
+ try {
11617
+ const pinned = deriveEnvironmentSpec(repoDir);
11618
+ return {
11619
+ runtime: pinned.runtime,
11620
+ runtimeVersion: pinned.runtimeVersion,
11621
+ variant: imageVariantFor(pinned)
11622
+ };
11623
+ } catch {
11624
+ return null;
11625
+ }
11626
+ }
11600
11627
  function tail(text, bytes = OUTPUT_TAIL_BYTES) {
11601
11628
  return text.length <= bytes ? text : text.slice(-bytes);
11602
11629
  }
@@ -11652,9 +11679,17 @@ function refusedRun(fields) {
11652
11679
  // A refused run never held a lease, so there is no venue to describe. Same
11653
11680
  // reasoning as `leaksClean` above: null because nothing happened, and it must
11654
11681
  // not read as a venue we looked at and could not name.
11655
- venue: null
11682
+ venue: null,
11683
+ refusalOrigin: fields.origin
11656
11684
  };
11657
11685
  }
11686
+ function refusalOriginOf(refusal2) {
11687
+ try {
11688
+ return refusal2.origin === "repository" ? "repository" : "ours";
11689
+ } catch {
11690
+ return "ours";
11691
+ }
11692
+ }
11658
11693
  function unacceptableTarget(req) {
11659
11694
  try {
11660
11695
  assertSafeTargetUrl(req.targetRepo);
@@ -11735,7 +11770,8 @@ async function verifyWorkingDiff(req) {
11735
11770
  const ctx = {
11736
11771
  startedAt: Date.now(),
11737
11772
  runId: req.runId ?? `run-${randomUUID().slice(0, 8)}`,
11738
- touchedPaths: []
11773
+ touchedPaths: [],
11774
+ imageChosenByRepository: false
11739
11775
  };
11740
11776
  const target = {
11741
11777
  claimId: req.claimId,
@@ -11750,6 +11786,10 @@ async function verifyWorkingDiff(req) {
11750
11786
  throw err;
11751
11787
  return {
11752
11788
  result: refusedRun({
11789
+ // `repository` survives only when the repository's files alone chose the image.
11790
+ // `resolvePublishedImage` knows the version came from the repo, but not whether an
11791
+ // override picked the image variant the missing tag belongs to (Codex, TERM-1313).
11792
+ origin: refusalOriginOf(refusal2) === "repository" && ctx.imageChosenByRepository ? "repository" : "ours",
11753
11793
  runId: ctx.runId,
11754
11794
  claimId: target.claimId,
11755
11795
  // `describeThrown`, not `refusal.message`. Classifying a value does not make
@@ -11817,6 +11857,7 @@ async function runVerification(req, ctx) {
11817
11857
  if (badTarget !== null) {
11818
11858
  return {
11819
11859
  result: refusedRun({
11860
+ origin: "ours",
11820
11861
  runId,
11821
11862
  claimId: req.claimId,
11822
11863
  reason: badTarget,
@@ -11840,6 +11881,7 @@ async function runVerification(req, ctx) {
11840
11881
  if (placement.refusal !== null) {
11841
11882
  return {
11842
11883
  result: refusedRun({
11884
+ origin: "ours",
11843
11885
  runId,
11844
11886
  claimId: req.claimId,
11845
11887
  reason: placement.refusal,
@@ -11883,6 +11925,7 @@ async function runVerification(req, ctx) {
11883
11925
  const first = pre.refusals[0];
11884
11926
  return {
11885
11927
  result: refusedRun({
11928
+ origin: "ours",
11886
11929
  runId,
11887
11930
  claimId: req.claimId,
11888
11931
  reason: first?.detail ?? "the diff was refused by the local slice pre-flight, but no reason was recorded",
@@ -11917,6 +11960,7 @@ async function runVerification(req, ctx) {
11917
11960
  // there and passing it unconditionally keeps one code path instead of two.
11918
11961
  ...req.targetAuth ? { auth: req.targetAuth } : {}
11919
11962
  });
11963
+ const pinnedImageInputs = imageInputsAt(cloneDir);
11920
11964
  const baselinePatch = source.kind === "working-diff" ? source.baselinePatch : void 0;
11921
11965
  const hasBaselinePatch = baselinePatch !== void 0 && baselinePatch.trim() !== "";
11922
11966
  if (hasBaselinePatch) {
@@ -11937,6 +11981,9 @@ async function runVerification(req, ctx) {
11937
11981
  if (lockfileRefusals.length > 0) {
11938
11982
  return {
11939
11983
  result: refusedRun({
11984
+ // The developer's diff, not the repository's environment, so never `repository`
11985
+ // (TERM-1313). Only a working diff is judged here; a dispatched baseline has none.
11986
+ origin: "ours",
11940
11987
  runId,
11941
11988
  claimId: req.claimId,
11942
11989
  reason: lockfileRefusals[0]?.detail ?? "a lockfile in the diff was refused",
@@ -11958,6 +12005,7 @@ async function runVerification(req, ctx) {
11958
12005
  const baselinePatchSha256 = hasBaselinePatch ? sha256Hex(baselinePatch ?? "") : null;
11959
12006
  const derived = deriveEnvironmentSpec(cloneDir);
11960
12007
  const { spec, imageSource } = resolveRunEnvironment(derived, req);
12008
+ ctx.imageChosenByRepository = imageSource === "detected" && imageVariantFor(spec) === imageVariantFor(derived) && pinnedImageInputs !== null && pinnedImageInputs.runtime === spec.runtime && pinnedImageInputs.runtimeVersion === spec.runtimeVersion && pinnedImageInputs.variant === imageVariantFor(spec);
11961
12009
  progress("derive", `runtime=${spec.runtime} install=${String(spec.installCommand)} test=${String(spec.testCommand)}`);
11962
12010
  const unfrozenNote = installUnfrozenNote(spec);
11963
12011
  if (unfrozenNote !== null)
@@ -11968,6 +12016,7 @@ async function runVerification(req, ctx) {
11968
12016
  if (!resolved.ok) {
11969
12017
  return {
11970
12018
  result: refusedRun({
12019
+ origin: "ours",
11971
12020
  runId,
11972
12021
  claimId: req.claimId,
11973
12022
  reason: resolved.refusal,
@@ -12079,7 +12128,9 @@ async function runVerification(req, ctx) {
12079
12128
  // Built from the LEASE, over the client that ran the steps — never from
12080
12129
  // `req.placement`, which is a request. `venueDescriptor.ts` carries the
12081
12130
  // reasoning and the #735 failure that makes the distinction load-bearing.
12082
- venue: describeVenue(lease)
12131
+ venue: describeVenue(lease),
12132
+ // A run that reached a verdict was not refused, so neither side refused it.
12133
+ refusalOrigin: null
12083
12134
  };
12084
12135
  let later = null;
12085
12136
  if (req.screenshots !== void 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminalhire",
3
- "version": "0.42.38",
3
+ "version": "0.42.39",
4
4
  "description": "Developer jobs and paid bounties, matched in the terminal — ambient matches in the Claude Code spinner. Claim a scoped bounty and get paid when the poster accepts it.",
5
5
  "repository": {
6
6
  "type": "git",