Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions runs/offload-test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,36 @@ describe("offload-test staged mode", () => {
},
);

it.effect("a dead stage's marker keeps the platform's own incident id", () => {
const { layer, handles } = makeCFRuntimeTest({
sandboxProgram: {
// What a dying container actually reports. The class is the half a
// consumer can already infer; the reference is the half only the
// platform's operator can act on, and it used to be dropped.
"run-a": {
fail: "ExecFailed",
exitCode: -1,
stderrTail: "exec failed (exit -1): internal error; reference = aggq3f5m407e2vb2ht76l2vf",
},
},
config: {
"offload-test.stages:owner/name": "a",
"offload-test.command:owner/name:a": "run-a",
},
});

return Effect.gen(function* () {
yield* Effect.exit(offloadTest.run(webhookInput));
const markerWrite = handles.sandbox.execs.find((e) => e.command.includes("stage=a"));
expect(markerWrite?.command).toContain("reference=aggq3f5m407e2vb2ht76l2vf");
// Shell-safe by construction: whatever lands after `reference=` is drawn
// from `[A-Za-z0-9_-]` only, so no vendor text can close the quote the
// marker is printed inside.
const id = /reference=([^\s']*)/.exec(markerWrite?.command ?? "")?.[1];
expect(id).toMatch(/^[A-Za-z0-9_-]+$/);
}).pipe(Effect.provide(layer));
});

it.effect(
"an Action dispatch that passes `command` stays single-exec even with stages set",
() => {
Expand Down
26 changes: 23 additions & 3 deletions runs/offload-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,29 @@ export const offloadTest = defineRun({
});
const elapsedMs = (yield* io.now) - stageStartMs;
const elapsedS = Math.round(elapsedMs / 1000);
// Label (STAGE_LABEL_RE), tag, and number only — shell-quote-safe
// by construction.
const markerLine = `stage=${stage.label} error=${errorClass} elapsedMs=${elapsedMs}`;
// Label (STAGE_LABEL_RE), tag, numbers, and — when the platform
// supplied one — its own incident id.
//
// `ExecFailed: exec failed (exit -1): internal error; reference =
// aggq3f5m407e2vb2ht76l2vf` is what a dying container reports, and
// that reference is the only thing that identifies the incident to
// the platform's operator. The marker used to record the CLASS and
// drop the id, which is the half a consumer can already infer from
// the fact that their stage died.
//
// EXTRACTED, not interpolated: the marker is shell-quoted into a
// `printf '%s\n' '<line>'`, so free vendor text could close the
// quote. A `[A-Za-z0-9_-]` id and a signed integer cannot.
const rendered = Option.match(Cause.failureOption(exit.cause), {
onSome: (f) => `${String((f as { cause?: unknown }).cause ?? "")} ${String((f as { message?: unknown }).message ?? "")}`,
onNone: () => "",
});
const reference = /reference\s*=\s*([A-Za-z0-9_-]{1,64})/.exec(rendered)?.[1];
const platformExit = /exit\s+(-?\d{1,5})\)/.exec(rendered)?.[1];
const markerLine =
`stage=${stage.label} error=${errorClass} elapsedMs=${elapsedMs}` +
(platformExit !== undefined ? ` exit=${platformExit}` : "") +
(reference !== undefined ? ` reference=${reference}` : "");
// The marker rides the marker exec's OWN log stream: `sandbox.exec`
// streams stdout to an R2 log key and returns it as `logPath`, so
// uploading THAT key in R2-source mode (no `container` — same mode
Expand Down
Loading