diff --git a/.github/scripts/runner-loss-rerun.mjs b/.github/scripts/runner-loss-rerun.mjs new file mode 100644 index 00000000000..8a94ece7ddd --- /dev/null +++ b/.github/scripts/runner-loss-rerun.mjs @@ -0,0 +1,205 @@ +#!/usr/bin/env node +/** + * runner-loss-rerun.mjs + * + * Re-runs the failed jobs of a first PR CI attempt once, but only when every + * failed job failed because its runner was lost. Runs from + * .github/workflows/ci-runner-loss-rerun.yml on workflow_run. It reads GitHub + * API metadata only and never touches the PR's code or artifacts. + * + * Local dry run against a real run (no rerun is requested): + * GITHUB_TOKEN=$(gh auth token) node .github/scripts/runner-loss-rerun.mjs --run-id --dry-run + */ +import { appendFileSync, readFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +export const REPOSITORY = "paperclipai/paperclip"; +export const REPOSITORY_ID = 1170821064; +export const PR_WORKFLOW_PATH = ".github/workflows/pr.yml"; + +// The runner's own messages when an AWS instance disappears mid-job. +export const RUNNER_LOSS_PATTERN = /lost communication with the server|received a shutdown signal/; +// `verify` and `e2e` in pr-trusted.yml only assert their `needs` results. They +// fail whenever a dependency failed and re-run with it. +export const AGGREGATE_JOBS = new Set(["ci / verify", "ci / e2e"]); +// ci-routing.yml checks the attempt's triggering actor. A bot-triggered attempt +// would move the whole run to GitHub-hosted runners, so leave it to a human. +export const GATE_JOB_PREFIX = "ci / gate / "; +// A shutdown signal often reaches the check run only as this annotation; the +// signal itself is logged as an error line in the job log. +const CANCELLED_MESSAGE = "The operation was canceled."; + +export function createGithubClient({ token, fetcher = fetch, apiUrl = "https://api.github.com" }) { + if (!token) throw new Error("GITHUB_TOKEN is required"); + const origin = new URL(apiUrl).origin; + const request = async (target, { method = "GET" } = {}) => { + const url = new URL(target, apiUrl); + if (url.origin !== origin) throw new Error(`Refusing to call ${url.origin}`); + const response = await fetcher(url.href, { + method, + headers: { Accept: "application/vnd.github+json", Authorization: `Bearer ${token}`, "X-GitHub-Api-Version": "2022-11-28" }, + signal: AbortSignal.timeout(60_000), + }); + if (!response.ok) throw new Error(`GitHub API ${method} ${url.pathname} failed (HTTP ${response.status})`); + return response; + }; + return { + json: async (target) => (await request(target)).json(), + // Follows Link rel="next" until the last page. `field` selects the array + // in wrapped responses such as { total_count, jobs }. + paginate: async (target, field) => { + const items = []; + let totalCount; + for (let next = target, pages = 0; next; pages += 1) { + if (pages >= 100) throw new Error(`Too many pages for ${target}`); + const response = await request(next); + const body = await response.json(); + const page = field ? body[field] : body; + if (!Array.isArray(page)) throw new Error(`Unexpected page shape for ${target}`); + items.push(...page); + if (field && Number.isInteger(body.total_count)) totalCount = body.total_count; + next = /<([^>]+)>;\s*rel="next"/.exec(response.headers.get("link") ?? "")?.[1]; + } + if (totalCount !== undefined && items.length !== totalCount) { + throw new Error(`Incomplete listing for ${target}: ${items.length} of ${totalCount}`); + } + return items; + }, + // Job logs answer with a redirect to a signed download URL. + text: async (target) => (await request(target)).text(), + post: async (target) => { await request(target, { method: "POST" }); }, + }; +} + +export function logShowsRunnerLoss(log) { + return log.split("\n").some((line) => line.includes("##[error]") && RUNNER_LOSS_PATTERN.test(line)); +} + +/** Classifies one failed job. Logs are read only when annotations are inconclusive. */ +export async function classifyJob(job, { annotations, readLog }) { + const failures = annotations.filter((annotation) => annotation.annotation_level === "failure"); + const isRunnerLoss = (annotation) => RUNNER_LOSS_PATTERN.test(annotation.message ?? ""); + // A step can fail for a real reason before the runner is lost (for example a + // test failure, then a loss during an always() upload step). Any failure + // annotation other than runner loss or cancellation marks a real failure. + const real = failures.find((annotation) => !isRunnerLoss(annotation) && annotation.message !== CANCELLED_MESSAGE); + if (real) return { lost: false, evidence: firstLine(real.message) }; + const match = failures.find(isRunnerLoss); + if (match) return { lost: true, evidence: firstLine(match.message) }; + // Only cancellations are left: the shutdown signal, if any, is in the log. + if (failures.length > 0) { + if (logShowsRunnerLoss(await readLog(job))) { + return { lost: true, evidence: "job log: runner received a shutdown signal or lost communication" }; + } + return { lost: false, evidence: `${CANCELLED_MESSAGE} (no runner-loss error in the job log)` }; + } + return { lost: false, evidence: "no failure annotation" }; +} + +function firstLine(message) { + const line = String(message).split("\n")[0]; + return line.length > 160 ? `${line.slice(0, 157)}...` : line; +} + +export function eligibleRun(run) { + if (run.repository?.full_name !== REPOSITORY || run.repository?.id !== REPOSITORY_ID) return "run is not in the canonical repository"; + if (run.path !== PR_WORKFLOW_PATH) return `workflow is ${run.path}, not ${PR_WORKFLOW_PATH}`; + if (run.event !== "pull_request") return `event is ${run.event}, not pull_request`; + if (run.status !== "completed" || run.conclusion !== "failure") return `run is ${run.status}/${run.conclusion}, not completed/failure`; + // One automatic re-run only. A higher attempt also means someone re-ran it. + if (run.run_attempt !== 1) return `run is on attempt ${run.run_attempt}; only attempt 1 is re-run automatically`; + return undefined; +} + +/** + * Re-running an older run joins the PR's `cancel-in-progress` concurrency + * group and would cancel newer CI. Require the run to be the latest CI for the + * PR's current head. + */ +export async function staleReason(client, run) { + const pulls = await client.paginate(`/repos/${REPOSITORY}/commits/${run.head_sha}/pulls?per_page=100`); + const open = pulls.filter((pr) => pr.state === "open" && pr.base?.repo?.id === REPOSITORY_ID + && pr.head?.repo?.id === run.head_repository?.id && pr.head?.sha === run.head_sha); + if (open.length === 0) return "no open pull request still has this run's head commit"; + const runs = await client.paginate( + `/repos/${REPOSITORY}/actions/workflows/pr.yml/runs?event=pull_request&head_sha=${run.head_sha}&per_page=100`, + "workflow_runs", + ); + const newer = runs.find((candidate) => candidate.id > run.id && candidate.conclusion !== "skipped"); + if (newer) return `a newer PR run (${newer.id}) exists for this head commit`; + return undefined; +} + +export async function decide(client, run) { + const decision = { runId: run.id, attempt: run.run_attempt, rerun: false, jobs: [] }; + const ineligible = eligibleRun(run); + if (ineligible) return { ...decision, reason: ineligible }; + + const jobs = await client.paginate(`/repos/${REPOSITORY}/actions/runs/${run.id}/attempts/1/jobs?per_page=100`, "jobs"); + const failed = jobs.filter((job) => job.conclusion === "failure" && !AGGREGATE_JOBS.has(job.name)); + if (failed.length === 0) return { ...decision, reason: "no failed jobs other than the verify/e2e aggregates" }; + + for (const job of failed) { + if (job.name.startsWith(GATE_JOB_PREFIX)) { + decision.jobs.push({ id: job.id, name: job.name, lost: false, evidence: "routing gate failed; a bot re-run would lose AWS routing" }); + continue; + } + const annotations = await client.paginate(`/repos/${REPOSITORY}/check-runs/${job.id}/annotations?per_page=100`); + const readLog = (entry) => client.text(`/repos/${REPOSITORY}/actions/jobs/${entry.id}/logs`); + decision.jobs.push({ id: job.id, name: job.name, ...(await classifyJob(job, { annotations, readLog })) }); + } + + const real = decision.jobs.filter((job) => !job.lost); + if (real.length) return { ...decision, reason: `${real.length} of ${failed.length} failed jobs did not lose their runner` }; + + const stale = await staleReason(client, run); + if (stale) return { ...decision, reason: stale }; + return { ...decision, rerun: true, reason: `all ${failed.length} failed jobs lost their runner` }; +} + +export function renderSummary(decision, { dryRun = false } = {}) { + const action = decision.rerun ? (dryRun ? "Would re-run failed jobs (dry run)" : "Re-ran failed jobs") : "No automatic re-run"; + const lines = [ + "### CI runner-loss re-run", "", + `**${action}** for run ${decision.runId} attempt ${decision.attempt}: ${decision.reason}.`, "", + ]; + if (decision.jobs.length) { + lines.push("| Job | Runner lost | Evidence |", "| --- | --- | --- |"); + for (const job of decision.jobs) { + lines.push(`| ${escapeCell(job.name)} | ${job.lost ? "yes" : "no"} | ${escapeCell(job.evidence)} |`); + } + lines.push(""); + } + return `${lines.join("\n")}\n`; +} + +const escapeCell = (value) => String(value).replace(/\|/g, "\\|").replace(/[\r\n]+/g, " "); + +export async function main({ env = process.env, argv = process.argv.slice(2), fetcher = fetch, log = console.log } = {}) { + const dryRun = argv.includes("--dry-run"); + const argRunId = argv[argv.indexOf("--run-id") + 1]; + const event = env.GITHUB_EVENT_PATH ? JSON.parse(readFileSync(env.GITHUB_EVENT_PATH, "utf8")) : undefined; + const runId = argv.includes("--run-id") ? argRunId : event?.workflow_run?.id; + if (!/^[1-9]\d*$/.test(String(runId))) throw new Error("Provide --run-id or a workflow_run event"); + const client = createGithubClient({ token: env.GITHUB_TOKEN, fetcher }); + + // Read the run's current state rather than the event snapshot: its attempt + // number is above 1 if anyone re-ran it after this event was queued. + const run = await client.json(`/repos/${REPOSITORY}/actions/runs/${runId}`); + const decision = await decide(client, run); + if (decision.rerun && !dryRun) { + await client.post(`/repos/${REPOSITORY}/actions/runs/${run.id}/rerun-failed-jobs`); + } + const summary = renderSummary(decision, { dryRun }); + log(summary); + if (env.GITHUB_STEP_SUMMARY) appendFileSync(env.GITHUB_STEP_SUMMARY, summary); + return decision; +} + +if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + main().catch((error) => { + console.error(error.message); + process.exitCode = 1; + }); +} diff --git a/.github/scripts/tests/fixtures/runner-loss-rerun/run-42264785415.json b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42264785415.json new file mode 100644 index 00000000000..7d02395ec7a --- /dev/null +++ b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42264785415.json @@ -0,0 +1,976 @@ +{ + "source": "GET /repos/paperclipai/paperclip/actions/runs/42264785415/attempts/1 (+ jobs and annotations), trimmed", + "run": { + "id": 42264785415, + "name": "PR", + "head_branch": "fix/rc16-bootstrap-proof-after-connect", + "head_sha": "f418091616c6f7b0af1d4c3115fa47c500015a8a", + "path": ".github/workflows/pr.yml", + "run_number": 60214, + "event": "pull_request", + "status": "completed", + "conclusion": "failure", + "workflow_id": 249194268, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415", + "created_at": "2026-11-06T17:47:06Z", + "run_attempt": 1, + "run_started_at": "2026-11-06T17:47:06Z", + "actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "triggering_actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + }, + "head_repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + } + }, + "jobs": [ + { + "id": 128053744882, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128053744882", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:47:07Z", + "started_at": "2026-11-06T17:47:30Z", + "completed_at": "2026-11-06T17:48:06Z", + "name": "ci / gate / Select trusted runner", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128053744882", + "labels": [ + "runs-on/fleet=paperclip-ci-routing-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0bd15c639391d3334--e87997a5-9", + "runner_group_name": "paperclip-ci-routing" + }, + { + "id": 128054259560, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259560", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:32Z", + "completed_at": "2026-11-06T17:58:38Z", + "name": "ci / Typecheck + Release Registry", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259560", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f9c9e372436e224a--ce576ff8-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259668, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259668", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:50:19Z", + "name": "ci / policy", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259668", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-02004b0b62771f088--836450ae-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259676, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259676", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:30Z", + "completed_at": "2026-11-06T17:53:43Z", + "name": "ci / Verify Paperclip Runner (static checks)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259676", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0499d8944ad722cc8--d269ace8-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259678, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259678", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:34Z", + "completed_at": "2026-11-06T17:49:18Z", + "name": "ci / Docker context integrity", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259678", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f415a1e7415eded5--1ead060a-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259685, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259685", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:57:02Z", + "name": "ci / Build", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259685", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04162f556ced67989--89ceb20a-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259696, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259696", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:32Z", + "completed_at": "2026-11-06T17:56:06Z", + "name": "ci / Canary Dry Run", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259696", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e73a58cd878a2eba--ed01493c-d", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259836, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259836", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T18:02:15Z", + "name": "ci / Verify Paperclip Runner (vitest package)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259836", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03b78c874a221b14d--3f9580f1-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259837, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259837", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:34Z", + "completed_at": "2026-11-06T17:50:33Z", + "name": "ci / Select Vitest files", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259837", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0965b01d7ca22acc7--46a2c286-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054259878, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054259878", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:34Z", + "completed_at": "2026-11-06T17:55:01Z", + "name": "ci / Verify Paperclip Runner (vitest native server)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054259878", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a3c1c296733234fa--24120234-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260016, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260016", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:55:03Z", + "name": "ci / e2e shard (2/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260016", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05170a3c06ca46460--d09cbbe4-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260029, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260029", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:56:53Z", + "name": "ci / e2e shard (3/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260029", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03be127710fc5e3f3--1232d471-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260068, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260068", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:34Z", + "completed_at": "2026-11-06T17:57:28Z", + "name": "ci / e2e shard (4/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260068", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e30b923f731a8617--7f3f286f-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260075, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260075", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:55:25Z", + "name": "ci / e2e shard (6/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260075", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0afa242a4729d2f5e--1e1e7e9a-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260099, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260099", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:33Z", + "completed_at": "2026-11-06T17:54:46Z", + "name": "ci / e2e shard (8/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260099", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-08fc2533358d5e023--bc9c002a-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260141, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260141", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:34Z", + "completed_at": "2026-11-06T17:53:23Z", + "name": "ci / e2e shard (7/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260141", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e1920f3a20679a6d--4eaf0fed-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260232, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260232", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:35Z", + "completed_at": "2026-11-06T17:54:31Z", + "name": "ci / e2e shard (5/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260232", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01730060988e5694a--f4f43bb3-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128054260285, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128054260285", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:48:07Z", + "started_at": "2026-11-06T17:48:36Z", + "completed_at": "2026-11-06T17:53:55Z", + "name": "ci / e2e shard (1/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128054260285", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0398f5a4a13d3bb86--06283b1d-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055537875, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537875", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:08Z", + "completed_at": "2026-11-06T17:54:45Z", + "name": "ci / Verify serialized server suites (6/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537875", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03863cc26751ee81d--ed7003ac-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055537897, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537897", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:09Z", + "completed_at": "2026-11-06T17:54:56Z", + "name": "ci / Verify serialized server suites (5/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537897", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07c73636f0cb7025c--f79ac0af-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055537952, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537952", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:50:57Z", + "completed_at": "2026-11-06T17:54:28Z", + "name": "ci / Verify serialized server suites (8/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537952", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03b2eebb3d82945ba--deae2c56-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055537956, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537956", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:11Z", + "completed_at": "2026-11-06T17:54:27Z", + "name": "ci / Verify serialized server suites (3/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537956", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0efadc3ad82b120d2--95e7dcf3-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055537962, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055537962", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:50:57Z", + "completed_at": "2026-11-06T17:57:23Z", + "name": "ci / Verify serialized server suites (2/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055537962", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07d521bfd6e73257a--19c15d8d-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538017, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538017", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:54:58Z", + "name": "ci / Verify serialized server suites (7/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538017", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01e662eefaa655648--55d2ece6-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538089, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538089", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:56:27Z", + "name": "ci / Verify serialized server suites (1/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538089", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0ad89fde02e893c90--06ed32bb-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538125, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538125", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:54:49Z", + "name": "ci / Verify serialized server suites (4/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538125", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-064cd806776d929f4--274b294f-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538149, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538149", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:09Z", + "completed_at": "2026-11-06T18:06:26Z", + "name": "ci / General tests (server (2/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538149", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0eea471a99f85b880--00c81037-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538165, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538165", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:08Z", + "completed_at": "2026-11-06T17:58:45Z", + "name": "ci / General tests (server (1/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538165", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04800a2d79c810238--b9ce8e93-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538174, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538174", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:08Z", + "completed_at": "2026-11-06T17:59:43Z", + "name": "ci / General tests (server (6/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538174", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0efaf057cc5a98d48--edea4c47-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538185, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538185", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:57:34Z", + "name": "ci / General tests (server (7/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538185", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0205811b68f4b3fd1--52920e1d-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538207, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538207", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:14Z", + "completed_at": "2026-11-06T18:00:06Z", + "name": "ci / General tests (server (5/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538207", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a37eb2d9fde459d4--36952ebd-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538219, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538219", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:19Z", + "completed_at": "2026-11-06T17:59:30Z", + "name": "ci / General tests (server (3/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538219", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0188e96e97af2f59c--b8e855e1-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538250, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538250", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:13Z", + "completed_at": "2026-11-06T18:00:22Z", + "name": "ci / General tests (server (9/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538250", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00c505418cc8ee70e--fb114f23-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538253, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538253", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:12Z", + "completed_at": "2026-11-06T17:56:10Z", + "name": "ci / General tests (workspaces-b)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538253", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05fc778dbd976d597--c58725c9-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538265, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538265", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:54:31Z", + "name": "ci / Verify serialized server suites (9/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538265", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06a3bf8d19333dd51--c4258f53-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538302, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538302", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:33Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:58:51Z", + "name": "ci / General tests (server (12/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538302", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07605db9087df8358--8137b272-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538306, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538306", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:13Z", + "completed_at": "2026-11-06T17:59:36Z", + "name": "ci / General tests (server (11/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538306", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d357b1cfb24c69f8--9cc138ac-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538334, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538334", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:14Z", + "completed_at": "2026-11-06T17:57:39Z", + "name": "ci / General tests (server (8/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538334", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06bee8abdadd855f6--4777aea8-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538337, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538337", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:17Z", + "completed_at": "2026-11-06T17:57:43Z", + "name": "ci / General tests (server (4/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538337", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00861ea950b0c2df8--e7934d4c-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538364, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538364", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:16Z", + "completed_at": "2026-11-06T17:56:44Z", + "name": "ci / General tests (chat (2/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538364", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04505acda283d309b--e4997141-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538368, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538368", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:23Z", + "completed_at": "2026-11-06T17:57:14Z", + "name": "ci / General tests (workspaces-a (1/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538368", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01559d90b1c03dafc--39658d89-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538374, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538374", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:20Z", + "completed_at": "2026-11-06T17:57:56Z", + "name": "ci / General tests (server (10/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538374", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05115335e959346eb--0b11d7ba-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538399, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538399", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:16Z", + "completed_at": "2026-11-06T17:57:35Z", + "name": "ci / General tests (chat (1/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538399", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-020c27d3a16ef9c2b--ea30bd71-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538415, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538415", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:18Z", + "completed_at": "2026-11-06T17:55:40Z", + "name": "ci / General tests (workspaces-a (2/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538415", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c674a4b6f26936cf--ec849767-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128055538546, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128055538546", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:50:34Z", + "started_at": "2026-11-06T17:51:19Z", + "completed_at": "2026-11-06T17:59:30Z", + "name": "ci / General tests (chat (3/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128055538546", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05c610ca30a34300b--725c544b-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128059102519, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128059102519", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T17:57:28Z", + "started_at": "2026-11-06T17:58:02Z", + "completed_at": "2026-11-06T17:58:07Z", + "name": "ci / e2e", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128059102519", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-02635cc9003444823--4f0acae5-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128063690619, + "run_id": 42264785415, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42264785415/job/128063690619", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:06:26Z", + "started_at": "2026-11-06T18:07:00Z", + "completed_at": "2026-11-06T18:07:08Z", + "name": "ci / verify", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128063690619", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-007fb864dc5bb537d--f46a91cb-e", + "runner_group_name": "paperclip-public-pr" + } + ], + "annotations": { + "128055538337": [ + { + "path": ".github", + "start_line": 285371, + "end_line": 285371, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + }, + { + "path": "server/src/__tests__/connection-management.integration.test.ts", + "start_line": 1806, + "end_line": 1806, + "annotation_level": "failure", + "title": "[@paperclipai/server] src/__tests__/connection-management.integration.test.ts > connection management with production default agents > reads only the authorized Anthropic account identity through actual agent authentication", + "message": "AssertionError: expected 3 to be 2 // Object.is equality\n\n- Expected\n+ Received\n\n- 2\n+ 3\n\n ❯ src/__tests__/connection-management.integration.test.ts:1806:21\n\n", + "raw_details": "" + }, + { + "path": ".github", + "start_line": 162423, + "end_line": 162423, + "annotation_level": "failure", + "title": "", + "message": "command (/home/runner/_work/paperclip/paperclip/) /home/runner/setup-pnpm/node_modules/.bin/bin/pnpm run test:run:general -- --group general-server-without-chat --shard-index 3 --shard-count 12 exited (1)", + "raw_details": "" + } + ], + "128063690619": [ + { + "path": ".github", + "start_line": 120, + "end_line": 120, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + } + ] + }, + "logs": {}, + "total_count": 47 +} diff --git a/.github/scripts/tests/fixtures/runner-loss-rerun/run-42271918832.json b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42271918832.json new file mode 100644 index 00000000000..2dca8cc8caa --- /dev/null +++ b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42271918832.json @@ -0,0 +1,1094 @@ +{ + "source": "GET /repos/paperclipai/paperclip/actions/runs/42271918832/attempts/1 (+ jobs and annotations), trimmed", + "run": { + "id": 42271918832, + "name": "PR", + "head_branch": "fix/chat-onboarding-duplicate-question", + "head_sha": "365cac18409b3ab154f3d1433f18127be06561b9", + "path": ".github/workflows/pr.yml", + "run_number": 60261, + "event": "pull_request", + "status": "completed", + "conclusion": "failure", + "workflow_id": 249194268, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832", + "created_at": "2026-11-06T18:34:23Z", + "run_attempt": 1, + "run_started_at": "2026-11-06T18:34:23Z", + "actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "triggering_actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + }, + "head_repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + } + }, + "jobs": [ + { + "id": 128078366543, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078366543", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:34:24Z", + "started_at": "2026-11-06T18:34:47Z", + "completed_at": "2026-11-06T18:34:59Z", + "name": "ci / gate / Select trusted runner", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078366543", + "labels": [ + "runs-on/fleet=paperclip-ci-routing-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0216cbcfcdfba5fac--12a5c383-4", + "runner_group_name": "paperclip-ci-routing" + }, + { + "id": 128078673798, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078673798", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:35Z", + "completed_at": "2026-11-06T18:48:51Z", + "name": "ci / Typecheck + Release Registry", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078673798", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04d441d96053a0412--39dde6c8-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078673891, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078673891", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:34Z", + "completed_at": "2026-11-06T18:46:54Z", + "name": "ci / Build", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078673891", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c9a3b63b118eab27--b5711e0a-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078673924, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078673924", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:35Z", + "completed_at": "2026-11-06T18:43:39Z", + "name": "ci / Verify Paperclip Runner (vitest native server)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078673924", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-086f97ef3dd06aec3--abed3f42-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078673958, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078673958", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:35Z", + "completed_at": "2026-11-06T18:37:54Z", + "name": "ci / policy", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078673958", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-02913c39945bb5411--a4f9673c-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674036, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674036", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:35Z", + "completed_at": "2026-11-06T18:42:21Z", + "name": "ci / Verify Paperclip Runner (static checks)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674036", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f9d0d99b024f1e51--6d006b4b-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674044, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674044", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:35Z", + "completed_at": "2026-11-06T18:44:23Z", + "name": "ci / Canary Dry Run", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674044", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-062353f08da97520f--775f4c86-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674048, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674048", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:38Z", + "completed_at": "2026-11-06T18:36:26Z", + "name": "ci / Docker context integrity", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674048", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-09a3e7aaeea73441d--3ea4022a-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674061, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674061", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:40Z", + "completed_at": "2026-11-06T18:36:01Z", + "name": "ci / Select Vitest files", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674061", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-08f1e1cc09aa2fda2--6fa7058f-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674151, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674151", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:38Z", + "completed_at": "2026-11-06T18:42:44Z", + "name": "ci / Verify Paperclip Runner (vitest package)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674151", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d1702723aae87975--400d356c-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674264, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674264", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:36Z", + "completed_at": "2026-11-06T18:43:33Z", + "name": "ci / e2e shard (1/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674264", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07223443dabe27a66--b1a55598-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674288, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674288", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:36Z", + "completed_at": "2026-11-06T18:44:49Z", + "name": "ci / e2e shard (5/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674288", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-078ea9d39e71de0d7--694e3704-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674311, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674311", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:38Z", + "completed_at": "2026-11-06T18:43:34Z", + "name": "ci / e2e shard (4/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674311", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b41e8a65878c1804--9ad6e0ae-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674409, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674409", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:39Z", + "completed_at": "2026-11-06T18:43:06Z", + "name": "ci / e2e shard (7/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674409", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e45823392babfd76--89f333ff-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674420, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674420", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:38Z", + "completed_at": "2026-11-06T18:52:38Z", + "name": "ci / e2e shard (2/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674420", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04146687585301d3a--a164cf39-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674488, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674488", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:39Z", + "completed_at": "2026-11-06T18:52:38Z", + "name": "ci / e2e shard (3/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674488", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e8655cb338267738--4d24cd7e-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674529, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674529", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:44Z", + "completed_at": "2026-11-06T18:44:42Z", + "name": "ci / e2e shard (8/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674529", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a8f8360c994cab55--71f7ad95-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078674535, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078674535", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:38Z", + "completed_at": "2026-11-06T18:52:38Z", + "name": "ci / e2e shard (6/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078674535", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05739a1954ef27c6d--4864b3c1-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128078676152, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128078676152", + "status": "completed", + "conclusion": "skipped", + "created_at": "2026-11-06T18:35:00Z", + "started_at": "2026-11-06T18:35:00Z", + "completed_at": "2026-11-06T18:35:00Z", + "name": "ci / Sandbox provider tests", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078676152", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": null, + "runner_group_name": null + }, + { + "id": 128079212940, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079212940", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:37Z", + "completed_at": "2026-11-06T18:43:01Z", + "name": "ci / Verify serialized server suites (1/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079212940", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-033af230cf26e68ae--33b7274e-6", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079212951, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079212951", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:39Z", + "completed_at": "2026-11-06T18:42:54Z", + "name": "ci / Verify serialized server suites (2/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079212951", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0286992fc69a0d47f--a1c011ac-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079212978, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079212978", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:38Z", + "completed_at": "2026-11-06T18:42:19Z", + "name": "ci / Verify serialized server suites (9/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079212978", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-02788f1d677262cb1--bbb7ef96-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079212991, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079212991", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:37Z", + "completed_at": "2026-11-06T18:52:37Z", + "name": "ci / Verify serialized server suites (5/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079212991", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05e10642a9beb3ff2--3bf2cd4a-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213013, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213013", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:39Z", + "completed_at": "2026-11-06T18:42:44Z", + "name": "ci / Verify serialized server suites (6/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213013", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-000d71c71a3319146--03677a4b-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213060, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213060", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:42Z", + "completed_at": "2026-11-06T18:42:42Z", + "name": "ci / Verify serialized server suites (4/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213060", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05b8f00f6c9d8fc0f--73c86c8b-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213109, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213109", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:42Z", + "completed_at": "2026-11-06T18:42:48Z", + "name": "ci / Verify serialized server suites (8/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213109", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a2c05ade16fdf7e2--5eb9acae-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213186, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213186", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:42:47Z", + "name": "ci / Verify serialized server suites (7/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213186", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03f46c96cbb4ba625--47c0bc8c-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213204, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213204", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:46Z", + "completed_at": "2026-11-06T18:42:37Z", + "name": "ci / Verify serialized server suites (3/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213204", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f352b980bed98843--f1cbc002-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213211, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213211", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:39Z", + "completed_at": "2026-11-06T18:42:51Z", + "name": "ci / General tests (server (1/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213211", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00617e9e4384506a0--e1cd9d76-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213231, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213231", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:47:58Z", + "name": "ci / General tests (server (6/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213231", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0254668e52e872f74--62c64174-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213239, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213239", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:43Z", + "completed_at": "2026-11-06T18:47:06Z", + "name": "ci / General tests (server (4/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213239", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e20e9f83713bf77d--25816635-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213241, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213241", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:50:02Z", + "name": "ci / General tests (server (5/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213241", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-08035dd685bbe8a5a--185541df-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213245, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213245", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:47:07Z", + "name": "ci / General tests (server (3/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213245", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-057ac650050d69cda--76d1e735-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213246, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213246", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:46Z", + "completed_at": "2026-11-06T18:48:27Z", + "name": "ci / General tests (server (10/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213246", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06754bff83958fbed--1ac43060-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213254, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213254", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:46:20Z", + "name": "ci / General tests (chat (1/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213254", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06936514f9ae54c81--efda4fbf-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213266, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213266", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:40Z", + "completed_at": "2026-11-06T18:52:54Z", + "name": "ci / General tests (server (2/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213266", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e2d00fd0aec3ee65--79769f5d-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213278, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213278", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:44Z", + "completed_at": "2026-11-06T18:51:45Z", + "name": "ci / General tests (server (9/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213278", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07b75e9ad6d3ef554--eca5f4f1-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213293, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213293", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:41Z", + "completed_at": "2026-11-06T18:46:44Z", + "name": "ci / General tests (server (8/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213293", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04b1fcd4248817d14--e51335bf-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213345, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213345", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:45Z", + "completed_at": "2026-11-06T18:51:45Z", + "name": "ci / General tests (server (12/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213345", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0881afbaf9aa0aaf8--090d6a82-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213368, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213368", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:44Z", + "completed_at": "2026-11-06T18:48:17Z", + "name": "ci / General tests (server (7/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213368", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-079f7866b26322557--33b46556-d", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213417, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213417", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:41Z", + "completed_at": "2026-11-06T18:44:03Z", + "name": "ci / General tests (workspaces-b)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213417", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03edc45d9f2c575e4--f5e9dfa1-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213419, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213419", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:49Z", + "completed_at": "2026-11-06T18:44:02Z", + "name": "ci / General tests (chat (2/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213419", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b2324499b03a08b9--42463b64-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213482, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213482", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:42Z", + "completed_at": "2026-11-06T18:45:54Z", + "name": "ci / General tests (workspaces-a (2/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213482", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01c609e12f7311e8c--9bac745e-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213518, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213518", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:50Z", + "completed_at": "2026-11-06T18:47:37Z", + "name": "ci / General tests (chat (3/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213518", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-031a362e7d12b7a58--7db3b0f0-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213529, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213529", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:50Z", + "completed_at": "2026-11-06T18:48:56Z", + "name": "ci / General tests (server (11/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213529", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01aa0332fdd4205b6--b451dd52-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079213530, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128079213530", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:36:01Z", + "started_at": "2026-11-06T18:36:44Z", + "completed_at": "2026-11-06T18:46:39Z", + "name": "ci / General tests (workspaces-a (1/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079213530", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0574053a01923d9cc--30096aff-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128087703467, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128087703467", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:52:39Z", + "started_at": "2026-11-06T18:52:58Z", + "completed_at": "2026-11-06T18:53:03Z", + "name": "ci / e2e", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128087703467", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d0fd6b0946cbee59--3ee80826-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128087836089, + "run_id": 42271918832, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42271918832/job/128087836089", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:52:54Z", + "started_at": "2026-11-06T18:52:58Z", + "completed_at": "2026-11-06T18:53:04Z", + "name": "ci / verify", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128087836089", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03d17b9c4207c40c0--7dbcd730-8", + "runner_group_name": "paperclip-public-pr" + } + ], + "annotations": { + "128078674151": [ + { + "path": ".github", + "start_line": 198, + "end_line": 198, + "annotation_level": "failure", + "title": "", + "message": "The operation was canceled.", + "raw_details": "" + } + ], + "128078674420": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128078674488": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128078674535": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128079212991": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128079213278": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128079213345": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128079213530": [ + { + "path": ".github", + "start_line": 474561, + "end_line": 474561, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + }, + { + "path": "cli/src/__tests__/company-import-transfer.test.ts", + "start_line": 123, + "end_line": 123, + "annotation_level": "failure", + "title": "[paperclipai] src/__tests__/company-import-transfer.test.ts > resolveChunkedImportZip > takes the chunked path for a small zip whose entries inflate past the threshold", + "message": "Error: Test timed out in 5000ms.\nIf this is a long-running test, pass a timeout value as the last argument or configure it globally with \"testTimeout\".\n ❯ src/__tests__/company-import-transfer.test.ts:123:3\n\n", + "raw_details": "" + }, + { + "path": "cli/src/__tests__/company-import-export-e2e.test.ts", + "start_line": 280, + "end_line": 280, + "annotation_level": "failure", + "title": "[paperclipai] src/__tests__/company-import-export-e2e.test.ts > paperclipai company import/export e2e", + "message": "Error: Timed out waiting for the child server recorded in /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/paperclip-home/instances/company-cli-e2e/runtime-info.json.\nstdout:\nUpdate available: 2026.1023.0 — run `paperclipai update`\n┌ paperclipai run \n│\n│ Home: /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/paperclip-home\n│\n│ Instance: company-cli-e2e\n│\n│ Config: /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/config/config.json\n│\n◇ Running doctor checks...\nUpdate available: 2026.1023.0 — run `paperclipai update`\n\n██████╗ █████╗ ██████╗ ███████╗██████╗ ██████╗██╗ ██╗██████╗ \n██╔══██╗██╔══██╗██╔══██╗██╔════╝██╔══██╗██╔════╝██║ ██║██╔══██╗\n██████╔╝███████║██████╔╝█████╗ ██████╔╝██║ ██║ ██║██████╔╝\n██╔═══╝ ██╔══██║██╔═══╝ ██╔══╝ ██╔══██╗██║ ██║ ██║██╔═══╝ \n██║ ██║ ██║██║ ███████╗██║ ██║╚██████╗███████╗██║██║ \n╚═╝ ╚═╝ ╚═╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝╚═╝ \n ───────────────────────────────────────────────────────\n The app people use to manage AI agents for work\n\n┌ paperclip doctor \n│\n│ ✓ Config file: Valid config at /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/config/config.json\n│\n│ ✓ Deployment/auth mode: local_trusted mode is configured for loopback-only access\n│\n│ ✗ Agent JWT secret: PAPERCLIP_AGENT_JWT_SECRET missing from environment and /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/config/.env\n│\n│ Run with --repair to create /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/config/.env containing PAPERCLIP_AGENT_JWT_SECRET\n│\n◆ Repaired: Agent JWT secret\n│\n│ ✓ Agent JWT secret: PAPERCLIP_AGENT_JWT_SECRET is set in environment\n│\n│ ! Secrets adapter: Secrets key file does not exist yet: /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/secrets/master.key; strict secret mode is disabled for postgres deployment\n│\n│ Run with --repair to create a local encrypted secrets key file. Consider enabling secrets.strictMode\n│\n◆ Repaired: Secrets adapter\n│\n│ ! Secrets adapter: Local encrypted provider configured with key file /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/secrets/master.key; strict secret mode is disabled for postgres deployment\n│\n│ Consider enabling secrets.strictMode\n│\n│ ✓ Storage: Local disk storage is writable: /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/storage\n│\n│ ✓ Database: PostgreSQL connection successful\n│\n│ ✓ LLM provider: No LLM provider configured (optional)\n│\n│ ✓ Log directory: Log directory is writable: /tmp/pv-KMcoQP/t/paperclip-company-cli-e2e-8VX8vL/logs\n│\n│ ! Server port: Port 37925 is already in use\n│\n│ Check what's using port 37925 with: lsof -i :37925\n│\n│ ✓ Node.js runtime: Node.js 24.22.2\n│\n│ ✓ Managed install: Not present (optional for npx, global npm, and source-checkout usage)\n│\n│ ✓ Background service: No usable systemd user manager was detected (common in containers and WSL1). Use paperclipai run instead.\n│\n◇ Summary ───────────────╮\n│ │\n│ 10 passed, 2 warnings │\n│ │\n├─────────────────────────╯\n│\n└ All critical checks passed with some warnings.\n\n│\n◇ Start", + "raw_details": "" + }, + { + "path": ".github", + "start_line": 126918, + "end_line": 126918, + "annotation_level": "failure", + "title": "", + "message": "command (/home/runner/_work/paperclip/paperclip/) /home/runner/setup-pnpm/node_modules/.bin/bin/pnpm run test:run:general -- --group general-workspaces-a --shard-index 0 --shard-count 2 exited (1)", + "raw_details": "" + } + ], + "128087703467": [ + { + "path": ".github", + "start_line": 89, + "end_line": 89, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + } + ], + "128087836089": [ + { + "path": ".github", + "start_line": 122, + "end_line": 122, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + } + ] + }, + "logs": { + "128078674151": "2026-11-06T18:42:31.0413375Z ##[error]The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.\n2026-11-06T18:42:43.5529901Z ##[error]The operation was canceled.\n2026-11-06T18:42:43.5656287Z Cleaning up orphan processes\n" + }, + "total_count": 48 +} diff --git a/.github/scripts/tests/fixtures/runner-loss-rerun/run-42272083862.json b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42272083862.json new file mode 100644 index 00000000000..1f05000a72b --- /dev/null +++ b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42272083862.json @@ -0,0 +1,1015 @@ +{ + "source": "GET /repos/paperclipai/paperclip/actions/runs/42272083862/attempts/1 (+ jobs and annotations), trimmed", + "run": { + "id": 42272083862, + "name": "PR", + "head_branch": "chore/dependabot-sandbox-providers", + "head_sha": "2dc6ae14b74a93b0dbb4e381b32216527721a5ea", + "path": ".github/workflows/pr.yml", + "run_number": 60263, + "event": "pull_request", + "status": "completed", + "conclusion": "failure", + "workflow_id": 249194268, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862", + "created_at": "2026-11-06T18:35:27Z", + "run_attempt": 1, + "run_started_at": "2026-11-06T18:35:27Z", + "actor": { + "login": "nickyleach", + "id": 331803, + "type": "User" + }, + "triggering_actor": { + "login": "nickyleach", + "id": 331803, + "type": "User" + }, + "repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + }, + "head_repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + } + }, + "jobs": [ + { + "id": 128078919907, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128078919907", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:35:28Z", + "started_at": "2026-11-06T18:35:53Z", + "completed_at": "2026-11-06T18:36:06Z", + "name": "ci / gate / Select trusted runner", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128078919907", + "labels": [ + "runs-on/fleet=paperclip-ci-routing-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00350796615b86e44--ef107434-0", + "runner_group_name": "paperclip-ci-routing" + }, + { + "id": 128079261446, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261446", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:51Z", + "completed_at": "2026-11-06T18:39:09Z", + "name": "ci / policy", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261446", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-051a9358cb64ff93b--f02c313b-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261486, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261486", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:51Z", + "completed_at": "2026-11-06T18:37:42Z", + "name": "ci / Docker context integrity", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261486", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0235f2a269736f19c--c3811ca2-d", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261500, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261500", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:51Z", + "completed_at": "2026-11-06T18:49:31Z", + "name": "ci / Typecheck + Release Registry", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261500", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01e6b61f0f35dd753--35112355-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261591, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261591", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:52Z", + "completed_at": "2026-11-06T18:55:11Z", + "name": "ci / Verify Paperclip Runner (vitest package)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261591", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03e71975960807af4--7cb65c1a-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261596, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261596", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:51Z", + "completed_at": "2026-11-06T18:39:43Z", + "name": "ci / Sandbox provider tests", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261596", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-01962bcfe2145b53c--cd1427aa-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261614, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261614", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:47:35Z", + "name": "ci / Build", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261614", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b280a6b682cc7dd1--71ea38b1-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261637, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261637", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:50Z", + "completed_at": "2026-11-06T18:45:42Z", + "name": "ci / Canary Dry Run", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261637", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0af77e12e676a1daa--50030625-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261711, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261711", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:52Z", + "completed_at": "2026-11-06T18:43:38Z", + "name": "ci / Verify Paperclip Runner (static checks)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261711", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-044877a98c227dfec--cb494d00-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261781, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261781", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:51Z", + "completed_at": "2026-11-06T18:44:51Z", + "name": "ci / Verify Paperclip Runner (vitest native server)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261781", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03e9b540449d1c3e0--b6f2d30b-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079261918, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079261918", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:43:04Z", + "name": "ci / Verify Paperclip Runner (rust)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079261918", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d7f34d5a56b592ab--d03c4277-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262079, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262079", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:45:38Z", + "name": "ci / e2e shard (5/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262079", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07a96e26cd27fed42--b369e2ee-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262095, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262095", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:52Z", + "completed_at": "2026-11-06T18:45:57Z", + "name": "ci / e2e shard (2/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262095", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04b2ccd871d959f73--d350cad1-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262111, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262111", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:48:30Z", + "name": "ci / e2e shard (3/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262111", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e0c76b0c763b70c7--731cec8c-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262112, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262112", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:45:08Z", + "name": "ci / e2e shard (4/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262112", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00f7b8874621b303a--dc82c991-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262185, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262185", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:46:12Z", + "name": "ci / e2e shard (8/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262185", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-063b6ddb970f9eed2--919ff681-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262246, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262246", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:06Z", + "started_at": "2026-11-06T18:36:54Z", + "completed_at": "2026-11-06T18:44:25Z", + "name": "ci / e2e shard (7/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262246", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-056c50bc28efed4b7--b3083a10-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262312, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262312", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:01Z", + "completed_at": "2026-11-06T18:46:41Z", + "name": "ci / e2e shard (6/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262312", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-08908e6c774a03492--d1c3f1ce-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079262325, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079262325", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:01Z", + "completed_at": "2026-11-06T18:42:20Z", + "name": "ci / e2e shard (1/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079262325", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03a9d44ad29a39625--04e8d63d-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263114, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263114", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:36:53Z", + "completed_at": "2026-11-06T18:46:17Z", + "name": "ci / Verify serialized server suites (2/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263114", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-045427c7a1aa6012b--cd64c5d3-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263166, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263166", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:36:54Z", + "completed_at": "2026-11-06T18:42:54Z", + "name": "ci / Verify serialized server suites (3/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263166", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d815d2a27d047a52--f5f7b04d-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263177, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263177", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:36:55Z", + "completed_at": "2026-11-06T18:43:39Z", + "name": "ci / Verify serialized server suites (6/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263177", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-032d5d397cf435d34--16387a22-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263209, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263209", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:41:59Z", + "name": "ci / Verify serialized server suites (8/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263209", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b4fd49a10f86255b--4676aed5-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263228, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263228", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:36:56Z", + "completed_at": "2026-11-06T18:43:45Z", + "name": "ci / Verify serialized server suites (5/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263228", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0ed02f6ef66711eed--36851958-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263250, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263250", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:41:24Z", + "name": "ci / Verify serialized server suites (7/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263250", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0eda82f6b55a1f1a8--d537c25b-d", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263310, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263310", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:41:14Z", + "name": "ci / Verify serialized server suites (4/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263310", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-061d0ae769d82d21c--82abfe58-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263323, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263323", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:43:04Z", + "name": "ci / Verify serialized server suites (1/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263323", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-065afe15faa0bda3a--d20acb9e-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263347, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263347", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:42:53Z", + "name": "ci / Verify serialized server suites (9/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263347", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-04123a1bb6f3a0f51--e7fae27e-f", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263676, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263676", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:45:55Z", + "name": "ci / General tests (server (12/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263676", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b0a69658de2dae43--eea873c0-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263700, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263700", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:46:10Z", + "name": "ci / General tests (server (11/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263700", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0ee8d39875ec6cd83--187ebb5d-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263702, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263702", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:44:57Z", + "name": "ci / General tests (server (1/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263702", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c17757c9a591b84a--1210ec14-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263724, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263724", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:52:02Z", + "name": "ci / General tests (server (3/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263724", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a1def53310c8aade--5485d06a-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263734, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263734", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:48:04Z", + "name": "ci / General tests (server (4/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263734", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0322362dd6742e735--ee34f158-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263762, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263762", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:46:35Z", + "name": "ci / General tests (server (5/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263762", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e393de8c6813762b--ddb13fd7-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263774, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263774", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:43:45Z", + "name": "ci / General tests (server (8/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263774", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d1fbdb55cd51027a--7459e663-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263790, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263790", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:48:18Z", + "name": "ci / General tests (server (7/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263790", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07d64a985968c8bae--047b7852-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263795, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263795", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:45:11Z", + "name": "ci / General tests (server (6/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263795", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0bc5ba9aeadd05725--e6ced706-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263838, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263838", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:44:27Z", + "name": "ci / General tests (server (9/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263838", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b1748f677f3429e8--99f27e0a-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263897, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263897", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:44:36Z", + "name": "ci / General tests (server (10/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263897", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-069a786e16cf0dc0a--d6f268d4-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263953, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263953", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:42:42Z", + "name": "ci / General tests (workspaces-b)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263953", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-002d44e03407252fb--3b1ae299-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263969, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263969", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:02Z", + "completed_at": "2026-11-06T18:45:26Z", + "name": "ci / General tests (chat (3/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263969", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-00a36d40a9d0cc3c1--38896919-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079263971, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079263971", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:40:46Z", + "name": "ci / General tests (workspaces-c)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079263971", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-053dbd6ce10b20723--99d07100-6", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264017, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264017", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:42:57Z", + "name": "ci / General tests (workspaces-a (2/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264017", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a6b4d59b9715c424--013db442-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264058, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264058", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:44:34Z", + "name": "ci / General tests (workspaces-a (1/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264058", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06272485726bd873f--83251313-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264097, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264097", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:45:08Z", + "name": "ci / General tests (chat (1/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264097", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-07e661fd137a572ce--3912c81b-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264142, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264142", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:43:50Z", + "name": "ci / General tests (chat (2/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264142", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0227d979818c65582--82d42739-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264184, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264184", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:37:03Z", + "completed_at": "2026-11-06T18:49:23Z", + "name": "ci / General tests (server (2/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264184", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-091dee008a8142f38--1be295f7-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128079264963, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128079264963", + "status": "completed", + "conclusion": "skipped", + "created_at": "2026-11-06T18:36:07Z", + "started_at": "2026-11-06T18:36:07Z", + "completed_at": "2026-11-06T18:36:06Z", + "name": "ci / Select Vitest files", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128079264963", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": null, + "runner_group_name": null + }, + { + "id": 128085600636, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128085600636", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T18:48:30Z", + "started_at": "2026-11-06T18:50:09Z", + "completed_at": "2026-11-06T18:50:15Z", + "name": "ci / e2e", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128085600636", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-09109657ddc07483f--23083f85-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128088995071, + "run_id": 42272083862, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42272083862/job/128088995071", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T18:55:11Z", + "started_at": "2026-11-06T18:56:11Z", + "completed_at": "2026-11-06T18:56:16Z", + "name": "ci / verify", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128088995071", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03b2d7218660a8abd--39f11340-5", + "runner_group_name": "paperclip-public-pr" + } + ], + "annotations": { + "128079263724": [ + { + "path": ".github", + "start_line": 1, + "end_line": 1, + "annotation_level": "failure", + "title": "", + "message": "The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", + "raw_details": "" + } + ], + "128088995071": [ + { + "path": ".github", + "start_line": 122, + "end_line": 122, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + } + ] + }, + "logs": {}, + "total_count": 50 +} diff --git a/.github/scripts/tests/fixtures/runner-loss-rerun/run-42277969418.json b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42277969418.json new file mode 100644 index 00000000000..77461a61e12 --- /dev/null +++ b/.github/scripts/tests/fixtures/runner-loss-rerun/run-42277969418.json @@ -0,0 +1,979 @@ +{ + "source": "GET /repos/paperclipai/paperclip/actions/runs/42277969418/attempts/1 (+ jobs and annotations), trimmed", + "run": { + "id": 42277969418, + "name": "PR", + "head_branch": "fix/status-card-compile-inline-guidance", + "head_sha": "85a1ebd70ebb687bac36cd7d3aa035f08b1b76fe", + "path": ".github/workflows/pr.yml", + "run_number": 60340, + "event": "pull_request", + "status": "completed", + "conclusion": "failure", + "workflow_id": 249194268, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418", + "created_at": "2026-11-06T19:15:10Z", + "run_attempt": 1, + "run_started_at": "2026-11-06T19:15:10Z", + "actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "triggering_actor": { + "login": "cryppadotta", + "id": 34892728, + "type": "User" + }, + "repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + }, + "head_repository": { + "id": 1170821064, + "full_name": "paperclipai/paperclip" + } + }, + "jobs": [ + { + "id": 128099176127, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099176127", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:11Z", + "started_at": "2026-11-06T19:15:35Z", + "completed_at": "2026-11-06T19:15:51Z", + "name": "ci / gate / Select trusted runner", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099176127", + "labels": [ + "runs-on/fleet=paperclip-ci-routing-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05f6b9b2930a13c18--04e93093-7", + "runner_group_name": "paperclip-ci-routing" + }, + { + "id": 128099518899, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518899", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:18:48Z", + "name": "ci / Select Vitest files", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518899", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-022ce6a3fe4cb976a--9b74ec42-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099518966, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518966", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:13Z", + "completed_at": "2026-11-06T19:17:52Z", + "name": "ci / policy", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518966", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06dd55e2393795fc3--8bdf1065-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099518969, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518969", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:30:17Z", + "name": "ci / Verify Paperclip Runner (vitest package)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518969", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-09eb0ccea8ce6e3f1--bf3c948a-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099518970, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099518970", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:26:13Z", + "name": "ci / Typecheck + Release Registry", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099518970", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06107c2f4ad4e0afa--e8a52bad-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519017, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519017", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:21:53Z", + "name": "ci / Verify Paperclip Runner (static checks)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519017", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0ce2155a81766d11b--1c931e39-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519063, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519063", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:16Z", + "completed_at": "2026-11-06T19:17:03Z", + "name": "ci / Docker context integrity", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519063", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0e251a79a0c87658b--54fd3399-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519192, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519192", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:24:53Z", + "name": "ci / Build", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519192", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-005e12d124d262094--566fec4c-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519255, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519255", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:23:21Z", + "name": "ci / e2e shard (2/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519255", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c236e72756ee5767--da386f7f-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519269, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519269", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:15Z", + "completed_at": "2026-11-06T19:26:36Z", + "name": "ci / e2e shard (6/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519269", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0460327d9a9ad85b9--4e8bc75b-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519294, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519294", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:22Z", + "completed_at": "2026-11-06T19:25:00Z", + "name": "ci / e2e shard (3/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519294", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0ff835844ee842210--66852b42-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519310, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519310", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:14Z", + "completed_at": "2026-11-06T19:22:48Z", + "name": "ci / e2e shard (4/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519310", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b5b047d9eb22c701--5e90d2e6-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519324, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519324", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:18Z", + "completed_at": "2026-11-06T19:22:50Z", + "name": "ci / Verify Paperclip Runner (vitest native server)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519324", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f33e5da352722dec--88ad2175-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519328, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519328", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:15Z", + "completed_at": "2026-11-06T19:23:26Z", + "name": "ci / e2e shard (5/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519328", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b4a144abcf5b5ad0--13d99f06-4", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519373, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519373", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:19Z", + "completed_at": "2026-11-06T19:23:19Z", + "name": "ci / Canary Dry Run", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519373", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-026bbfb8e1f2b02f6--fcd31fd2-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519399, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519399", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:17Z", + "completed_at": "2026-11-06T19:22:50Z", + "name": "ci / e2e shard (8/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519399", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06fecb3fefefd2b1e--48a7f824-3", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519420, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519420", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:19Z", + "completed_at": "2026-11-06T19:22:36Z", + "name": "ci / e2e shard (1/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519420", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0b1eec8b49f261f40--0ee7ea96-8", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099519640, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099519640", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:16:19Z", + "completed_at": "2026-11-06T19:22:41Z", + "name": "ci / e2e shard (7/8)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099519640", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c06a9265636bb3c1--29213d2a-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128099521660, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128099521660", + "status": "completed", + "conclusion": "skipped", + "created_at": "2026-11-06T19:15:51Z", + "started_at": "2026-11-06T19:15:51Z", + "completed_at": "2026-11-06T19:15:51Z", + "name": "ci / Sandbox provider tests", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128099521660", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": null, + "runner_group_name": null + }, + { + "id": 128101015827, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015827", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:36Z", + "completed_at": "2026-11-06T19:23:28Z", + "name": "ci / Verify serialized server suites (3/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015827", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f29d5a87a13a3137--0ae30aa5-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015873, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015873", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:37Z", + "completed_at": "2026-11-06T19:25:47Z", + "name": "ci / Verify serialized server suites (1/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015873", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a92a42f0bc1f9c02--30c81b0a-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015886, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015886", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:57Z", + "completed_at": "2026-11-06T19:24:10Z", + "name": "ci / Verify serialized server suites (4/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015886", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-050c1bc7159c094e4--1d0ecbb0-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015895, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015895", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:24:10Z", + "name": "ci / Verify serialized server suites (6/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015895", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0473b976117b1a23d--148e3608-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015916, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015916", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:43Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / Verify serialized server suites (2/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015916", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-06aa99d6dfd3eefa2--6d5659d3-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015954, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015954", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:41Z", + "completed_at": "2026-11-06T19:24:11Z", + "name": "ci / Verify serialized server suites (8/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015954", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-02e59035275e65dc1--f14d4574-a", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101015978, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101015978", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:43Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / Verify serialized server suites (5/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101015978", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0fc8f7dbd4ebf8e25--306b0039-6", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016102, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016102", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:43Z", + "completed_at": "2026-11-06T19:24:31Z", + "name": "ci / Verify serialized server suites (7/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016102", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f30ba7b9604359f6--7247346a-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016153, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016153", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:41Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / General tests (server (1/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016153", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a9149d343f722f73--6c14189b-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016167, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016167", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:36Z", + "completed_at": "2026-11-06T19:27:21Z", + "name": "ci / General tests (server (5/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016167", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0c26f035abc2181de--db86c3ca-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016193, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016193", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:37Z", + "completed_at": "2026-11-06T19:27:48Z", + "name": "ci / General tests (chat (1/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016193", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-09edcc5cc037cb21b--a7821027-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016200, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016200", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:37Z", + "completed_at": "2026-11-06T19:24:42Z", + "name": "ci / General tests (server (8/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016200", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0d85343085d2a7e66--3919a1b5-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016203, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016203", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:41Z", + "completed_at": "2026-11-06T19:24:01Z", + "name": "ci / Verify serialized server suites (9/9)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016203", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f2a0ad6f8136ed03--3f5b22b1-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016204, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016204", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:38Z", + "completed_at": "2026-11-06T19:25:44Z", + "name": "ci / General tests (workspaces-b)", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016204", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-022720c628aea9909--3489c3bc-e", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016209, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016209", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:37Z", + "completed_at": "2026-11-06T19:27:03Z", + "name": "ci / General tests (server (3/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016209", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05cd168e2c805dfa1--2db2f96e-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016247, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016247", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:37Z", + "completed_at": "2026-11-06T19:24:39Z", + "name": "ci / General tests (workspaces-a (2/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016247", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a76b068c81f7024a--8a17bf0c-7", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016250, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016250", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:26:41Z", + "name": "ci / General tests (server (12/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016250", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05867958d44053ee3--8a8e3069-9", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016265, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016265", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:26:58Z", + "name": "ci / General tests (server (4/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016265", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0bf649f272db17bac--41ee1099-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016277, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016277", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:34:40Z", + "name": "ci / General tests (server (2/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016277", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-057aa4559787e702b--99da1fc5-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016291, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016291", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:27:31Z", + "name": "ci / General tests (server (6/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016291", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0204b721d120e8305--4a8cbdcf-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016304, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016304", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:42Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / General tests (workspaces-a (1/2))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016304", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-083ececdc0bee80c6--049cc912-b", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016340, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016340", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:41Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / General tests (server (7/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016340", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0a46ba5536afd6715--10ddddf7-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016380, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016380", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:27:21Z", + "name": "ci / General tests (server (11/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016380", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0f1df9c61064c6c00--bfe5ea08-c", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016402, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016402", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:43Z", + "completed_at": "2026-11-06T19:24:42Z", + "name": "ci / General tests (server (9/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016402", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0cd6219458ec3772c--7a914eac-5", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016432, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016432", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:39Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / General tests (chat (3/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016432", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0fdc6b32e8998c1ba--0724a4a5-2", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016453, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016453", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:44Z", + "completed_at": "2026-11-06T19:24:43Z", + "name": "ci / General tests (server (10/12))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016453", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05195ce82810fc9ab--39894cef-6", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128101016461, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128101016461", + "status": "completed", + "conclusion": "cancelled", + "created_at": "2026-11-06T19:18:48Z", + "started_at": "2026-11-06T19:19:43Z", + "completed_at": "2026-11-06T19:24:42Z", + "name": "ci / General tests (chat (2/3))", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128101016461", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-0722bda62fe122e78--24305ada-1", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128104989524, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128104989524", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-06T19:26:36Z", + "started_at": "2026-11-06T19:27:42Z", + "completed_at": "2026-11-06T19:27:47Z", + "name": "ci / e2e", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128104989524", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-03d74c0aaf2a6f9a8--5077b150-0", + "runner_group_name": "paperclip-public-pr" + }, + { + "id": 128109082787, + "run_id": 42277969418, + "workflow_name": "PR", + "run_attempt": 1, + "html_url": "https://github.com/paperclipai/paperclip/actions/runs/42277969418/job/128109082787", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-06T19:34:41Z", + "started_at": "2026-11-06T19:35:37Z", + "completed_at": "2026-11-06T19:35:43Z", + "name": "ci / verify", + "check_run_url": "https://api.github.com/repos/paperclipai/paperclip/check-runs/128109082787", + "labels": [ + "runs-on/fleet=paperclip-public-pr-x64/env=public-ci" + ], + "runner_name": "runs-on--i-05ba3f428ff571fab--c14c92a3-1", + "runner_group_name": "paperclip-public-pr" + } + ], + "annotations": { + "128101016102": [ + { + "path": ".github", + "start_line": 2, + "end_line": 2, + "annotation_level": "failure", + "title": "", + "message": "The operation was canceled.", + "raw_details": "" + } + ], + "128109082787": [ + { + "path": ".github", + "start_line": 124, + "end_line": 124, + "annotation_level": "failure", + "title": "", + "message": "Process completed with exit code 1.", + "raw_details": "" + } + ] + }, + "logs": { + "128101016102": "2026-11-06T19:24:29.1450769Z ##[error]The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.\n2026-11-06T19:24:29.1898916Z ##[error]The operation was canceled.\n2026-11-06T19:24:29.1977091Z Cleaning up orphan processes\n" + }, + "total_count": 48 +} diff --git a/.github/scripts/tests/runner-loss-rerun.test.mjs b/.github/scripts/tests/runner-loss-rerun.test.mjs new file mode 100644 index 00000000000..bdc89f1d986 --- /dev/null +++ b/.github/scripts/tests/runner-loss-rerun.test.mjs @@ -0,0 +1,317 @@ +import assert from "node:assert/strict"; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import test from "node:test"; +import { + classifyJob, createGithubClient, decide, logShowsRunnerLoss, main, renderSummary, +} from "../runner-loss-rerun.mjs"; + +// Trimmed attempt-1 snapshots of real PR runs: jobs, check-run annotations for +// each failed job, and the error lines of job logs whose only annotation is +// "The operation was canceled.". +const fixture = (runId) => JSON.parse(readFileSync( + new URL(`./fixtures/runner-loss-rerun/run-${runId}.json`, import.meta.url), "utf8", +)); +const MIXED = 42271918832; // six lost runners, one shutdown in the log, one real test timeout +const REAL = 42264785415; // a real assertion failure +const ALL_LOST = 42272083862; // one lost runner +const LOG_ONLY = 42277969418; // shutdown signal visible only in the job log +const workflow = readFileSync(new URL("../../workflows/ci-runner-loss-rerun.yml", import.meta.url), "utf8"); + +const json = (body, headers = {}) => new Response(JSON.stringify(body), { + status: 200, headers: { "content-type": "application/json", ...headers }, +}); + +/** + * Serves a fixture as the GitHub REST API. By default the run is the latest + * CI for an open PR's current head. + */ +function fakeGithub(data, { + jobsPageSize = 100, pulls, prRuns, mutateRun = (run) => run, +} = {}) { + const calls = []; + const run = mutateRun(structuredClone(data.run)); + const openPr = { + number: 1, state: "open", + base: { repo: { id: data.run.repository.id } }, + head: { sha: data.run.head_sha, repo: { id: data.run.head_repository.id } }, + }; + const fetcher = async (href, init) => { + const url = new URL(href); + calls.push({ method: init.method, path: url.pathname, query: url.search, auth: init.headers.Authorization }); + const base = `/repos/paperclipai/paperclip`; + const route = url.pathname.slice(base.length); + if (init.method === "POST" && route === `/actions/runs/${run.id}/rerun-failed-jobs`) { + return new Response(null, { status: 201 }); + } + if (route === `/actions/runs/${run.id}`) return json(run); + if (route === `/actions/runs/${run.id}/attempts/1/jobs`) { + const page = Number(url.searchParams.get("page") ?? 1); + const jobs = data.jobs.slice((page - 1) * jobsPageSize, page * jobsPageSize); + const last = page * jobsPageSize >= data.jobs.length; + const next = new URL(url); + next.searchParams.set("page", String(page + 1)); + return json({ total_count: data.total_count, jobs }, last ? {} : { link: `<${next.href}>; rel="next"` }); + } + let match = route.match(/^\/check-runs\/(\d+)\/annotations$/); + if (match) return json(data.annotations[match[1]] ?? []); + match = route.match(/^\/actions\/jobs\/(\d+)\/logs$/); + if (match) return new Response(data.logs[match[1]] ?? "", { status: 200 }); + if (route === `/commits/${run.head_sha}/pulls`) return json(pulls ?? [openPr]); + if (route === "/actions/workflows/pr.yml/runs") { + const runs = prRuns ?? [{ id: run.id, conclusion: "failure" }]; + return json({ total_count: runs.length, workflow_runs: runs }); + } + return new Response("not found", { status: 404 }); + }; + return { calls, fetcher, run, client: createGithubClient({ token: "test-token", fetcher }) }; +} + +const posted = (calls) => calls.filter((call) => call.method === "POST"); + +async function runMain(data, options = {}, eventRun = {}) { + const github = fakeGithub(data, options); + const directory = mkdtempSync(path.join(tmpdir(), "runner-loss-rerun-")); + try { + const eventPath = path.join(directory, "event.json"); + const summaryPath = path.join(directory, "summary.md"); + writeFileSync(eventPath, JSON.stringify({ workflow_run: { id: data.run.id, run_attempt: 1, ...eventRun } })); + writeFileSync(summaryPath, ""); + const decision = await main({ + env: { GITHUB_TOKEN: "test-token", GITHUB_EVENT_PATH: eventPath, GITHUB_STEP_SUMMARY: summaryPath }, + argv: [], fetcher: github.fetcher, log: () => {}, + }); + return { decision, calls: github.calls, summary: readFileSync(summaryPath, "utf8") }; + } finally { + rmSync(directory, { recursive: true, force: true }); + } +} + +test("all failed jobs lost their runner: re-runs failed jobs once", async () => { + const { decision, calls, summary } = await runMain(fixture(ALL_LOST)); + assert.equal(decision.rerun, true); + assert.deepEqual(decision.jobs.map((job) => [job.name, job.lost]), [["ci / General tests (server (3/12))", true]]); + assert.deepEqual(posted(calls).map((call) => call.path), + [`/repos/paperclipai/paperclip/actions/runs/${ALL_LOST}/rerun-failed-jobs`]); + assert.ok(calls.every((call) => call.auth === "Bearer test-token")); + // `ci / verify` failed too, but only because its dependency failed. + assert.equal(calls.some((call) => call.path.endsWith("/check-runs/128088995071/annotations")), false); + assert.match(summary, /\*\*Re-ran failed jobs\*\*/); + assert.match(summary, /\| ci \/ General tests \(server \(3\/12\)\) \| yes \| The self-hosted runner lost communication/); +}); + +test("a shutdown signal found only in the job log counts as runner loss", async () => { + const data = fixture(LOG_ONLY); + assert.deepEqual(data.annotations["128101016102"].map((annotation) => annotation.message), ["The operation was canceled."]); + const { decision, calls } = await runMain(data); + assert.equal(decision.rerun, true); + assert.match(decision.jobs[0].evidence, /job log/); + assert.ok(calls.some((call) => call.path.endsWith("/actions/jobs/128101016102/logs"))); + assert.equal(posted(calls).length, 1); +}); + +test("mixed runner loss and a real test failure: no re-run", async () => { + const { decision, calls, summary } = await runMain(fixture(MIXED)); + assert.equal(decision.rerun, false); + assert.equal(decision.jobs.length, 8); + assert.deepEqual(decision.jobs.filter((job) => !job.lost).map((job) => job.name), ["ci / General tests (workspaces-a (1/2))"]); + assert.equal(decision.jobs.find((job) => job.name === "ci / Verify Paperclip Runner (vitest package)").lost, true); + assert.equal(posted(calls).length, 0); + assert.match(decision.reason, /1 of 8 failed jobs did not lose their runner/); + assert.match(summary, /\*\*No automatic re-run\*\*/); +}); + +test("real test failures: no re-run", async () => { + const { decision, calls } = await runMain(fixture(REAL)); + assert.equal(decision.rerun, false); + assert.deepEqual(decision.jobs.map((job) => [job.name, job.lost]), [["ci / General tests (server (4/12))", false]]); + assert.equal(posted(calls).length, 0); +}); + +test("only the verify and e2e aggregates failed: no re-run", async () => { + const data = fixture(ALL_LOST); + data.jobs = data.jobs.map((job) => job.name.startsWith("ci / General tests") ? { ...job, conclusion: "success" } : job); + const { decision, calls } = await runMain(data); + assert.equal(decision.rerun, false); + assert.match(decision.reason, /no failed jobs other than the verify\/e2e aggregates/); + assert.equal(calls.some((call) => call.path.includes("/check-runs/")), false); + assert.equal(posted(calls).length, 0); +}); + +test("attempt 2 or later is never re-run automatically", async () => { + // The event was for attempt 1, but someone re-ran the run before this job started. + const { decision, calls } = await runMain(fixture(ALL_LOST), { mutateRun: (run) => ({ ...run, run_attempt: 2 }) }); + assert.equal(decision.rerun, false); + assert.match(decision.reason, /attempt 2/); + assert.deepEqual(calls.map((call) => call.path), [`/repos/paperclipai/paperclip/actions/runs/${ALL_LOST}`]); +}); + +test("a failed routing gate is left for a human re-run", async () => { + const data = fixture(ALL_LOST); + const gate = data.jobs.find((job) => job.name === "ci / gate / Select trusted runner"); + gate.conclusion = "failure"; + data.annotations[gate.id] = [{ annotation_level: "failure", message: "The self-hosted runner lost communication with the server." }]; + const { decision, calls } = await runMain(data); + assert.equal(decision.rerun, false); + assert.match(decision.jobs.find((job) => job.id === gate.id).evidence, /routing gate/); + assert.equal(posted(calls).length, 0); +}); + +test("runs that are no longer the PR's latest CI are not re-run", async () => { + const data = fixture(ALL_LOST); + const moved = await decide(fakeGithub(data, { + pulls: [{ state: "open", base: { repo: { id: 1170821064 } }, head: { sha: "0".repeat(40), repo: { id: 1170821064 } } }], + }).client, data.run); + assert.equal(moved.rerun, false); + assert.match(moved.reason, /no open pull request/); + + const merged = await decide(fakeGithub(data, { + pulls: [{ state: "closed", base: { repo: { id: 1170821064 } }, head: { sha: data.run.head_sha, repo: { id: 1170821064 } } }], + }).client, data.run); + assert.equal(merged.rerun, false); + + // A later full-ci label run on the same head shares the PR concurrency group; + // re-running the older run would cancel it. + const newer = await decide(fakeGithub(data, { + prRuns: [{ id: data.run.id + 1, conclusion: null }, { id: data.run.id, conclusion: "failure" }], + }).client, data.run); + assert.equal(newer.rerun, false); + assert.match(newer.reason, /newer PR run/); + + // A later label event that did not request CI skips its only job; it is not CI. + const skipped = await decide(fakeGithub(data, { + prRuns: [{ id: data.run.id + 1, conclusion: "skipped" }, { id: data.run.id, conclusion: "failure" }], + }).client, data.run); + assert.equal(skipped.rerun, true); +}); + +test("ineligible runs are rejected before any job is read", async () => { + const data = fixture(ALL_LOST); + for (const [change, reason] of [ + [{ event: "push" }, /event is push/], + [{ path: ".github/workflows/other.yml" }, /workflow is/], + [{ conclusion: "success" }, /completed\/success/], + [{ repository: { id: 1, full_name: "someone/paperclip" } }, /canonical repository/], + ]) { + const github = fakeGithub(data); + const decision = await decide(github.client, { ...data.run, ...change }); + assert.equal(decision.rerun, false); + assert.match(decision.reason, reason); + assert.equal(github.calls.length, 0); + } +}); + +test("job listing follows Link pagination across pages", async () => { + const data = fixture(MIXED); + const github = fakeGithub(data, { jobsPageSize: 20 }); + const decision = await decide(github.client, data.run); + const pages = github.calls.filter((call) => call.path.endsWith("/attempts/1/jobs")); + assert.deepEqual(pages.map((call) => new URLSearchParams(call.query).get("page")), [null, "2", "3"]); + // Failed jobs on pages 2 and 3 are all classified. + assert.equal(decision.jobs.length, 8); + assert.equal(decision.rerun, false); +}); + +test("an incomplete job listing fails instead of deciding on partial data", async () => { + const data = fixture(ALL_LOST); + data.total_count += 1; + const github = fakeGithub(data); + await assert.rejects(decide(github.client, data.run), /Incomplete listing/); + assert.equal(posted(github.calls).length, 0); +}); + +test("the client refuses to follow pagination to another host", async () => { + const client = createGithubClient({ + token: "test-token", + fetcher: async () => json([], { link: '; rel="next"' }), + }); + await assert.rejects(client.paginate("/repos/paperclipai/paperclip/commits/x/pulls"), /Refusing to call https:\/\/example.com/); +}); + +test("classification is conservative about cancelled jobs", async () => { + const cancelled = [{ annotation_level: "failure", message: "The operation was canceled." }]; + const noSignal = await classifyJob({ id: 1 }, { annotations: cancelled, readLog: async () => "##[error]The operation was canceled.\n" }); + assert.equal(noSignal.lost, false); + // A job timeout also cancels the step, but adds its own failure annotation. + const timedOut = await classifyJob({ id: 1 }, { + annotations: [{ annotation_level: "failure", message: "The job has exceeded the maximum execution time of 30m0s" }, ...cancelled], + readLog: async () => { throw new Error("log must not be read"); }, + }); + assert.equal(timedOut.lost, false); + // Notices and warnings are not failure evidence. + const warning = await classifyJob({ id: 1 }, { + annotations: [{ annotation_level: "warning", message: "The self-hosted runner lost communication with the server." }], + readLog: async () => "", + }); + assert.equal(warning.lost, false); + // Test output that merely prints the phrase is not a runner error line. + assert.equal(logShowsRunnerLoss("2026-11-06T00:00:00Z expected 'received a shutdown signal'\n"), false); + assert.equal(logShowsRunnerLoss(fixture(MIXED).logs["128078674151"]), true); +}); + +test("a real failure before the runner was lost is not counted as runner loss", async () => { + const lostMessage = "The self-hosted runner lost communication with the server. Verify the machine is running."; + const noLog = async () => { throw new Error("log must not be read"); }; + // A test fails, then the runner is lost during an always() upload step. + const testThenLost = await classifyJob({ id: 1 }, { + annotations: [ + { annotation_level: "failure", message: "Error: Test timed out in 15000ms." }, + { annotation_level: "failure", message: "Process completed with exit code 1." }, + { annotation_level: "failure", message: lostMessage }, + ], + readLog: noLog, + }); + assert.equal(testThenLost.lost, false); + assert.match(testThenLost.evidence, /Test timed out/); + // The order of the annotations does not matter. + const lostThenExit = await classifyJob({ id: 1 }, { + annotations: [ + { annotation_level: "failure", message: lostMessage }, + { annotation_level: "failure", message: "Process completed with exit code 1." }, + ], + readLog: noLog, + }); + assert.equal(lostThenExit.lost, false); + // Runner loss with a cancellation only is still runner loss. + const lostAndCancelled = await classifyJob({ id: 1 }, { + annotations: [ + { annotation_level: "failure", message: lostMessage }, + { annotation_level: "failure", message: "The operation was canceled." }, + ], + readLog: noLog, + }); + assert.equal(lostAndCancelled.lost, true); +}); + +test("summary cells cannot break the table", () => { + const summary = renderSummary({ + runId: 1, attempt: 1, rerun: false, reason: "test", + jobs: [{ name: "ci / a|b", lost: false, evidence: "line one\nline | two" }], + }); + assert.match(summary, /\| ci \/ a\\\|b \| no \| line one line \\\| two \|/); +}); + +test("workflow acts only on failed first attempts of the canonical PR workflow", () => { + const condition = workflow.match(/^ {4}if: >-\n((?: {6}.+\n)+)/m)?.[1].replace(/\s+/g, " ").trim(); + assert.equal(condition, [ + "github.repository == 'paperclipai/paperclip' &&", + "github.repository_id == '1170821064' &&", + "github.event.workflow_run.event == 'pull_request' &&", + "github.event.workflow_run.path == '.github/workflows/pr.yml' &&", + "github.event.workflow_run.conclusion == 'failure' &&", + "github.event.workflow_run.run_attempt == 1", + ].join(" ")); + assert.match(workflow, /^on:\n {2}workflow_run:\n {4}workflows: \[PR\]\n {4}types: \[completed\]$/m); + assert.match(workflow, /^ {2}group: ci-runner-loss-rerun-\$\{\{ github\.event\.workflow_run\.id \}\}$/m); + const permissions = workflow.match(/^permissions:\n((?: {2}.+\n)+)/m)[1] + .split("\n").filter((line) => /^ {2}[a-z-]+:/.test(line)).map((line) => line.trim()); + assert.deepEqual(permissions, ["actions: write", "checks: read", "contents: read", "pull-requests: read"]); +}); + +test("workflow runs only trusted default-branch code", () => { + assert.match(workflow, /ref: \$\{\{ github\.sha \}\}\n {10}persist-credentials: false\n {10}sparse-checkout: \.github\/scripts\n/); + assert.doesNotMatch(workflow, /head_sha|head_branch|download-artifact|secrets\.|pull_request_target/); + assert.equal([...workflow.matchAll(/uses: /g)].length, 1); + assert.match(workflow, /runs-on: ubuntu-latest/); +}); diff --git a/.github/workflows/ci-runner-loss-rerun.yml b/.github/workflows/ci-runner-loss-rerun.yml new file mode 100644 index 00000000000..bc718fdb95b --- /dev/null +++ b/.github/workflows/ci-runner-loss-rerun.yml @@ -0,0 +1,52 @@ +name: CI runner-loss rerun + +# Self-hosted AWS runners are sometimes lost mid-job. When every failed job of +# a first PR CI attempt lost its runner, re-run the failed jobs once. This is +# what a maintainer's "Re-run failed jobs" click does; github-actions[bot] +# becomes attempt 2's triggering actor. See "Trusted PR Workflow" in +# doc/DEVELOPING.md. +on: + workflow_run: + workflows: [PR] + types: [completed] + +permissions: + # rerun-failed-jobs, and reading jobs and job logs. + actions: write + # Check-run annotations carry the runner-loss message. + checks: read + contents: read + # Confirms the run still belongs to an open PR's current head. + pull-requests: read + +concurrency: + group: ci-runner-loss-rerun-${{ github.event.workflow_run.id }} + cancel-in-progress: false + +jobs: + rerun: + # Attempt 1 only: this allows one automatic re-run and cannot loop. + if: >- + github.repository == 'paperclipai/paperclip' && + github.repository_id == '1170821064' && + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.path == '.github/workflows/pr.yml' && + github.event.workflow_run.conclusion == 'failure' && + github.event.workflow_run.run_attempt == 1 + # GitHub-hosted on purpose: this job must not depend on the fleet it repairs. + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + # workflow_run is privileged. Never check out its head SHA or run code + # from downloaded artifacts. This checkout is the trusted default branch. + - name: Checkout trusted re-run script + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ github.sha }} + persist-credentials: false + sparse-checkout: .github/scripts + + - name: Re-run failed jobs if every failure was runner loss + env: + GITHUB_TOKEN: ${{ github.token }} + run: node .github/scripts/runner-loss-rerun.mjs diff --git a/doc/DEVELOPING.md b/doc/DEVELOPING.md index 62107e72ab4..9e268299baa 100644 --- a/doc/DEVELOPING.md +++ b/doc/DEVELOPING.md @@ -186,6 +186,19 @@ Authorized test jobs and the final `verify` and `e2e` aggregates use the selecte AWS fleet. A stale admission roster can allocate only the short metadata gate; the fresh CODEOWNERS check still denies PR execution for a removed owner. +AWS runners are sometimes lost mid-job. `ci-runner-loss-rerun.yml` re-runs the +failed jobs of a PR's first CI attempt once when every failed job lost its +runner. A lost runner is recognized by the check-run annotation "lost +communication with the server" or "received a shutdown signal". When the only +annotation is "The operation was canceled.", the job log is checked for the +same messages. The `verify` and `e2e` aggregates are not counted. Any other +failure, a failed routing gate, or a PR whose head has moved prevents the +automatic re-run. The workflow job summary lists each failed job and its +evidence. Like a maintainer's "Re-run failed jobs", the re-run reuses the +gate's successful outputs, including its AWS admission. Attempt 2's +triggering actor is `github-actions[bot]`, so `profile-ci` does not export +that attempt. Later attempts are never re-run automatically. + The routing workflow also selects the CI scope. Middle PRs in a stack and PRs whose diff changes only release notes (`releases/v*.md` or `releases/beta/v*.md`) skip the build, test, and e2e lanes. The `policy` job